summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authornagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-07-12 23:08:32 +0000
committernagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-07-12 23:08:32 +0000
commited6ce8b43b6f25df1d4809ac799de4dd1c85c1f3 (patch)
tree09bc05d679d0f224a29fee44d10beea321bdc0b5 /ext
parente13fb8029b87943ab8af2211226b7c9347d3976d (diff)
* ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries.
* ext/tk/*: Support new features of Tcl/Tk8.6b1 and minor bug fixes. ( [KNOWN BUG] Ruby/Tk on Ruby 1.9 will not work on Cygwin. ) * ext/tk/*: Unify sources between Ruby 1.8 & 1.9. Improve default_widget_set handling. * ext/tk/*: Multi-TkInterpreter (multi-tk.rb) works on Ruby 1.8 & 1.9. ( [KNOWN BUG] On Ruby 1.8, join to a long term Thread on Tk callbacks may freeze. On Ruby 1.9, cannot create a second master interpreter (creating slaves are OK); supported master interpreter is the default master interpreter only. ) * ext/tk/lib/tkextlib/*: Update supported versions of Tk extensions. Tcllib 1.8/Tklib 0.4.1 ==> Tcllib 1.11.1/Tklib 0.5 BWidgets 1.7 ==> BWidgets 1.8 TkTable 2.9 ==> TkTable 2.10 TkTreeCtrl 2005-12-02 ==> TkTreeCtrl 2.2.9 Tile 0.8.0/8.5.1 ==> Tile 0.8.3/8.6b1 IncrTcl 2005-02-14 ==> IncrTcl 2008-12-15 TclX 2005-02-07 ==> TclX 2008-12-15 Trofs 0.4.3 ==> Trofs 0.4.4 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24063 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/tk/ChangeLog.tkextlib14
-rw-r--r--ext/tk/MANUAL_tcltklib.eng8
-rw-r--r--ext/tk/MANUAL_tcltklib.eucj9
-rw-r--r--ext/tk/README.ActiveTcl13
-rw-r--r--ext/tk/README.tcltklib43
-rw-r--r--ext/tk/config_list.in35
-rw-r--r--ext/tk/extconf.rb1087
-rw-r--r--ext/tk/lib/multi-tk.rb343
-rw-r--r--ext/tk/lib/remote-tk.rb18
-rw-r--r--ext/tk/lib/tk.rb255
-rw-r--r--ext/tk/lib/tk/autoload.rb398
-rw-r--r--ext/tk/lib/tk/bindtag.rb2
-rw-r--r--ext/tk/lib/tk/busy.rb118
-rw-r--r--ext/tk/lib/tk/button.rb5
-rw-r--r--ext/tk/lib/tk/canvas.rb31
-rw-r--r--ext/tk/lib/tk/canvastag.rb29
-rw-r--r--ext/tk/lib/tk/checkbutton.rb8
-rw-r--r--ext/tk/lib/tk/composite.rb42
-rw-r--r--ext/tk/lib/tk/entry.rb5
-rw-r--r--ext/tk/lib/tk/event.rb22
-rw-r--r--ext/tk/lib/tk/font.rb15
-rw-r--r--ext/tk/lib/tk/fontchooser.rb166
-rw-r--r--ext/tk/lib/tk/frame.rb5
-rw-r--r--ext/tk/lib/tk/image.rb2
-rw-r--r--ext/tk/lib/tk/itemconfig.rb7
-rw-r--r--ext/tk/lib/tk/label.rb5
-rw-r--r--ext/tk/lib/tk/labelframe.rb6
-rw-r--r--ext/tk/lib/tk/listbox.rb6
-rw-r--r--ext/tk/lib/tk/macpkg.rb4
-rw-r--r--ext/tk/lib/tk/menu.rb59
-rw-r--r--ext/tk/lib/tk/menubar.rb24
-rw-r--r--ext/tk/lib/tk/menuspec.rb207
-rw-r--r--ext/tk/lib/tk/message.rb6
-rw-r--r--ext/tk/lib/tk/msgcat.rb2
-rw-r--r--ext/tk/lib/tk/namespace.rb2
-rw-r--r--ext/tk/lib/tk/optiondb.rb2
-rw-r--r--ext/tk/lib/tk/panedwindow.rb8
-rw-r--r--ext/tk/lib/tk/radiobutton.rb8
-rw-r--r--ext/tk/lib/tk/root.rb2
-rw-r--r--ext/tk/lib/tk/scale.rb5
-rw-r--r--ext/tk/lib/tk/scrollbar.rb14
-rw-r--r--ext/tk/lib/tk/spinbox.rb33
-rw-r--r--ext/tk/lib/tk/text.rb16
-rw-r--r--ext/tk/lib/tk/textmark.rb2
-rw-r--r--ext/tk/lib/tk/texttag.rb5
-rw-r--r--ext/tk/lib/tk/timer.rb4
-rw-r--r--ext/tk/lib/tk/toplevel.rb6
-rw-r--r--ext/tk/lib/tk/ttk_selector.rb34
-rw-r--r--ext/tk/lib/tk/variable.rb10
-rw-r--r--ext/tk/lib/tk/virtevent.rb2
-rw-r--r--ext/tk/lib/tk/winpkg.rb7
-rw-r--r--ext/tk/lib/tkextlib/SUPPORT_STATUS24
-rw-r--r--ext/tk/lib/tkextlib/blt.rb2
-rw-r--r--ext/tk/lib/tkextlib/blt/barchart.rb4
-rw-r--r--ext/tk/lib/tkextlib/blt/bitmap.rb2
-rw-r--r--ext/tk/lib/tkextlib/blt/busy.rb1
-rw-r--r--ext/tk/lib/tkextlib/blt/component.rb81
-rw-r--r--ext/tk/lib/tkextlib/blt/container.rb2
-rw-r--r--ext/tk/lib/tkextlib/blt/dragdrop.rb3
-rw-r--r--ext/tk/lib/tkextlib/blt/graph.rb4
-rw-r--r--ext/tk/lib/tkextlib/blt/htext.rb3
-rw-r--r--ext/tk/lib/tkextlib/blt/stripchart.rb4
-rw-r--r--ext/tk/lib/tkextlib/blt/table.rb15
-rw-r--r--ext/tk/lib/tkextlib/blt/tabnotebook.rb2
-rw-r--r--ext/tk/lib/tkextlib/blt/tabset.rb8
-rw-r--r--ext/tk/lib/tkextlib/blt/ted.rb5
-rw-r--r--ext/tk/lib/tkextlib/blt/tile.rb4
-rw-r--r--ext/tk/lib/tkextlib/blt/tree.rb4
-rw-r--r--ext/tk/lib/tkextlib/blt/treeview.rb25
-rw-r--r--ext/tk/lib/tkextlib/blt/unix_dnd.rb8
-rw-r--r--ext/tk/lib/tkextlib/blt/watch.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/arrowbutton.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/button.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/buttonbox.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/combobox.rb13
-rw-r--r--ext/tk/lib/tkextlib/bwidget/dialog.rb16
-rw-r--r--ext/tk/lib/tkextlib/bwidget/entry.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/label.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/labelentry.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/labelframe.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/listbox.rb7
-rw-r--r--ext/tk/lib/tkextlib/bwidget/mainframe.rb6
-rw-r--r--ext/tk/lib/tkextlib/bwidget/messagedlg.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/notebook.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/pagesmanager.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/panedwindow.rb7
-rw-r--r--ext/tk/lib/tkextlib/bwidget/panelframe.rb14
-rw-r--r--ext/tk/lib/tkextlib/bwidget/passwddlg.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/progressbar.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/progressdlg.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/scrollableframe.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/scrolledwindow.rb12
-rw-r--r--ext/tk/lib/tkextlib/bwidget/scrollview.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/selectcolor.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/selectfont.rb7
-rw-r--r--ext/tk/lib/tkextlib/bwidget/separator.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/spinbox.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/statusbar.rb18
-rw-r--r--ext/tk/lib/tkextlib/bwidget/titleframe.rb2
-rw-r--r--ext/tk/lib/tkextlib/bwidget/tree.rb55
-rw-r--r--ext/tk/lib/tkextlib/itcl/incr_tcl.rb4
-rw-r--r--ext/tk/lib/tkextlib/itk/incr_tk.rb6
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/buttonbox.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/calendar.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/canvasprintbox.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/canvasprintdialog.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/checkbox.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/combobox.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/dateentry.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/datefield.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/dialog.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/dialogshell.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/disjointlistbox.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/entryfield.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/extbutton.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/extfileselectionbox.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/extfileselectiondialog.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/feedback.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/fileselectionbox.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/fileselectiondialog.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/finddialog.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/hierarchy.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/hyperhelp.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/labeledframe.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/labeledwidget.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/mainwindow.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/menubar.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/messagebox.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/messagedialog.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/notebook.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/optionmenu.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/panedwindow.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/promptdialog.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/pushbutton.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/radiobox.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/scopedobject.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/scrolledframe.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/scrolledhtml.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb6
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/scrolledwidget.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/selectionbox.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/selectiondialog.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/shell.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/spindate.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/spinint.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/spinner.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/spintime.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/tabset.rb5
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/timeentry.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/timefield.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/toolbar.rb2
-rw-r--r--ext/tk/lib/tkextlib/iwidgets/watch.rb2
-rw-r--r--ext/tk/lib/tkextlib/tcllib.rb29
-rw-r--r--ext/tk/lib/tkextlib/tcllib/calendar.rb55
-rw-r--r--ext/tk/lib/tkextlib/tcllib/canvas_sqmap.rb36
-rw-r--r--ext/tk/lib/tkextlib/tcllib/canvas_zoom.rb21
-rw-r--r--ext/tk/lib/tkextlib/tcllib/chatwidget.rb151
-rw-r--r--ext/tk/lib/tkextlib/tcllib/crosshair.rb117
-rw-r--r--ext/tk/lib/tkextlib/tcllib/ctext.rb2
-rw-r--r--ext/tk/lib/tkextlib/tcllib/dateentry.rb62
-rw-r--r--ext/tk/lib/tkextlib/tcllib/diagrams.rb224
-rw-r--r--ext/tk/lib/tkextlib/tcllib/getstring.rb2
-rw-r--r--ext/tk/lib/tkextlib/tcllib/ico.rb32
-rw-r--r--ext/tk/lib/tkextlib/tcllib/ip_entry.rb11
-rw-r--r--ext/tk/lib/tkextlib/tcllib/khim.rb68
-rw-r--r--ext/tk/lib/tkextlib/tcllib/menuentry.rb47
-rw-r--r--ext/tk/lib/tkextlib/tcllib/ntext.rb146
-rw-r--r--ext/tk/lib/tkextlib/tcllib/panelframe.rb8
-rw-r--r--ext/tk/lib/tkextlib/tcllib/plotchart.rb616
-rw-r--r--ext/tk/lib/tkextlib/tcllib/scrolledwindow.rb57
-rw-r--r--ext/tk/lib/tkextlib/tcllib/statusbar.rb79
-rw-r--r--ext/tk/lib/tkextlib/tcllib/swaplist.rb2
-rw-r--r--ext/tk/lib/tkextlib/tcllib/tablelist.rb7
-rw-r--r--ext/tk/lib/tkextlib/tcllib/tablelist_core.rb308
-rw-r--r--ext/tk/lib/tkextlib/tcllib/tablelist_tile.rb20
-rw-r--r--ext/tk/lib/tkextlib/tcllib/toolbar.rb175
-rw-r--r--ext/tk/lib/tkextlib/tcllib/tooltip.rb11
-rw-r--r--ext/tk/lib/tkextlib/tcllib/widget.rb34
-rw-r--r--ext/tk/lib/tkextlib/tile.rb36
-rw-r--r--ext/tk/lib/tkextlib/tile/dialog.rb6
-rw-r--r--ext/tk/lib/tkextlib/tile/sizegrip.rb11
-rw-r--r--ext/tk/lib/tkextlib/tile/style.rb20
-rw-r--r--ext/tk/lib/tkextlib/tile/tbutton.rb9
-rw-r--r--ext/tk/lib/tkextlib/tile/tcheckbutton.rb12
-rw-r--r--ext/tk/lib/tkextlib/tile/tcombobox.rb9
-rw-r--r--ext/tk/lib/tkextlib/tile/tentry.rb9
-rw-r--r--ext/tk/lib/tkextlib/tile/tframe.rb9
-rw-r--r--ext/tk/lib/tkextlib/tile/tlabel.rb9
-rw-r--r--ext/tk/lib/tkextlib/tile/tlabelframe.rb12
-rw-r--r--ext/tk/lib/tkextlib/tile/tmenubutton.rb12
-rw-r--r--ext/tk/lib/tkextlib/tile/tnotebook.rb18
-rw-r--r--ext/tk/lib/tkextlib/tile/tpaned.rb26
-rw-r--r--ext/tk/lib/tkextlib/tile/tprogressbar.rb9
-rw-r--r--ext/tk/lib/tkextlib/tile/tradiobutton.rb12
-rw-r--r--ext/tk/lib/tkextlib/tile/treeview.rb79
-rw-r--r--ext/tk/lib/tkextlib/tile/tscale.rb13
-rw-r--r--ext/tk/lib/tkextlib/tile/tscrollbar.rb21
-rw-r--r--ext/tk/lib/tkextlib/tile/tseparator.rb9
-rw-r--r--ext/tk/lib/tkextlib/tile/tspinbox.rb107
-rw-r--r--ext/tk/lib/tkextlib/tile/tsquare.rb2
-rw-r--r--ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb4
-rw-r--r--ext/tk/lib/tkextlib/tktable/tktable.rb15
-rw-r--r--ext/tk/lib/tkextlib/treectrl/tktreectrl.rb87
-rw-r--r--ext/tk/lib/tkextlib/version.rb2
-rw-r--r--ext/tk/lib/tkextlib/vu/bargraph.rb2
-rw-r--r--ext/tk/lib/tkextlib/vu/dial.rb2
-rw-r--r--ext/tk/lib/tkextlib/vu/pie.rb8
-rw-r--r--ext/tk/old-extconf.rb440
-rw-r--r--ext/tk/sample/demos-en/widget7
-rw-r--r--ext/tk/sample/demos-jp/widget8
-rw-r--r--ext/tk/sample/editable_listbox.rb131
-rw-r--r--ext/tk/sample/menubar3.rb72
-rw-r--r--ext/tk/sample/multi-ip_sample.rb3
-rw-r--r--ext/tk/sample/safe-tk.rb23
-rw-r--r--ext/tk/sample/scrollframe.rb20
-rw-r--r--ext/tk/sample/tkalignbox.rb44
-rw-r--r--ext/tk/sample/tkballoonhelp.rb90
-rw-r--r--ext/tk/sample/tkcombobox.rb121
-rw-r--r--ext/tk/sample/tktextframe.rb251
-rw-r--r--ext/tk/stubs.c33
-rw-r--r--ext/tk/tcltklib.c373
-rw-r--r--ext/tk/tkutil/extconf.rb4
-rw-r--r--ext/tk/tkutil/tkutil.c60
227 files changed, 7234 insertions, 1043 deletions
diff --git a/ext/tk/ChangeLog.tkextlib b/ext/tk/ChangeLog.tkextlib
index fc919a5eb5..4aa9cb61d6 100644
--- a/ext/tk/ChangeLog.tkextlib
+++ b/ext/tk/ChangeLog.tkextlib
@@ -1,3 +1,17 @@
+2009-07-12 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
+
+ * ext/tk/lib/tkextlib/*: update release.
+ Tcllib 1.8/Tklib 0.4.1 ==> Tcllib 1.11.1/Tklib 0.5
+ BWidgets 1.7 ==> BWidgets 1.8
+ TkTable 2.9 ==> TkTable 2.10
+ TkTreeCtrl 2005-12-02 ==> TkTreeCtrl 2.2.9
+ Tile 0.8.0/8.5.1 ==> Tile 0.8.3/8.6b1
+ IncrTcl 2005-02-14 ==> IncrTcl 2008-12-15
+ TclX 2005-02-07 ==> TclX 2008-12-15
+ Trofs 0.4.3 ==> Trofs 0.4.4
+
+--------------< ... some bug fixes ... >------------------
+
Tue Nov 25 03:37:42 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/lib/tkextlib/blt/tabset.rb,
diff --git a/ext/tk/MANUAL_tcltklib.eng b/ext/tk/MANUAL_tcltklib.eng
index 6fa775b7de..c139947da4 100644
--- a/ext/tk/MANUAL_tcltklib.eng
+++ b/ext/tk/MANUAL_tcltklib.eng
@@ -140,8 +140,7 @@ module TclTklib
[module methods]
get_version()
: return an array of major, minor, release-type number,
- : number, release-type name, and patchlevel of current
- : Tcl/Tk library.
+ : and patchlevel of current Tcl/Tk library.
mainloop(check_root = true)
: Starts the eventloop. If 'check_root' is true, this method
@@ -354,6 +353,11 @@ class TclTkIp
: to _eval and regist the command once, after that, the
: command can be called by _invoke.
+ _cancel_eval(str)
+ _cancel_eval_unwind(str)
+ : (Tcl/Tk8.6 or later)
+ : Call Tcl_CancelEval() function, and cancel evaluation.
+
_toUTF8(str, encoding=nil)
_fromUTF8(str, encoding=nil)
: Call the function (which is internal function of Tcl/Tk) to
diff --git a/ext/tk/MANUAL_tcltklib.eucj b/ext/tk/MANUAL_tcltklib.eucj
index 7df42997b4..26b39f7943 100644
--- a/ext/tk/MANUAL_tcltklib.eucj
+++ b/ext/tk/MANUAL_tcltklib.eucj
@@ -235,8 +235,8 @@ require "tcltklib" ¤¹¤ë¤È, °Ê²¼¤Î¥â¥¸¥å¡¼¥ë, ¥¯¥é¥¹¤¬ÍøÍѲÄǽ¤Ç¤¹.
¥â¥¸¥å¡¼¥ë¥á¥½¥Ã¥É
get_version()
- : Tcl/Tk ¤Î major, minor, release-type ÈÖ¹æ, release-type ̾,
- : patchlevel ¤òÇÛÎó¤Ë¤·¤ÆÊÖ¤¹¡¥
+ : Tcl/Tk ¤Î major, minor, release-type ÈÖ¹æ, patchlevel ¤ò
+ : ÇÛÎó¤Ë¤·¤ÆÊÖ¤¹¡¥
mainloop(check_root = true)
: ¥¤¥Ù¥ó¥È¥ë¡¼¥×¤òµ¯Æ°¤¹¤ë¡¥check_root ¤¬ true ¤Ç¤¢¤ì¤Ð¡¤
@@ -464,6 +464,11 @@ require "tcltklib" ¤¹¤ë¤È, °Ê²¼¤Î¥â¥¸¥å¡¼¥ë, ¥¯¥é¥¹¤¬ÍøÍѲÄǽ¤Ç¤¹.
: ¤·¤ÆÅÐÏ¿¤ËÀ®¸ù¤·¤µ¤¨¤¹¤ì¤Ð¡¤°Ê¹ß¤Ï _invoke ¤Ç¤âÍøÍѤÇ
: ¤­¤ë¤è¤¦¤Ë¤Ê¤ë¡¥
+ _cancel_eval(str)
+ _cancel_eval_unwind(str)
+ : (Tcl/Tk8.6 or later)
+ : Tcl_CancelEval() ´Ø¿ô¤ò¸Æ¤Ó½Ð¤·¡¤eval ¤Î¼Â¹Ô¤òÂǤÁÀڤ롥
+
_toUTF8(str, encoding=nil)
_fromUTF8(str, encoding=nil)
: Tcl/Tk ¤¬Æ⢤·¤Æ¤¤¤ë UTF8 ÊÑ´¹½èÍý¤ò¸Æ¤Ó½Ð¤¹¡¥
diff --git a/ext/tk/README.ActiveTcl b/ext/tk/README.ActiveTcl
index 3afb3f4cf6..c0f9ef8fe4 100644
--- a/ext/tk/README.ActiveTcl
+++ b/ext/tk/README.ActiveTcl
@@ -3,9 +3,22 @@ ActiveTcl is ActiveState's quality-assured distribution of Tcl.
# see <http://www.activestate.com/Products/ActiveTcl/>
# <http://www.tcl.tk/>
+First of all, please try to configure without any options.
+"extconf.rb" searches ActiveTcl as default action.
+If you have ActiveTcl and standard (or your own) Tcl/Tk on your
+environment and don't want to use ActiveTcl on your Ruby/Tk, please
+use --without-ActiveTcl option.
+
+When "extconf.rb" fails to find your ActiveTcl libraries, please try
+the followings.
+
If you want to use ActiveTcl binary package as the Tcl/Tk libraries,
please use the following configure options.
+ --with-ActiveTcl=<ActiveTcl_root>
+ ( When without argument; no <ActiveTcl_root>; only '--with-ActiveTcl',
+ it same to '--with-ActiveTcl=/opt/ActiveTcl*/lib' )
+
--with-tcl-dir=<ActiveTcl_root>
--with-tk-dir=<ActiveTcl_root>
diff --git a/ext/tk/README.tcltklib b/ext/tk/README.tcltklib
index 8c6dd5178f..0db2758f26 100644
--- a/ext/tk/README.tcltklib
+++ b/ext/tk/README.tcltklib
@@ -1,18 +1,53 @@
To compile 'tcltklib', you must have Tcl/Tk libraries on your environment.
-Although 'extconf.rb' script searches Tcl/Tk libraries and header files,
+Although 'extconf.rb' script searches Tcl/Tk libraries and header files
+(as default, searches tclConfig.sh/tkConfig.sh and use the defintions on
+those; ActiveTcl has high priority on searching unless --without-ActiveTcl),
sometimes fails to find them. And then, 'tcltklib' cannot be compiled. If
Tcl/Tk libraries or header files are installed but are not found, you can
give the information by arguments of the 'configure' script. Please give
some or all of the following options.
+ --with-tk-old-extconf use old "extconf.rb" (default: false).
+ If current extconf.rb doesn't work properly
+ (or your install process is based on old
+ documant about Ruby/Tk install), please try
+ this option.
+
+ --with-ActiveTcl / --without-ActiveTcl
+ --with-ActiveTcl=<dir> search ActiveTcl libraries (default: true).
+ When true, try to find installed ActiveTcl.
+ When <dir> is given, use it as the ActiveTcl's
+ top directory (use <dir>/lib, and so on).
+ Old "extconf.rb" doesn't support this option.
+
+ --with-tk-shlib-search-path=<paths>
+ teach the paths for loading shared-libraries
+ to linker.
+ <paths> is a path list with the same format
+ as PATH environment variable.
+ This option may be experimental.
+ Old "extconf.rb" doesn't support this option.
+
--with-tcltkversion=<version>
force version of Tcl/Tk libaray
(e.g. libtcl8.4g.so ==> --with-tcltkversion=8.4g)
+ --without-tcl-config / --without-tk-config
+ --with-tclConfig-dir=<dir>
+ --with-tkConfig-dir=<dir> the directory contains 'tclConfig.sh' and
+ 'tkConfig.sh'.
+ Current "extconf.rb" uses the information
+ on tclConfig.sh/tkConfig.rb, if possible.
+ Old "extconf.rb" doesn't support this option.
+
--with-tcllib=<libname> (e.g. libtcl8.4.so ==> --with-tcllib=tcl8.4)
--with-tklib=<libname> (e.g. libtk8.4.so ==> --with-tklib=tk8.4)
--enable-tcltk-stubs (if you force to enable stubs)
+ On old "extconf.rb", default is false.
+ On current "extconf.rb", default is true when
+ tclConfig.sh/tkConfig.sh have TCL_STUB_LIB_SPEC
+ /TK_STUB_LIB_SPEC, else default is false.
--with-tcl-dir=<path>
equal to "--with-tcl-include=<path>/include --with-tcl-lib=<path>/lib"
@@ -36,6 +71,12 @@ some or all of the following options.
When this option is given, it is assumed that
--enable-tcltk-framework option is given also.
+ --with-tcl-framework-dir=<dir>
+ Tcl framework directory (e.g. "/Library/Frameworks/Tcl.framework")
+
+ --with-tk-framework-dir=<dir>
+ Tk framework directory (e.g. "/Library/Frameworks/Tk.framework")
+
--with-tcl-framework-header=<dir>
Tcl framework headers directory
(e.g. "/Library/Frameworks/Tcl.framework/Headers")
diff --git a/ext/tk/config_list.in b/ext/tk/config_list.in
new file mode 100644
index 0000000000..ba0a963bb0
--- /dev/null
+++ b/ext/tk/config_list.in
@@ -0,0 +1,35 @@
+##############################################
+# configure options for Ruby/Tk
+# release date: 2009-07-12
+##############################################
+with tk-old-extconf
+with ActiveTcl
+with tk-shlib-search-path
+with tcltkversion
+with tcl-config
+with tk-config
+with tclConfig-dir
+with tkConfig-dir
+with tcllib
+with tklib
+enable tcltk-stubs
+with tcl-dir
+with tk-dir
+with tcl-include
+with tcl-lib
+with tcl-lib
+with tk-lib
+enable mac-tcltk-framework
+enable tcltk-framework
+with tcltk-framework
+with tcl-framework-dir
+with tk-framework-dir
+with tcl-framework-header
+with tk-framework-header
+with X11
+with X11-dir
+with X11-include
+with X11-lib
+enable pthread
+enable tcl-thread
+with tclConfig-file
diff --git a/ext/tk/extconf.rb b/ext/tk/extconf.rb
index ebc83a0c0b..7d2853a37b 100644
--- a/ext/tk/extconf.rb
+++ b/ext/tk/extconf.rb
@@ -1,93 +1,126 @@
+##############################################################
# extconf.rb for tcltklib
-
+# release date: 2009-07-12
+##############################################################
require 'mkmf'
-is_win32 = (/mswin|mingw|cygwin|bccwin/ =~ RUBY_PLATFORM)
-#is_macosx = (/darwin/ =~ RUBY_PLATFORM)
+TkLib_Config = {}
+TkLib_Config['search_versions'] =
+ %w[8.9 8.8 8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2]
-have_func("ruby_native_thread_p", "ruby.h")
-have_func("rb_errinfo", "ruby.h")
-have_func("rb_safe_level", "ruby.h")
-have_struct_member("struct RArray", "ptr", "ruby.h")
-have_struct_member("struct RArray", "len", "ruby.h")
-def find_framework(tcl_hdr, tk_hdr)
- if framework_dir = with_config("tcltk-framework")
- paths = [framework_dir]
- else
- unless tcl_hdr || tk_hdr ||
- enable_config("tcltk-framework", false) ||
- enable_config("mac-tcltk-framework", false)
- return false
- end
- paths = ["/Library/Frameworks", "/System/Library/Frameworks"]
- end
-
- checking_for('Tcl/Tk Framework') {
- paths.find{|dir|
- dir.strip!
- dir.chomp!('/')
- (tcl_hdr || FileTest.directory?(dir + "/Tcl.framework/") ) &&
- (tk_hdr || FileTest.directory?(dir + "/Tk.framework/") )
- }
- }
+##############################################################
+# use old extconf.rb ?
+##############################################################
+if with_config('tk-old-extconf')
+ require File.join(File.dirname(__FILE__), 'old-extconf.rb')
+ exit
end
-tcl_framework_header = with_config("tcl-framework-header")
-tk_framework_header = with_config("tk-framework-header")
-tcltk_framework = find_framework(tcl_framework_header, tk_framework_header)
-
-unless is_win32
- have_library("nsl", "t_open")
- have_library("socket", "socket")
- have_library("dl", "dlopen")
- have_library("m", "log")
+##############################################################
+# check configs
+##############################################################
+$cleanfiles << 'config_list'
+config_list_file = File.join(File.dirname(__FILE__),'config_list')
+config_list_file_source = config_list_file + '.in'
+if !File.exist?(config_list_file) ||
+ File.ctime(config_list_file_source) > File.ctime(config_list_file)
+ old_config_list_file = config_list_file_source
+else
+ old_config_list_file = config_list_file
end
-tk_idir, tk_ldir = dir_config("tk")
-tcl_idir, tcl_ldir = dir_config("tcl")
-x11_idir, x11_ldir = dir_config("X11")
+current_configs = {'with'=>{}, 'enable'=>{}}
-tk_ldir2 = with_config("tk-lib")
-tcl_ldir2 = with_config("tcl-lib")
-x11_ldir2 = with_config("X11-lib")
+# setup keys by config_list.in
+IO.foreach(config_list_file_source){|line|
+ line.chomp!
+ line.lstrip!
+ next if line.empty? || line =~ /^\#/ #
+ mode, key, value = line.split(/\s+/, 3)
+ value ||= ""
+ current_configs[mode][key] = value rescue nil
+}
-tk_ldir_list = [tk_ldir2, tk_ldir]
-tcl_ldir_list = [tcl_ldir2, tcl_ldir]
+# define current value of keys
+IO.foreach(old_config_list_file){|line|
+ line.chomp!
+ line.lstrip!
+ next if line.empty? || line =~ /^\#/ #
+ mode, key, value = line.split(/\s+/, 3)
+ value ||= ""
+ if current_configs[mode] && current_configs[mode].has_key?(key)
+ current_configs[mode][key] = value
+ end
+}
-tklib = with_config("tklib")
-tcllib = with_config("tcllib")
-stubs = enable_config("tcltk_stubs") || with_config("tcltk_stubs")
+update_flag = false
+current_configs['with'].each_key{|key|
+ if (value = with_config(key).to_s) != current_configs['with'][key]
+ update_flag = true
+ current_configs['with'][key] = value
+ end
+}
+current_configs['enable'].each_key{|key|
+ if (value = enable_config(key).to_s) != current_configs['enable'][key]
+ update_flag = true
+ current_configs['enable'][key] = value
+ end
+}
-tcltk_version = with_config("tcltkversion")
+# update current_configs
+if update_flag || !File.exist?(config_list_file)
+ open(config_list_file, 'w'){|fobj|
+ fobj.print("# values of current configure options (generated by extconf.rb)\n");
+ ['with', 'enable'].each{|mode|
+ current_configs[mode].each_key{|key|
+ fobj.print("#{mode} #{key} #{current_configs[mode][key]}\n")
+ }
+ }
+ }
+end
-use_X = with_config("X11", (! is_win32))
+if update_flag
+ puts "Configure options for Ruby/Tk may be updated."
+ puts "So, delete files which depend on old configs."
+ File.delete(*(Dir.glob(File.join(File.dirname(__FILE__),
+ "*.#{CONFIG['DLEXT']}"))))
+ File.delete(*(Dir.glob(File.join(File.dirname(__FILE__), "*.#{$OBJEXT}"))))
+ File.delete(File.join(File.dirname(__FILE__), 'Makefile')) rescue nil
-def parse_tclConfig(file)
- # check tclConfig.sh/tkConfig.sh
- tbl = {}
- IO.foreach(file){|line|
- line.strip!
- next if line !~ /^([^\#=][^=]*)=(['"]|)(.*)\2$/
- key, val = $1, $3
- tbl[key] = val.gsub(/\$\{([^}]+)\}/){|s| tbl[$1]} rescue nil
- }
- tbl
+else
+ makefile = File.join(File.dirname(__FILE__),'Makefile')
+ if File.exist?(makefile) &&
+ File.ctime(config_list_file) > File.ctime(makefile)
+ # no need to update Makefile
+ exit
+ end
+end
+
+##############################################################
+# fuctions
+##############################################################
+def is_win32?
+ /mswin|mingw|cygwin|bccwin/ =~ RUBY_PLATFORM
+end
+
+def is_macosx?
+ /darwin/ =~ RUBY_PLATFORM
end
def check_tcltk_version(version)
- return [nil, nil] unless version
+ return [nil, nil] unless version.kind_of? String
version = version.strip
tclver = version.dup
tkver = version.dup
- major = dot = minor = dot = plvl = ext = nil
+ dot = major = minor_dot = minor = plvl_dot = plvl = ext = nil
if version =~ /^(\d)(\.?)(\d)(\.?)(\d*)(.*)$/
- major = $1; minor_dot = $2; minor = $3; plvl_dot = $4; plvl = $5; ext = $6
+ major = $1; minor_dot = $2; minor = $3; plvl_dot = $4; plvl = $5; ext = $6
dot = ! minor_dot.empty?
if plvl_dot.empty? && ! plvl.empty?
minor << plvl
@@ -111,12 +144,536 @@ def check_tcltk_version(version)
[tclver, tkver]
end
+def get_shlib_versions(major = 8, minor_max = 9, minor_min = 0, ext = "")
+ if tclcfg = TkLib_Config["tclConfig_info"]
+ major = tclcfg['TCL_MAJOR_VERSION'].to_i
+ minor_min = tclcfg['TCL_MINOR_VERSION'].to_i
+
+ elsif TkLib_Config["tcltkversion"]
+ tclver, tkver = TkLib_Config["tcltkversion"]
+ if tclver =~ /8\.?(\d)(.*)/
+ minor_min = $1.to_i
+ ext = $2
+ else
+ # unsupported version
+ return [""]
+ end
+ end
+
+ # if disable-stubs, version is fixed.
+ minor_max = minor_min unless TkLib_Config["tcltk-stubs"]
+
+ vers = []
+ minor_max.downto(minor_min){|minor|
+ vers << "#{major}.#{minor}#{ext}" unless ext.empty?
+ vers << "#{major}.#{minor}"
+ }
+
+ vers << ""
+end
+
+def get_shlib_path_head
+ path_head = []
+ path_dirs = []
+
+ if TkLib_Config["ActiveTcl"].kind_of?(String) # glob path
+ path_dirs.concat Dir.glob(TkLib_Config["ActiveTcl"]).sort.reverse
+ end
+
+ if is_win32?
+ if TkLib_Config["ActiveTcl"]
+ path_head.concat ["c:/ActiveTcl", "c:/Program Files/ActiveTcl"]
+ end
+ path_head.concat [
+ "c:/Tcl", "c:/Program Files/Tcl",
+ "/Tcl", "/Program Files/Tcl"
+ ]
+ path_head.each{|dir| path_dirs << "#{dir}"}
+
+ else
+ [
+ '/opt', '/pkg', '/share',
+ '/usr/local/opt', '/usr/local/pkg', '/usr/local/share', '/usr/local',
+ '/usr/opt', '/usr/pkg', '/usr/share', '/usr/contrib', '/usr'
+ ].each{|dir|
+ next unless File.directory?(dir)
+
+ path_dirs << "#{dir}/lib"
+ path_dirs << "#{dir}" unless Dir.glob("#{dir}/lib*.*").empty?
+
+ dirnames = []
+ if TkLib_Config["ActiveTcl"]
+ dirnames.concat ["ActiveTcl","activeTcl","Activetcl","activetcl"]
+ end
+ dirnames.concat ["TclTk","Tcl_Tk","Tcl-Tk","tcltk","tcl_tk","tcl-tk"]
+
+ dirnames.each{|name|
+ path_dirs << "#{dir}/#{name}" if File.directory?("#{dir}/#{name}")
+ path_head << "#{dir}/#{name}" unless Dir.glob("#{dir}/#{name}[-89_]*").empty?
+ }
+ }
+ end
+
+ [path_head, path_dirs]
+end
+
+def find_macosx_framework
+ use_framework = is_macosx? && TkLib_Config["ActiveTcl"]
+
+ use_framework ||= (tcl_hdr = with_config("tcl-framework-header"))
+ use_framework ||= (tk_hdr = with_config("tk-framework-header"))
+ tcl_hdr = nil unless tcl_hdr.kind_of? String
+ tk_hdr = nil unless tk_hdr.kind_of? String
+ TkLib_Config["tcl-framework-header"] = tcl_hdr
+ TkLib_Config["tk-framework-header"] = tk_hdr
+
+ use_framework ||= (tcl_dir = with_config("tcl-framework-dir"))
+ tcl_dir = nil unless tcl_dir.kind_of? String
+ if !tcl_dir && tcl_hdr
+ # e.g. /Library/Frameworks/Tcl.framework/Headers
+ # ==> /Library/Frameworks/Tcl.framework
+ tcl_dir = File.dirname(tcl_hdr.strip.chomp('/'))
+ end
+ TkLib_Config["tcl-framework-dir"] = tcl_dir
+
+ use_framework ||= (tk_dir = with_config("tk-framework-dir"))
+ tk_dir = nil unless tk_dir.kind_of? String
+ if !tk_dir && tk_hdr
+ # e.g. /Library/Frameworks/Tk.framework/Headers
+ # ==> /Library/Frameworks/Tk.framework
+ tk_dir = File.dirname(tk_hdr.strip.chomp('/'))
+ end
+ TkLib_Config["tk-framework-dir"] = tk_dir
+
+ if tcl_dir && !tk_dir
+ tk_dir = File.join(File.dirname(tcl_dir), 'Tk.framework')
+ TkLib_Config["tk-framework-dir"] = tk_dir
+ elsif !tcl_dir && tk_dir
+ tcl_dir = File.join(File.dirname(tk_dir), 'Tcl.framework')
+ TkLib_Config["tcl-framework-dir"] = tcl_dir
+ end
+ if tcl_dir && tk_dir
+ TkLib_Config["tcltk-framework"] = File.dirname(tcl_dir) unless TkLib_Config["tcltk-framework"]
+ return [tcl_dir, tk_dir]
+ end
+
+ # framework is disabled?
+ if with_config("tcltk-framework") == false ||
+ enable_config("tcltk-framework") == false
+ return false
+ end
+
+ use_framework ||= (framework_dir = with_config("tcltk-framework"))
+ if framework_dir.kind_of? String
+ TkLib_Config["tcltk-framework"] = framework_dir.strip.chomp('/')
+ return [File.join(TkLib_Config["tcltk-framework"], 'Tcl.framework'),
+ File.join(TkLib_Config["tcltk-framework"], 'Tk.framework')]
+ end
+
+ unless enable_config("tcltk-framework", use_framework) ||
+ enable_config("mac-tcltk-framework", use_framework)
+ TkLib_Config["tcltk-framework"] = false
+ return false
+ end
+
+ paths = [
+ #"~/Library/Frameworks",
+ "/Library/Frameworks",
+ "/Network/Library/Frameworks", "/System/Library/Frameworks"
+ ]
+
+ paths.map{|dir| dir.strip.chomp('/')}.each{|dir|
+ next unless File.directory?(tcldir = File.join(dir, "Tcl.framework"))
+ next unless File.directory?(tkdir = File.join(dir, "Tk.framework"))
+ TkLib_Config["tcltk-framework"] = dir
+ return [tcldir, tkdir]
+ }
+
+ nil
+end
+
+def collect_tcltk_defs(tcl_defs_str, tk_defs_str)
+ conflicts = [
+ 'PACKAGE_NAME', 'PACKAGE_TARNAME', 'PACKAGE_VERSION',
+ 'PACKAGE_STRING', 'PACKAGE_BUGREPORT'
+ ]
+
+ begin
+ # Ruby 1.9.x or later
+ arch_config_h = RbConfig.expand($arch_hdrdir + "/ruby/config.h")
+ if File.exist?(arch_config_h)
+ keys = []
+ IO.foreach(arch_config_h){|line|
+ if line =~ /^#define +([^ ]+)/
+ keys << $1
+ end
+ }
+ conflicts = keys
+ end
+ rescue
+ # ignore, use default
+ end
+
+ if tcl_defs_str
+ tcl_defs = tcl_defs_str.split(/ ?-D/).map{|s|
+ s =~ /^([^=]+)(.*)$/
+ [$1, $2]
+ }
+ else
+ tcl_defs = []
+ end
+
+ if tk_defs_str
+ tk_defs = tk_defs_str.split(/ ?-D/).map{|s|
+ s =~ /^([^=]+)(.*)$/
+ [$1, $2]
+ }
+ else
+ tk_defs = []
+ end
+
+ defs = tcl_defs | tk_defs
+
+ defs.delete_if{|name,value|
+ conflicts.include?(name) ||
+ ( (vtcl = tcl_defs.assoc(name)) && (vtk = tk_defs.assoc(name)) &&
+ vtcl != vtk )
+ }
+
+ defs.map{|ary| s = ary.join(''); (s.strip.empty?)? "": "-D" << s}.join(' ')
+end
+
+def parse_tclConfig(file)
+ # check tclConfig.sh/tkConfig.sh
+ tbl = Hash.new{|h,k| h[k] = ""}
+ return tbl unless file
+ IO.foreach(file){|line|
+ line.strip!
+ next if line !~ /^([^\#=][^=]*)=(['"]|)(.*)\2$/
+ key, val = $1, $3
+ tbl[key] = val.gsub(/\$\{([^}]+)\}/){|s|
+ subst = $1
+ (tbl[subst])? tbl[subst]: s
+ } rescue nil
+ }
+ tbl
+end
+
+def get_libpath(lib_flag, lib_spec)
+ # get libpath fro {TCL,Tk}_LIB_FLAG and {TCL,Tk}_LIB_SPEC
+ libpath = lib_spec.gsub(/(#{lib_flag}|-L)/, "").strip
+end
+
+def search_tclConfig(*paths) # list of lib-dir or [tcl-libdir, tk-libdir]
+ TkLib_Config["tclConfig_paths"] = []
+ config_dir = []
+
+ paths.compact!
+
+ fixed_tclConfig = ! paths.empty?
+
+ paths.each{|path|
+ if path.kind_of?(Array)
+ config_dir << path
+ else
+ dirs = Dir.glob(path)
+ config_dir.concat(dirs.zip(dirs))
+ end
+ }
+
+ if is_win32?
+ if TkLib_Config["ActiveTcl"]
+ dirs = []
+ if TkLib_Config["ActiveTcl"].kind_of?(String)
+ dirs << TkLib_Config["ActiveTcl"]
+ end
+ dirs.concat [
+ "c:/ActiveTcl*/lib", "c:/Activetcl*/lib",
+ "c:/activeTcl*/lib", "c:/activetcl*/lib",
+ "c:/Tcl*/lib", "c:/tcl*/lib",
+ "c:/Program Files/ActiveTcl*/lib", "c:/Program Files/Activetcl*/lib",
+ "c:/Program Files/activeTcl*/lib", "c:/Program Files/activetcl*/lib",
+ "c:/Program Files/Tcl*/lib", "c:/Program Files/tcl*/lib",
+ "/ActiveTcl*/lib", "/Activetcl*/lib",
+ "/activeTcl*/lib", "/activetcl*/lib",
+ "/Tcl*/lib", "/tcl*/lib",
+ "/Program Files/ActiveTcl*/lib", "/Program Files/Activetcl*/lib",
+ "/Program Files/activeTcl*/lib", "/Program Files/activetcl*/lib",
+ "/Program Files/Tcl*/lib", "/Program Files/tcl*/lib"
+ ]
+ else
+ dirs = [
+ "c:/Tcl*/lib", "c:/tcl*/lib",
+ "c:/Program Files/Tcl*/lib", "c:/Program Files/tcl*/lib",
+ "/Tcl*/lib", "/tcl*/lib",
+ "/Program Files/Tcl*/lib", "/Program Files/tcl*/lib"
+ ]
+ end
+ dirs.collect{|d| Dir.glob(d)}.flatten!
+ dirs |= dirs
+
+ ENV['PATH'].split(';').each{|dir|
+ dirs << File.expand_path(File.join(dir, '..', 'lib'))
+ dirs << dir
+ dirs << File.expand_path(File.join(dir, '..'))
+ }
+
+ config_dir.concat(dirs.zip(dirs))
+
+ elsif framework = find_macosx_framework()
+ config_dir.unshift(framework)
+
+ else
+ if activeTcl = TkLib_Config['ActiveTcl']
+ # check latest version at first
+ config_dir.concat(Dir.glob(activeTcl).sort.reverse)
+ end
+
+ config_dir.concat [
+ RbConfig::CONFIG['libdir'],
+ File.join(RbConfig::CONFIG['exec_prefix'], 'lib'),
+ File.join(RbConfig::CONFIG['prefix'], 'lib'),
+ "/usr/local/opt/lib", "/usr/local/pkg/lib", "/usr/local/share/lib",
+ "/usr/local/lib", "/usr/opt/lib", "/usr/pkg/lib",
+ "/usr/share/lib", "/usr/contrib/lib", "/usr/lib"
+ ]
+
+ config_dir.concat [
+ '/opt', '/pkg', '/share',
+ '/usr/local/opt', '/usr/local/pkg', '/usr/local/share', '/usr/local',
+ '/usr/opt', '/usr/pkg', '/usr/share', '/usr/contrib', '/usr'
+ ].map{|dir|
+ Dir.glob(dir + '/{TclTk,tcltk,Tcl,tcl,Tk,tk}[87]*/lib')
+ Dir.glob(dir + '/{TclTk,tcltk,Tcl,tcl,Tk,tk}[87]*')
+ Dir.glob(dir + '/{TclTk,tcltk,Tcl,tcl,Tk,tk}/lib')
+ Dir.glob(dir + '/{TclTk,tcltk,Tcl,tcl,Tk,tk}')
+ }.flatten!
+
+ ENV['PATH'].split(':').each{|dir|
+ config_dir << File.expand_path(File.join(dir, '..', 'lib'))
+ }
+
+ # for MacOS X
+ #config_dir << "~/Library/Tcl"
+ #config_dir.concat(Dir.glob("~/Library/Tcl/*").sort.reverse)
+ config_dir << "/Library/Tcl"
+ config_dir.concat(Dir.glob("/Library/Tcl/*").sort.reverse)
+ config_dir << "/Network/Library/Tcl"
+ config_dir.concat(Dir.glob("/Network/Library/Tcl/*").sort.reverse)
+ config_dir << "/System/Library/Tcl"
+ config_dir.concat(Dir.glob("/System/Library/Tcl/*").sort.reverse)
+ [
+ #"~/Library/Frameworks",
+ "/Library/Frameworks",
+ "/Network/Library/Frameworks", "/System/Library/Frameworks"
+ ].each{|framework|
+ config_dir << [File.expand_path(File.join(framework, 'Tcl.framework')),
+ File.expand_path(File.join(framework, 'Tk.framework'))]
+ }
+ end
+
+ tclver, tkver = TkLib_Config['tcltkversion']
+ conf = nil
+
+ config_dir.map{|dir|
+ if dir.kind_of? Array
+ [dir[0].strip.chomp('/'), dir[1].strip.chomp('/')]
+ else
+ dir.strip.chomp('/')
+ end
+ }.each{|dir|
+ # print("check #{dir} ==>");
+ if dir.kind_of? Array
+ tcldir, tkdir = dir
+ else
+ tcldir = tkdir = dir
+ end
+
+ ['Config-shared.sh','config-shared.sh','Config.sh','config.sh'].each{|f|
+ tclpath = File.join(tcldir, 'tcl' << f)
+ tkpath = File.join(tkdir, 'tk' << f)
+ next if !File.exist?(tclpath) || !File.exist?(tkpath)
+
+ # parse tclConfig.sh/tkConfig.sh
+ tclconf = parse_tclConfig(tclpath)
+ next if tclver && tclver !~ /^#{tclconf['TCL_MAJOR_VERSION']}(\.?)#{tclconf['TCL_MINOR_VERSION']}/
+ tkconf = parse_tclConfig(tkpath)
+ next if tkver && tkver !~ /^#{tkconf['TK_MAJOR_VERSION']}(\.?)#{tkconf['TK_MINOR_VERSION']}/
+
+ # find tclConfig.sh & tkConfig.sh
+ conf = [tclconf, tkconf] unless conf
+
+ # nativethread check
+ unless TkLib_Config["ruby_with_thread"]
+ tclconf['TCL_THREADS'] == '1'
+ puts "WARNIG: find #{tclpath.inspect}, but it WITH nativethread-support under ruby WITHOUT nativethread-support. So, ignore it."
+ TkLib_Config["tcltk-NG-path"] << File.dirname(tclpath)
+ next
+ end
+
+ #return [tclpath, tkpath]
+ # print(" #{[tclpath, tkpath]}");
+ TkLib_Config["tclConfig_paths"] << [tclpath, tkpath]
+ }
+
+ # print("\n");
+ }
+
+ if TkLib_Config["tclConfig_paths"].empty?
+ [nil, nil]
+ else
+ # find tclConfig.sh and tkConfig.sh
+ TkLib_Config["tclConfig_info"], TkLib_Config["tkConfig_info"] = conf
+ TkLib_Config["tclConfig_paths"][0]
+ end
+end
+
+def get_tclConfig(tclConfig_file, tclConfig_dir, tkConfig_dir)
+ use_tclConfig = (tclConfig_file != false) &&
+ (tclConfig_dir != false) && (tkConfig_dir != false)
+
+ tclConfig_file = nil unless tclConfig_file.kind_of? String
+ tclConfig_dir = nil unless tclConfig_dir.kind_of? String
+ tkConfig_dir = nil unless tkConfig_dir.kind_of? String
+
+ unless tclConfig_dir
+ if tclConfig_file
+ tclConfig_dir = File.dirname(tclConfig_file)
+ elsif tkConfig_dir
+ tclConfig_dir = tkConfig_dir
+ end
+ end
+ tkConfig_dir ||= tclConfig_dir
+
+ TkLib_Config["tclConfig-file"] = tclConfig_file
+ TkLib_Config["tclConfig-dir"] = tclConfig_dir
+ TkLib_Config["tkConfig-dir"] = tkConfig_dir
+
+ unless use_tclConfig
+ puts("Don't use [tclConfig.sh, tkConfig.sh]")
+ else
+ puts("Search tclConfig.sh and tkConfig.sh.")
+ if tclConfig_dir
+ tclConfig, tkConfig = search_tclConfig([tclConfig_dir, tkConfig_dir])
+ else
+ tclConfig, tkConfig = search_tclConfig()
+ end
+ # TclConfig_Info = TkLib_Config["tclConfig_info"]
+ # TkConfig_Info = TkLib_Config["tkConfig_info"]
+
+ if tclConfig && tkConfig
+ puts("Use [tclConfig.sh,tkConfig.sh] == ['#{tclConfig}','#{tkConfig}']")
+ $LIBPATH |= [File.dirname(tclConfig)]
+ $LIBPATH |= [File.dirname(tkConfig)]
+ #TkLib_Config["tclConfig_paths"].each{|tclcfg, tkcfg|
+ # $LIBPATH |= [File.dirname(tclcfg)] | [File.dirname(tkcfg)]
+ #}
+ else
+ puts("Fail to find [tclConfig.sh, tkConfig.sh]")
+ end
+ end
+
+ [tclConfig, tkConfig]
+end
+
+def check_NG_path(path_list)
+ path_list.find_all{|path| not TkLib_Config["tcltk-NG-path"].include?(path) }
+end
+
+def check_shlib_search_path(paths)
+ if !paths || paths.empty?
+ path_list = []
+
+ #if TkLib_Config["ActiveTcl"]
+ # path_list.concat Dir.glob(TkLib_Config["ActiveTcl"]).sort.reverse
+ #end
+ if TkLib_Config["ActiveTcl"].kind_of?(String) # glob path
+ path_list.concat Dir.glob(TkLib_Config["ActiveTcl"]).sort.reverse
+ end
+
+ vers = get_shlib_versions
+ path_head, path_dirs = get_shlib_path_head
+
+ path_list.concat vers.map{|ver|
+ path_head.map{|head|
+ if ver.empty?
+ head + "/lib"
+ else
+ dirs = []
+
+ if !Dir.glob(head + "-*").empty?
+ dirs << head + "-#{ver}/lib" if !Dir.glob(head + "-[89].*").empty?
+ dirs << head + "-#{ver.delete('.')}/lib" if !Dir.glob(head + "-[89][0-9]*").empty?
+ end
+
+ if !Dir.glob(head + "[_-]*").empty?
+ dirs << head + "_#{ver}/lib" if !Dir.glob(head + "_[89].*").empty?
+ dirs << head + "-#{ver}/lib" if !Dir.glob(head + "-[89].*").empty?
+ dirs << head + "_#{ver.delete('.')}/lib" if !Dir.glob(head + "_[89][0-9]*").empty?
+ dirs << head + "-#{ver.delete('.')}/lib" if !Dir.glob(head + "-[89][0-9]*").empty?
+ end
+
+ dirs
+ end
+ }
+ }.flatten!
+
+ path_list.concat path_dirs
+
+ else
+ # paths is a string with PATH environment style
+ path_list = paths.split((is_win32?)? ';': ':')
+ end
+
+ path_list = check_NG_path(path_list)
+
+ path_list.each{|path| $LIBPATH |= [path.strip] }
+end
+
def find_tcl(tcllib, stubs, version, *opt_paths)
- default_paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"]
- default_paths << "/Tcl/lib" # default for ActiveTcl
+ puts "Search Tcl library"
+ default_paths = []
+
+ default_paths.concat [
+ RbConfig::CONFIG['libdir'],
+ File.join(RbConfig::CONFIG['exec_prefix'], 'lib'),
+ File.join(RbConfig::CONFIG['prefix'], 'lib'),
+ "/usr/local/lib", "/usr/pkg/lib", "/usr/contrib/lib", "/usr/lib"
+ ].find_all{|dir| File.directory?(dir)}
+
+ default_paths.concat [
+ "c:/Tcl/lib", "c:/Program Files/Tcl/lib",
+ "/Tcl/lib", "/Program Files/Tcl/lib"
+ ].find_all{|dir| File.directory?(dir)}
if (paths = opt_paths.compact).empty?
- paths = default_paths
+ if TclConfig_Info['config_file_path']
+ # use definisions on tclConfig.sh
+ TclConfig_Info['TCL_LIB_SPEC'].sub(TclConfig_Info['TCL_LIB_FLAG'],"").strip.sub("-L","") =~ /("|'|)([^"']+)\1/
+ $LIBPATH |= [$2] unless $2.empty?
+
+ unless stubs
+ #*** Probably, TCL_LIBS is a subset of TK_LIBS. ***
+ # $LDFLAGS << ' ' << TclConfig_Info['TCL_LIBS']
+ # $DLDFLAGS << ' ' << TclConfig_Info['TCL_LIBS']
+ $LDFLAGS << ' ' << TclConfig_Info['TCL_LIB_SPEC']
+ return true
+ end
+
+ if TclConfig_Info['TCL_SUPPORTS_STUBS'] == '0' ||
+ TclConfig_Info['TCL_STUB_LIB_SPEC'].strip.empty?
+ puts "#{TclConfig_Info['config_file_path']} tells us that your Tcl/Tk library doesn't support stub."
+ return false
+ else
+ #*** Probably, TCL_LIBS is a subset of TK_LIBS. ***
+ # $LDFLAGS << ' ' << TclConfig_Info['TCL_LIBS']
+ # $DLDFLAGS << ' ' << TclConfig_Info['TCL_LIBS']
+ $LDFLAGS << ' ' << TclConfig_Info['TCL_STUB_LIB_SPEC']
+ return true
+ end
+ end
+
+ paths = check_NG_path(default_paths)
end
if stubs
@@ -130,7 +687,7 @@ def find_tcl(tcllib, stubs, version, *opt_paths)
if version && ! version.empty?
versions = [version]
else
- versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6]
+ versions = TkLib_Config['search_versions']
end
if tcllib
@@ -154,12 +711,62 @@ def find_tcl(tcllib, stubs, version, *opt_paths)
st
end
+def parse_TK_LIBS(tklibs)
+ sfx = "lib|shlib|dll|so"
+ re = /(("|')[^"']+\.(#{sfx})\2|[^"' ]+\.(#{sfx})|-l("|')[^"']+\5|-l[^" ]+)/#'
+
+ tklibs.scan(re).map{|lib,|
+ if lib =~ /^("|')([^"]+)\.(#{sfx})\1/
+ "\"-l#{$2}\""
+ elsif lib =~ /([^" ]+)\.(#{sfx})/
+ "-l#{$1}"
+ else
+ lib
+ end
+ }.join(' ')
+end
+
def find_tk(tklib, stubs, version, *opt_paths)
- default_paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"]
- default_paths << "/Tcl/lib" # default for ActiveTcl
+ puts "Search Tk library"
+ default_paths = []
+
+ default_paths.concat [
+ RbConfig::CONFIG['libdir'],
+ File.join(RbConfig::CONFIG['exec_prefix'], 'lib'),
+ File.join(RbConfig::CONFIG['prefix'], 'lib'),
+ "/usr/local/lib", "/usr/pkg/lib", "/usr/contrib/lib", "/usr/lib"
+ ].find_all{|dir| File.directory?(dir)}
+
+ default_paths.concat [
+ "c:/Tcl/lib", "c:/Program Files/Tcl/lib",
+ "/Tcl/lib", "/Program Files/Tcl/lib"
+ ].find_all{|dir| File.directory?(dir)}
if (paths = opt_paths.compact).empty?
- paths = default_paths
+ if TkConfig_Info['config_file_path']
+ # use definisions on tkConfig.sh
+ TkConfig_Info['TK_LIB_SPEC'].sub(TkConfig_Info['TK_LIB_FLAG'],"").strip.sub("-L","") =~ /("|'|)([^"']+)\1/
+ $LIBPATH |= [$2] unless $2.empty?
+
+ unless stubs
+ $LDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS'])
+ # $DLDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS'])
+ $LDFLAGS << ' ' << TkConfig_Info['TK_LIB_SPEC']
+ return true
+ end
+
+ if TkConfig_Info['TK_STUB_LIB_SPEC'].strip.empty?
+ puts "#{TkConfig_Info['config_file_path']} tells us that your Tcl/Tk library doesn't support stub."
+ return false
+ else
+ $LDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS'])
+ # $DLDFLAGS << ' ' << parse_TK_LIBS(TkConfig_Info['TK_LIBS'])
+ $LDFLAGS << ' ' << TkConfig_Info['TK_STUB_LIB_SPEC']
+ return true
+ end
+ end
+
+ paths = check_NG_path(default_paths)
end
if stubs
@@ -173,7 +780,7 @@ def find_tk(tklib, stubs, version, *opt_paths)
if version && ! version.empty?
versions = [version]
else
- versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2]
+ versions = TkLib_Config['search_versions']
end
if tklib
@@ -198,38 +805,93 @@ def find_tk(tklib, stubs, version, *opt_paths)
end
def find_tcltk_header(tclver, tkver)
- base_dir = ['/usr/local/include', '/usr/pkg/include', '/usr/include']
- base_dir << '/Tcl/include' # default for ActiveTcl
+ base_dir = []
+
+ base_dir.concat [
+ File.join(RbConfig::CONFIG['prefix'], 'include'),
+ "/usr/local/include", "/usr/pkg/include", "/usr/contrib/include",
+ "/usr/include"
+ ].find_all{|dir| File.directory?(dir)}
- unless have_tcl_h = have_header('tcl.h')
+ base_dir.concat [
+ "c:/Tcl/include", "c:/Program Files/Tcl/include",
+ "/Tcl/include", "/Program Files/Tcl/include"
+ ].find_all{|dir| File.directory?(dir)}
+
+ if TclConfig_Info['TCL_INCLUDE_SPEC'] &&
+ have_tcl_h = try_cpp('tcl.h', TclConfig_Info['TCL_INCLUDE_SPEC'])
+ $INCFLAGS << " " << TclConfig_Info['TCL_INCLUDE_SPEC']
+ elsif have_tcl_h = have_header('tcl.h')
+ # find
+ else
if tclver && ! tclver.empty?
versions = [tclver]
else
- versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6]
+ versions = TkLib_Config['search_versions']
end
paths = base_dir.dup
- versions.each{|ver| paths.concat(base_dir.map{|dir| dir + '/tcl' + ver})}
+ versions.each{|ver|
+ paths.concat(base_dir.map{|dir|
+ [dir + '/tcl' + ver, dir + '/tcl' + ver.delete('.')]
+ }.flatten)
+ }
have_tcl_h = find_header('tcl.h', *paths)
end
- unless have_tk_h = have_header("tk.h")
+ if TkConfig_Info['TK_INCLUDE_SPEC'] &&
+ have_tk_h = try_cpp('tk.h', TclConfig_Info['TK_INCLUDE_SPEC'])
+ $INCFLAGS << " " << TkConfig_Info['TK_INCLUDE_SPEC']
+ elsif have_tk_h = have_header('tk.h')
+ # find
+ else
if tkver && ! tkver.empty?
versions = [tkver]
else
- versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2]
+ versions = TkLib_Config['search_versions']
end
paths = base_dir.dup
- versions.each{|ver| paths.concat(base_dir.map{|dir| dir + '/tk' + ver})}
+ versions.each{|ver|
+ paths.concat(base_dir.map{|dir|
+ [dir + '/tk' + ver, dir + '/tk' + ver.delete('.')]
+ }.flatten)
+ }
have_tk_h = find_header('tk.h', *paths)
end
have_tcl_h && have_tk_h
end
+def setup_for_macosx_framework
+ # search directory of header files
+ if File.exist?(dir = File.join(TkLib_Config["tcltk-framework"],
+ 'Tcl.framework', 'Headers'))
+ TclConfig_Info['TCL_INCLUDE_SPEC'] = "-I#{dir} "
+ TclConfig_Info['TK_INCLUDE_SPEC'] = "-I#{File.join(TkLib_Config['tcltk-framework'], 'Tk.framework', 'Headers')} "
+ else
+ dir = Dir.glob(File.join(TkLib_Config["tcltk-framework"],
+ 'Tcl.framework', '*', 'Headers'))
+ TclConfig_Info['TCL_INCLUDE_SPEC'] = "-I#{dir[0]} " unless dir.empty?
+ TclConfig_Info['TK_INCLUDE_SPEC'] = "-I#{Dir.glob(File.join(TkLib_Config['tcltk-framework'], 'Tk.framework', '*', 'Headers'))[0]} "
+ end
+
+ $LDFLAGS << ' -framework Tk -framework Tcl'
+
+ if TkLib_Config["tcl-framework-header"]
+ TclConfig_Info['TCL_INCLUDE_SPEC'] =
+ "-I#{TkLib_Config["tcl-framework-header"]} "
+ end
+ if TkLib_Config["tk-framework-header"]
+ TkConfig_Info['TK_INCLUDE_SPEC'] =
+ "-I#{TkLib_Config["tk-framework-header"]} "
+ end
+end
+
def find_X11(*opt_paths)
- default_paths =
- [ "/usr/X11/lib", "/usr/lib/X11", "/usr/X11R6/lib", "/usr/openwin/lib" ]
- paths = opt_paths.compact.concat(default_paths)
+ defaults =
+ [ "/usr/X11*/lib", "/usr/lib/X11*", "/usr/local/X11*", "/usr/openwin/lib" ]
+ paths = []
+ opt_paths.compact.each{|path| paths.concat(Dir.glob(path.strip.chomp('/')))}
+ defaults.compact.each{|path| paths.concat(Dir.glob(path.strip.chomp('/')))}
st = find_library("X11", "XOpenDisplay", *paths)
unless st
puts("Warning:: cannot find X11 library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options. If your Tcl/Tk don't require X11, please try --without-X11.")
@@ -237,6 +899,31 @@ def find_X11(*opt_paths)
st
end
+def search_X_libraries
+ if TkConfig_Info['config_file_path']
+ # use definitions on tkConfig.sh
+ if TkConfig_Info['TK_XINCLUDES'] && TkConfig_Info['TK_XLIBSW'] &&
+ !TkConfig_Info['TK_XINCLUDES'].strip.empty? &&
+ !TkConfig_Info['TK_XLIBSW'].strip.empty?
+ use_X = true && with_config("X11", (! is_win32?))
+ else
+ use_X = false || with_config("X11", false)
+ end
+ else
+ # depend on configure options
+ use_X = with_config("X11", (! is_win32?))
+ end
+
+ if use_X
+ puts("Use X11 libraries.")
+ x11_idir, x11_ldir = dir_config("X11")
+ x11_ldir2 = with_config("X11-lib")
+ exit unless find_X11(x11_ldir2, x11_ldir)
+ end
+
+ use_X
+end
+
def pthread_check()
tcl_major_ver = nil
tcl_minor_ver = nil
@@ -251,42 +938,36 @@ def pthread_check()
tcl_enable_thread = nil
end
- if (tclConfig = with_config("tclConfig-file"))
+ if TclConfig_Info['config_file_path']
if tcl_enable_thread == true
- puts("Warning: --with-tclConfig-file option is ignored, because --enable-tcl-thread option is given.")
+ puts("Warning: definiton of tclConfig.sh is ignored, because --enable-tcl-thread option is given.")
elsif tcl_enable_thread == false
- puts("Warning: --with-tclConfig-file option is ignored, because --disable-tcl-thread option is given.")
+ puts("Warning: definition of tclConfig.sh is ignored, because --disable-tcl-thread option is given.")
else
# tcl-thread is unknown and tclConfig.sh is given
- begin
- tbl = parse_tclConfig(tclConfig)
- if tbl['TCL_THREADS']
- tcl_enable_thread = (tbl['TCL_THREADS'] == "1")
- else
- tcl_major_ver = tbl['TCL_MAJOR_VERSION'].to_i
- tcl_minor_ver = tbl['TCL_MINOR_VERSION'].to_i
- if tcl_major_ver < 8 || (tcl_major_ver == 8 && tcl_minor_ver == 0)
- tcl_enable_thread = false
- end
+ if TclConfig_Info['TCL_THREADS']
+ tcl_enable_thread = (TclConfig_Info['TCL_THREADS'] == "1")
+ else
+ tcl_major_ver = TclConfig_Info['TCL_MAJOR_VERSION'].to_i
+ tcl_minor_ver = TclConfig_Info['TCL_MINOR_VERSION'].to_i
+ if tcl_major_ver < 8 || (tcl_major_ver == 8 && tcl_minor_ver == 0)
+ tcl_enable_thread = false
end
+ end
- if tcl_enable_thread == nil
- # cannot find definition
- if tcl_major_ver
- puts("Warning: '#{tclConfig}' doesn't include TCL_THREADS definition.")
- else
- puts("Warning: '#{tclConfig}' may not be a tclConfig file.")
- end
- tclConfig = false
+ if tcl_enable_thread == nil
+ # cannot find definition
+ if tcl_major_ver
+ puts("Warning: '#{TclConfig_Info['config_file_path']}' doesn't include TCL_THREADS definition.")
+ else
+ puts("Warning: '#{TclConfig_Info['config_file_path']}' may not be a tclConfig file.")
end
- rescue Exception
- puts("Warning: fail to read '#{tclConfig}'!! --> ignore the file")
tclConfig = false
end
end
end
- if tcl_enable_thread == nil && !tclConfig
+ if tcl_enable_thread == nil && !TclConfig_Info['config_file_path']
# tcl-thread is unknown and tclConfig is unavailable
begin
try_run_available = try_run("int main() { exit(0); }")
@@ -295,12 +976,12 @@ def pthread_check()
puts(%Q'\
*****************************************************************************
**
-** PTHREAD SUPPORT CHECK WARNING:
+** NATIVETHREAD SUPPORT CHECK WARNING:
**
-** We cannot check the consistency of pthread support between Ruby
-** and the Tcl/Tk library in your environment (are you perhaps
-** cross-compiling?). If pthread support for these 2 packages is
-** inconsistent you may find you get errors when running Ruby/Tk
+** We cannot check the consistency of nativethread support between
+** Ruby and the Tcl/Tk library in your environment (are you perhaps
+** cross-compiling?). If nativethread support for these 2 packages
+** is inconsistent you may find you get errors when running Ruby/Tk
** (e.g. hangs or segmentation faults). We strongly recommend
** you to check the consistency manually.
**
@@ -333,26 +1014,27 @@ EOF
end
# check pthread mode
- if (macro_defined?('HAVE_NATIVETHREAD', '#include "ruby.h"'))
+ if (TkLib_Config["ruby_with_thread"])
# ruby -> enable
unless tcl_enable_thread
# ruby -> enable && tcl -> disable
puts(%Q'\
*****************************************************************************
**
-** PTHREAD SUPPORT MODE WARNING:
+** NATIVETHREAD SUPPORT MODE WARNING:
**
-** Ruby is compiled with --enable-pthread, but your Tcl/Tk library
-** seems to be compiled without pthread support. Although you can
-** create the tcltklib library, this combination may cause errors
-** (e.g. hangs or segmentation faults). If you have no reason to
-** keep the current pthread support status, we recommend you reconfigure
-** and recompile the libraries so that both or neither support pthreads.
+** Ruby is compiled with --enable-pthread, but your Tcl/Tk library
+** seems to be compiled without nativethread support. Although you can
+** create the tcltklib library, this combination may cause errors (e.g.
+** hangs or segmentation faults). If you have no reason to keep the
+** current nativethread support status, we recommend you reconfigure and
+** recompile the libraries so that both or neither support nativethreads.
**
-** If you want change the status of pthread support, please recompile
-** Ruby without "--enable-pthread" configure option or recompile Tcl/Tk
-** with "--enable-threads" configure option (if your Tcl/Tk is later
-** than or equal to Tcl/Tk 8.1).
+** If you want change the status of nativethread support, please recompile
+** Ruby without "--enable-pthread" configure option (If you use Ruby 1.9.x
+** or later, you cannot remove this option, because it requires native-
+** thread support.) or recompile Tcl/Tk with "--enable-threads" configure
+** option (if your Tcl/Tk is later than or equal to Tcl/Tk 8.1).
**
*****************************************************************************
')
@@ -374,13 +1056,13 @@ EOF
puts(%Q'\
*****************************************************************************
**
-** PTHREAD SUPPORT MODE ERROR:
+** NATIVETHREAD SUPPORT MODE ERROR:
**
** Ruby is not compiled with --enable-pthread, but your Tcl/Tk
-** library seems to be compiled with pthread support. This
+** library seems to be compiled with nativethread support. This
** combination may cause frequent hang or segmentation fault
** errors when Ruby/Tk is working. We recommend that you NEVER
-** create the library with such a combination of pthread support.
+** create the library with such a combination of nativethread support.
**
** Please recompile Ruby with the "--enable-pthread" configure option
** or recompile Tcl/Tk with the "--disable-threads" configure option.
@@ -397,44 +1079,135 @@ EOF
end
end
-tclver, tkver = check_tcltk_version(tcltk_version)
+##############################################################
+# main
+##############################################################
+# check header files
+have_func("ruby_native_thread_p", "ruby.h")
+have_func("rb_errinfo", "ruby.h")
+have_func("rb_safe_level", "ruby.h")
+have_func("rb_hash_lookup", "ruby.h")
+have_func("rb_proc_new", "ruby.h")
+have_func("rb_obj_untrust", "ruby.h")
+have_func("rb_obj_taint", "ruby.h")
+have_func("rb_set_safe_level_force", "ruby.h")
-if ( tcltk_framework ||
- ( find_tcltk_header(tclver, tkver) &&
- ( !use_X || find_X11(x11_ldir2, x11_ldir) ) &&
- find_tcl(tcllib, stubs, tclver, *tcl_ldir_list) &&
- find_tk(tklib, stubs, tkver, *tk_ldir_list) ) )
- $CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs
- $CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM
+have_struct_member("struct RArray", "ptr", "ruby.h")
+have_struct_member("struct RArray", "len", "ruby.h")
- if tcltk_framework
- if tcl_framework_header
- $CPPFLAGS += " -I#{tcl_framework_header}"
- else
- $CPPFLAGS += " -I#{tcltk_framework}/Tcl.framework/Headers"
- end
+# check libraries
+unless is_win32?
+ have_library("nsl", "t_open")
+ have_library("socket", "socket")
+ have_library("dl", "dlopen")
+ have_library("m", "log")
+end
+$CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM
- if tk_framework_header
- $CPPFLAGS += " -I#{tk_framework_header}"
- else
- $CPPFLAGS += " -I#{tcltk_framework}/Tk.framework/Headers"
- end
+# Does ruby have nativethread ?
+TkLib_Config["ruby_with_thread"] =
+ macro_defined?('HAVE_NATIVETHREAD', '#include "ruby.h"')
- $LDFLAGS += ' -framework Tk -framework Tcl'
+#---------------------------------------------------
+# check requirement of Tcl/tk version
+tcltk_version = with_config("tcltkversion")
+tclver, tkver =
+ TkLib_Config["tcltkversion"] = check_tcltk_version(tcltk_version)
+puts("Specified Tcl/Tk version is #{[tclver, tkver]}") if tclver && tkver
+
+# use ActiveTcl ?
+#if activeTcl = with_config("ActiveTcl")
+if activeTcl = with_config("ActiveTcl", true)
+ puts("Use ActiveTcl libraries (if available).")
+ activeTcl = '/opt/ActiveTcl*/lib' unless activeTcl.kind_of? String
+end
+TkLib_Config["ActiveTcl"] = activeTcl
+
+# enable Tcl/Tk stubs?
+=begin
+if TclConfig_Info['TCL_STUB_LIB_SPEC'] && TkConfig_Info['TK_STUB_LIB_SPEC'] &&
+ !TclConfig_Info['TCL_STUB_LIB_SPEC'].strip.empty? &&
+ !TkConfig_Info['TK_STUB_LIB_SPEC'].strip.empty?
+ stubs = true
+ unless (st = enable_config("tcltk-stubs")).nil?
+ stubs &&= st
+ end
+ unless (st = with_config("tcltk-stubs")).nil?
+ stubs &&= st
end
+else
+ stubs = enable_config("tcltk-stubs") || with_config("tcltk-stubs")
+end
+=end
+stubs = enable_config("tcltk-stubs") || with_config("tcltk-stubs")
+if (TkLib_Config["tcltk-stubs"] = stubs)
+ puts("Compile with Tcl/Tk stubs.")
+ $CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS'
+end
- if stubs or pthread_check
- # create Makefile
+# get tclConfig.sh/tkConfig.sh
+TkLib_Config["tcltk-NG-path"] = []
+tclcfg, tkcfg = get_tclConfig(with_config("tclConfig-file", true),
+ with_config("tclConfig-dir", true),
+ with_config("tkConfig-dir", true))
+TclConfig_Info = TkLib_Config["tclConfig_info"] || {}
+TkConfig_Info = TkLib_Config["tkConfig_info"] || {}
+TclConfig_Info['config_file_path'] = tclcfg
+TkConfig_Info['config_file_path'] = tkcfg
- # for SUPPORT_STATUS
- $INSTALLFILES ||= []
- $INSTALLFILES << ["lib/tkextlib/SUPPORT_STATUS", "$(RUBYLIBDIR)", "lib"]
+# check tk_shlib_search_path
+check_shlib_search_path(with_config('tk-shlib-search-path'))
- have_func("rb_hash_lookup", "ruby.h")
+# search X libraries
+use_X = search_X_libraries
- # create
- $defs << %[-DRUBY_VERSION=\\"#{RUBY_VERSION}\\"]
- $defs << %[-DRUBY_RELEASE_DATE=\\"#{RUBY_RELEASE_DATE}\\"]
- create_makefile("tcltklib")
- end
+# set TCL_DEFS and TK_DEFS
+# $CPPFLAGS += " #{TclConfig_Info['TCL_DEFS']}"
+# $CPPFLAGS += " #{TkConfig_Info['TK_DEFS']}"
+$CPPFLAGS += collect_tcltk_defs(TclConfig_Info['TCL_DEFS'], TkConfig_Info['TK_DEFS'])
+
+# MacOS X Frameworks?
+if TkLib_Config["tcltk-framework"]
+ puts("Use MacOS X Frameworks.")
+ setup_for_macosx_framework
+end
+
+# search Tcl/Tk libraries
+tk_idir, tk_ldir = dir_config("tk") if with_config('tk')
+tcl_idir, tcl_ldir = dir_config("tcl") if with_config('tcl')
+
+tk_ldir2 = with_config("tk-lib")
+tcl_ldir2 = with_config("tcl-lib")
+
+tk_ldir_list = [tk_ldir2, tk_ldir]
+tcl_ldir_list = [tcl_ldir2, tcl_ldir]
+
+tklib = with_config("tklib")
+tcllib = with_config("tcllib")
+
+TclConfig_Info['TCL_INCLUDE_SPEC'] = "-I#{tcl_idir.quote}" if tcl_idir
+TkConfig_Info['TK_INCLUDE_SPEC'] = "-I#{tk_idir.quote}" if tk_idir
+
+#---------------------------------------------------
+
+if (TkLib_Config["tcltk-framework"] ||
+ ( find_tcltk_header(tclver, tkver) &&
+ find_tcl(tcllib, stubs, tclver, *tcl_ldir_list) &&
+ find_tk(tklib, stubs, tkver, *tk_ldir_list) ) ) &&
+ (stubs || pthread_check())
+ # create Makefile
+
+ # for SUPPORT_STATUS
+ $INSTALLFILES ||= []
+ $INSTALLFILES << ["lib/tkextlib/SUPPORT_STATUS", "$(RUBYLIBDIR)", "lib"]
+
+ # create
+ $defs << %[-DRUBY_VERSION=\\"#{RUBY_VERSION}\\"]
+ $defs << %[-DRUBY_RELEASE_DATE=\\"#{RUBY_RELEASE_DATE}\\"]
+
+ create_makefile("tcltklib")
+
+ puts "Find Tcl/Tk libraries. Make tcltklib.so which is required by Ruby/Tk."
+else
+ puts "Can't find proper Tcl/Tk libraries. So, can't make tcltklib.so which is required by Ruby/Tk."
end
diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb
index 32aaa2099c..c10c349d05 100644
--- a/ext/tk/lib/multi-tk.rb
+++ b/ext/tk/lib/multi-tk.rb
@@ -30,8 +30,8 @@ class << TclTkIp
end
obj = __new__(*args)
obj.instance_eval{
- @force_default_encoding ||= [false].taint
- @encoding ||= [nil].taint
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
obj
@@ -120,31 +120,31 @@ MultiTkIp_OK.freeze
class MultiTkIp
BASE_DIR = File.dirname(__FILE__)
- WITH_RUBY_VM = Object.const_defined?(:VM) && ::VM.class == Class
+ WITH_RUBY_VM = Object.const_defined?(:RubyVM) && ::RubyVM.class == Class
WITH_ENCODING = defined?(::Encoding.default_external)
#WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class
- (@@SLAVE_IP_ID = ['slave'.freeze, '0'.taint]).instance_eval{
+ (@@SLAVE_IP_ID = ['slave'.freeze, TkUtil.untrust('0')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
- @@IP_TABLE = {}.taint unless defined?(@@IP_TABLE)
+ @@IP_TABLE = TkUtil.untrust({}) unless defined?(@@IP_TABLE)
- @@INIT_IP_ENV = [].taint unless defined?(@@INIT_IP_ENV) # table of Procs
- @@ADD_TK_PROCS = [].taint unless defined?(@@ADD_TK_PROCS) # table of [name, args, body]
+ @@INIT_IP_ENV = TkUtil.untrust([]) unless defined?(@@INIT_IP_ENV) # table of Procs
+ @@ADD_TK_PROCS = TkUtil.untrust([]) unless defined?(@@ADD_TK_PROCS) # table of [name, args, body]
- @@TK_TABLE_LIST = [].taint unless defined?(@@TK_TABLE_LIST)
+ @@TK_TABLE_LIST = TkUtil.untrust([]) unless defined?(@@TK_TABLE_LIST)
unless defined?(@@TK_CMD_TBL)
- @@TK_CMD_TBL = Object.new.taint
+ @@TK_CMD_TBL = TkUtil.untrust(Object.new)
# @@TK_CMD_TBL.instance_variable_set('@tbl', {}.taint)
- @@TK_CMD_TBL.instance_variable_set('@tbl', Hash.new{|hash,key|
- fail IndexError,
- "unknown command ID '#{key}'"
- }.taint)
+ tbl_obj = TkUtil.untrust(Hash.new{|hash,key|
+ fail IndexError, "unknown command ID '#{key}'"
+ })
+ @@TK_CMD_TBL.instance_variable_set('@tbl', tbl_obj)
class << @@TK_CMD_TBL
allow = [
@@ -223,7 +223,10 @@ class MultiTkIp
@@CB_ENTRY_CLASS = Class.new(TkCallbackEntry){
def initialize(ip, cmd)
@ip = ip
- @cmd = cmd
+ @safe = safe = $SAFE
+ # @cmd = cmd
+ cmd = MultiTkIp._proc_on_safelevel(&cmd)
+ @cmd = proc{|*args| cmd.call(safe, *args)}
self.freeze
end
attr_reader :ip, :cmd
@@ -736,15 +739,15 @@ class MultiTkIp
@@DEFAULT_MASTER = self.allocate
@@DEFAULT_MASTER.instance_eval{
- @tk_windows = {}.taint
+ @tk_windows = TkUtil.untrust({})
- @tk_table_list = [].taint
+ @tk_table_list = TkUtil.untrust([])
- @slave_ip_tbl = {}.taint
+ @slave_ip_tbl = TkUtil.untrust({})
- @slave_ip_top = {}.taint
+ @slave_ip_top = TkUtil.untrust({})
- @evloop_thread = [].taint
+ @evloop_thread = TkUtil.untrust([])
unless keys.kind_of? Hash
fail ArgumentError, "expecting a Hash object for the 2nd argument"
@@ -755,7 +758,12 @@ class MultiTkIp
else ### Ruby 1.9 !!!!!!!!!!!
@interp_thread = Thread.new{
current = Thread.current
- current[:interp] = interp = TclTkIp.new(name, _keys2opts(keys))
+ begin
+ current[:interp] = interp = TclTkIp.new(name, _keys2opts(keys))
+ rescue e
+ current[:interp] = e
+ raise e
+ end
#sleep
current[:mutex] = mutex = Mutex.new
current[:root_check] = cond_var = ConditionVariable.new
@@ -770,13 +778,29 @@ class MultiTkIp
current[:status] = status
begin
- current[:status].value = interp.mainloop(true)
- rescue Exception=>e
- current[:status].value = e
+ begin
+ #TclTkLib.mainloop_abort_on_exception = false
+ #Thread.current[:status].value = TclTkLib.mainloop(true)
+ interp.mainloop_abort_on_exception = true
+ current[:status].value = interp.mainloop(true)
+ rescue SystemExit=>e
+ current[:status].value = e
+ rescue Exception=>e
+ current[:status].value = e
+ retry if interp.has_mainwindow?
+ ensure
+ mutex.synchronize{ cond_var.broadcast }
+ end
+
+ #Thread.current[:status].value = TclTkLib.mainloop(false)
+ current[:status].value = interp.mainloop(false)
+
ensure
- mutex.synchronize{ cond_var.broadcast }
+ # interp must be deleted before the thread for interp is dead.
+ # If not, raise Tcl_Panic on Tcl_AsyncDelete because async handler
+ # deleted by the wrong thread.
+ interp.delete
end
- current[:status].value = interp.mainloop(false)
}
until @interp_thread[:interp]
Thread.pass
@@ -795,18 +819,18 @@ class MultiTkIp
end
@interp.instance_eval{
- @force_default_encoding ||= [false].taint
- @encoding ||= [nil].taint
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
@ip_name = nil
- @callback_status = [].taint
+ @callback_status = TkUtil.untrust([])
@system = Object.new
- @wait_on_mainloop = [true, 0].taint
+ @wait_on_mainloop = TkUtil.untrust([true, 0])
@threadgroup = Thread.current.group
@@ -1181,8 +1205,8 @@ class MultiTkIp
ip_name = _create_slave_ip_name
slave_ip = @interp.create_slave(ip_name, true)
slave_ip.instance_eval{
- @force_default_encoding ||= [false].taint
- @encoding ||= [nil].taint
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
@slave_ip_tbl[ip_name] = slave_ip
@@ -1228,8 +1252,8 @@ class MultiTkIp
ip_name = _create_slave_ip_name
slave_ip = @interp.create_slave(ip_name, false)
slave_ip.instance_eval{
- @force_default_encoding ||= [false].taint
- @encoding ||= [nil].taint
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
slave_ip._invoke('set', 'argv0', name) if name.kind_of?(String)
@@ -1282,12 +1306,12 @@ class MultiTkIp
@cb_error_proc = []
@evloop_thread = []
- @tk_windows.taint unless @tk_windows.tainted?
- @tk_table_list.taint unless @tk_table_list.tainted?
- @slave_ip_tbl.taint unless @slave_ip_tbl.tainted?
- @slave_ip_top.taint unless @slave_ip_top.tainted?
- @cb_error_proc.taint unless @cb_error_proc.tainted?
- @evloop_thread.taint unless @evloop_thread.tainted?
+ TkUtil.untrust(@tk_windows) unless @tk_windows.tainted?
+ TkUtil.untrust(@tk_table_list) unless @tk_table_list.tainted?
+ TkUtil.untrust(@slave_ip_tbl) unless @slave_ip_tbl.tainted?
+ TkUtil.untrust(@slave_ip_top) unless @slave_ip_top.tainted?
+ TkUtil.untrust(@cb_error_proc) unless @cb_error_proc.tainted?
+ TkUtil.untrust(@evloop_thread) unless @evloop_thread.tainted?
@callback_status = []
@@ -1302,17 +1326,18 @@ class MultiTkIp
unless WITH_RUBY_VM
@interp = TclTkIp.new(name, _keys2opts(tk_opts))
@interp.instance_eval{
- @force_default_encoding ||= [false].taint
- @encoding ||= [nil].taint
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
else ### Ruby 1.9 !!!!!!!!!!!
+=begin
@interp_thread = Thread.new{
Thread.current[:interp] = interp = TclTkIp.new(name, _keys2opts(tk_opts))
interp.instance_eval{
- @force_default_encoding ||= [false].taint
- @encoding ||= [nil].taint
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
}
@@ -1324,15 +1349,74 @@ class MultiTkIp
end
# INTERP_THREAD.run
@interp = @interp_thread[:interp]
+=end
+ @interp_thread = Thread.new{
+ current = Thread.current
+ begin
+ current[:interp] = interp = TclTkIp.new(name, _keys2opts(tk_opts))
+ rescue e
+ current[:interp] = e
+ raise e
+ end
+ #sleep
+ #TclTkLib.mainloop(true)
+ current[:mutex] = mutex = Mutex.new
+ current[:root_check] = cond_ver = ConditionVariable.new
+
+ status = [nil]
+ def status.value
+ self[0]
+ end
+ def status.value=(val)
+ self[0] = val
+ end
+ current[:status] = status
+
+ begin
+ current[:status].value = interp.mainloop(true)
+ rescue SystemExit=>e
+ current[:status].value = e
+ rescue Exception=>e
+ current[:status].value = e
+ retry if interp.has_mainwindow?
+ ensure
+ mutex.synchronize{ cond_var.broadcast }
+ end
+ current[:status].value = interp.mainloop(false)
+ }
+ until @interp_thread[:interp]
+ Thread.pass
+ end
+ # INTERP_THREAD.run
+ @interp = @interp_thread[:interp]
+
+ @evloop_thread[0] = @interp_thread
+
+ def self.mainloop(check_root = true)
+ begin
+ TclTkLib.set_eventloop_window_mode(true)
+ @interp_thread.value
+ ensure
+ TclTkLib.set_eventloop_window_mode(false)
+ end
+ end
end
+ @interp.instance_eval{
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
+ def @encoding.to_s; self.join(nil); end
+ }
+
@ip_name = nil
+
if safe
safe = $SAFE if safe < $SAFE
@safe_level = [safe]
else
@safe_level = [$SAFE]
end
+
else
# create slave-ip
if safeip || master.safe?
@@ -1365,8 +1449,8 @@ class MultiTkIp
@system = Object.new
- @wait_on_mainloop = [true, 0].taint
- # @wait_on_mainloop = [false, 0].taint
+ @wait_on_mainloop = TkUtil.untrust([true, 0])
+ # @wait_on_mainloop = TkUtil.untrust([false, 0])
@threadgroup = ThreadGroup.new
@@ -1386,8 +1470,7 @@ class MultiTkIp
@@IP_TABLE[@threadgroup] = self
@@TK_TABLE_LIST.size.times{
- (tbl = {}).tainted? || tbl.taint
- @tk_table_list << tbl
+ @tk_table_list << TkUtil.untrust({})
}
_init_ip_internal(@@INIT_IP_ENV, @@ADD_TK_PROCS)
@@ -1435,6 +1518,17 @@ end
# get target IP
class MultiTkIp
+ @@CALLBACK_SUBTHREAD = Class.new(Thread){
+ def self.new(interp, &blk)
+ super(interp){|ip| Thread.current[:callback_ip] = ip; blk.call}
+ end
+
+ @table = TkUtil.untrust(Hash.new{|h,k| h[k] = TkUtil.untrust([])})
+ def self.table
+ @table
+ end
+ }
+
def self._ip_id_
__getip._ip_id_
end
@@ -1445,6 +1539,9 @@ class MultiTkIp
def self.__getip
current = Thread.current
+ if current.kind_of?(@@CALLBACK_SUBTHREAD)
+ return current[:callback_ip]
+ end
if TclTkLib.mainloop_thread? != false && current[:callback_ip]
return current[:callback_ip]
end
@@ -1467,11 +1564,11 @@ class << MultiTkIp
alias __new new
private :__new
- def new_master(safe=nil, keys={})
+ def new_master(safe=nil, keys={}, &blk)
if MultiTkIp::WITH_RUBY_VM
#### TODO !!!!!!
fail RuntimeError,
- 'sorry, still not support multiple master-interpreters on Ruby VM'
+ 'sorry, still not support multiple master-interpreters on RubyVM'
end
if safe.kind_of?(Hash)
@@ -1489,15 +1586,17 @@ class << MultiTkIp
ip = __new(__getip, nil, keys)
#ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
- if block_given?
- Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
- end
+ if block_given?
+ #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
+ #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; yield}.call)}
+ ip._proc_on_safelevel(&blk).call(ip.safe_level)
+ end
ip
end
alias new new_master
- def new_slave(safe=nil, keys={})
+ def new_slave(safe=nil, keys={}, &blk)
if safe.kind_of?(Hash)
keys = safe
elsif safe.kind_of?(Integer)
@@ -1514,13 +1613,15 @@ class << MultiTkIp
ip = __new(__getip, false, keys)
# ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
if block_given?
- Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
+ #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
+ #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; yield}.call)}
+ ip._proc_on_safelevel(&blk).call(ip.safe_level)
end
ip
end
alias new_trusted_slave new_slave
- def new_safe_slave(safe=4, keys={})
+ def new_safe_slave(safe=4, keys={}, &blk)
if safe.kind_of?(Hash)
keys = safe
elsif safe.kind_of?(Integer)
@@ -1535,7 +1636,9 @@ class << MultiTkIp
ip = __new(__getip, true, keys)
# ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call) if block_given?
if block_given?
- Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
+ #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; Proc.new}.call)}
+ #Thread.new{ip.eval_proc(proc{$SAFE=ip.safe_level; yield}.call)}
+ ip._proc_on_safelevel(&blk).call(ip.safe_level)
end
ip
end
@@ -1669,8 +1772,7 @@ class MultiTkIp
def _add_new_tables
(@@TK_TABLE_LIST.size - @tk_table_list.size).times{
- (tbl = {}).tainted? || tbl.taint
- @tk_table_list << tbl
+ @tk_table_list << TkUtil.untrust({})
}
end
@@ -1813,7 +1915,6 @@ class MultiTkIp
end
end
-
# for callback operation
class MultiTkIp
def self.cb_entry_class
@@ -1838,12 +1939,20 @@ class MultiTkIp
end
=end
def cb_eval(cmd, *args)
+ self.eval_callback(*args,
+ &_proc_on_safelevel{|*params|
+ TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))
+ })
+ end
+=begin
+ def cb_eval(cmd, *args)
self.eval_callback(*args){|safe, *params|
$SAFE=safe if $SAFE < safe
# TkUtil.eval_cmd(cmd, *params)
TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params))
}
end
+=end
=begin
def cb_eval(cmd, *args)
@callback_status[0] ||= TkVariable.new
@@ -1938,6 +2047,48 @@ end
# evaluate a procedure on the proper interpreter
class MultiTkIp
+ # instance & class method
+ def _proc_on_safelevel(cmd=nil, &blk) # require a block for eval
+ if cmd
+ if cmd.kind_of?(Method)
+ _proc_on_safelevel{|*args| cmd.call(*args)}
+ else
+ _proc_on_safelevel(&cmd)
+ end
+ else
+ #Proc.new{|safe, *args| $SAFE=safe if $SAFE < safe; yield(*args)}
+ Proc.new{|safe, *args|
+ # avoid security error on Exception objects
+ untrust_proc = proc{|err|
+ begin
+ err.untrust if err.respond_to?(:untrust)
+ rescue SecurityError
+ end
+ err
+ }
+ $SAFE=safe if $SAFE < safe;
+ begin
+ yield(*args)
+ rescue Exception => e
+ fail untrust_proc.call(e)
+ end
+ }
+ end
+ end
+ def MultiTkIp._proc_on_safelevel(cmd=nil, &blk)
+ MultiTkIp.__getip._proc_on_safelevel(cmd, &blk)
+ end
+
+ def _proc_on_current_safelevel(cmd=nil, &blk) # require a block for eval
+ safe = $SAFE
+ cmd = _proc_on_safelevel(cmd, &blk)
+ Proc.new{|*args| cmd.call(safe, *args)}
+ end
+ def MultiTkIp._proc_on_current_safelevel(cmd=nil, &blk)
+ MultiTkIp.__getip._proc_on_current_safelevel(cmd, &blk)
+ end
+
+ ######################################
# instance method
def eval_proc_core(req_val, cmd, *args)
# check
@@ -1953,10 +2104,10 @@ class MultiTkIp
ret = cmd.call(safe_level, *args)
rescue SystemExit => e
# exit IP
- warn("Warning: "+ $! + " on " + self.inspect) if $DEBUG
+ warn("Warning: "+ e.inspect + " on " + self.inspect) if $DEBUG
begin
self._eval_without_enc('exit')
- rescue Exception
+ rescue Exception => e
end
self.delete
ret = nil
@@ -2008,7 +2159,7 @@ class MultiTkIp
return ret.value
rescue SystemExit => e
# exit IP
- warn("Warning: " + $! + " on " + self.inspect) if $DEBUG
+ warn("Warning: " + e.inspect + " on " + self.inspect) if $DEBUG
begin
self._eval_without_enc('exit')
rescue Exception
@@ -2031,22 +2182,76 @@ class MultiTkIp
end
private :eval_proc_core
+if WITH_RUBY_VM ### Ruby 1.9
+ def eval_callback(*args)
+ if block_given?
+ cmd = Proc.new
+ else
+ cmd = args.shift
+ end
+ begin
+ if @@CALLBACK_SUBTHREAD.table[self].index(Thread.current)
+ last_th = nil
+ else
+ last_th = @@CALLBACK_SUBTHREAD.table[self][-1]
+ end
+ @@CALLBACK_SUBTHREAD.new(self){
+ @@CALLBACK_SUBTHREAD.table[self] << Thread.current
+ begin
+ last_th.join if last_th
+ eval_proc_core(false, cmd, *args)
+ rescue Exception=>e
+ e
+ ensure
+ @@CALLBACK_SUBTHREAD.table[self].delete(Thread.current)
+ end
+ }
+ end
+ end
+else ### Ruby 1.8
def eval_callback(*args)
if block_given?
cmd = Proc.new
else
cmd = args.shift
end
- current = Thread.current
- backup_ip = current[:callback_ip]
- current[:callback_ip] = self
begin
eval_proc_core(false, cmd, *args)
+ rescue Exception=>e
+ e
ensure
- current[:callback_ip] = backup_ip
end
end
+end
+ def eval_proc(*args, &blk)
+ if block_given?
+ cmd = _proc_on_safelevel(&blk)
+ else
+ unless (cmd = args.shift)
+ fail ArgumentError, "A Proc or Method object is expected for 1st argument"
+ end
+ cmd = _proc_on_safelevel(&cmd)
+ end
+ if TclTkLib.mainloop_thread? == true
+ # call from eventloop
+ current = Thread.current
+ backup_ip = current[:callback_ip]
+ current[:callback_ip] = self
+ begin
+ eval_proc_core(false, cmd, *args)
+ ensure
+ current[:callback_ip] = backup_ip
+ end
+ else
+ eval_proc_core(true,
+ proc{|safe, *params|
+ Thread.new{cmd.call(safe, *params)}.value
+ },
+ *args)
+ end
+ end
+=begin
def eval_proc(*args)
# The scope of the eval-block of 'eval_proc' method is different from
# the external. If you want to pass local values to the eval-block,
@@ -2081,6 +2286,7 @@ class MultiTkIp
*args)
end
end
+=end
alias call eval_proc
def bg_eval_proc(*args)
@@ -2478,7 +2684,8 @@ end
# depend on TclTkIp
class MultiTkIp
- def mainloop(check_root = true, restart_on_dead = true)
+# def mainloop(check_root = true, restart_on_dead = true)
+ def mainloop(check_root = true, restart_on_dead = false)
raise SecurityError, "no permission to manipulate" unless self.manipulable?
if WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!!
@@ -2507,7 +2714,7 @@ class MultiTkIp
end
rescue SystemExit => e
# exit IP
- warn("Warning: " + $! + " on " + self.inspect) if $DEBUG
+ warn("Warning: " + e.inspect + " on " + self.inspect) if $DEBUG
begin
self._eval_without_enc('exit')
rescue Exception
diff --git a/ext/tk/lib/remote-tk.rb b/ext/tk/lib/remote-tk.rb
index f56864687e..0fa713359e 100644
--- a/ext/tk/lib/remote-tk.rb
+++ b/ext/tk/lib/remote-tk.rb
@@ -10,8 +10,8 @@ class MultiTkIp; end
class RemoteTkIp < MultiTkIp; end
class MultiTkIp
- @@IP_TABLE = {}.taint unless defined?(@@IP_TABLE)
- @@TK_TABLE_LIST = [].taint unless defined?(@@TK_TABLE_LIST)
+ @@IP_TABLE = TkUtil.untrust({}) unless defined?(@@IP_TABLE)
+ @@TK_TABLE_LIST = TkUtil.untrust([]) unless defined?(@@TK_TABLE_LIST)
def self._IP_TABLE; @@IP_TABLE; end
def self._TK_TABLE_LIST; @@TK_TABLE_LIST; end
@@ -88,14 +88,14 @@ class RemoteTkIp
@slave_ip_tbl = {}
@slave_ip_top = {}
- @force_default_encoding ||= [false].taint
- @encoding ||= [nil].taint
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
- @tk_windows.taint unless @tk_windows.tainted?
- @tk_table_list.taint unless @tk_table_list.tainted?
- @slave_ip_tbl.taint unless @slave_ip_tbl.tainted?
- @slave_ip_top.taint unless @slave_ip_top.tainted?
+ TkUtil.untrust(@tk_windows) unless @tk_windows.tainted?
+ TkUtil.untrust(@tk_table_list) unless @tk_table_list.tainted?
+ TkUtil.untrust(@slave_ip_tbl) unless @slave_ip_tbl.tainted?
+ TkUtil.untrust(@slave_ip_top) unless @slave_ip_top.tainted?
@system = Object.new
@@ -119,7 +119,7 @@ class RemoteTkIp
@@IP_TABLE[@threadgroup] = self
@@TK_TABLE_LIST.size.times{
- (tbl = {}).tainted? || tbl.taint
+ (tbl = {}).tainted? || TkUtil.untrust(tbl)
@tk_table_list << tbl
}
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index 49e4ca2564..b071bf5be8 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -15,7 +15,9 @@ require 'thread'
class TclTkIp
# backup original (without encoding) _eval and _invoke
alias _eval_without_enc _eval
+ alias __eval__ _eval
alias _invoke_without_enc _invoke
+ alias __invoke__ _invoke
def _ip_id_
# for RemoteTkIp
@@ -28,8 +30,8 @@ class TclTkIp
def initialize(*args)
__initialize__(*args)
- @force_default_encoding ||= [false].taint
- @encoding ||= [nil].taint
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
end
end
@@ -39,8 +41,8 @@ module TkComm
include TkUtil
extend TkUtil
- WidgetClassNames = {}.taint
- TkExtlibAutoloadModule = [].taint
+ WidgetClassNames = TkUtil.untrust({})
+ TkExtlibAutoloadModule = TkUtil.untrust([])
# None = Object.new ### --> definition is moved to TkUtil module
# def None.to_s
@@ -50,7 +52,10 @@ module TkComm
#Tk_CMDTBL = {}
#Tk_WINDOWS = {}
- Tk_IDs = ["00000".taint, "00000".taint] # [0]-cmdid, [1]-winid
+ Tk_IDs = [
+ TkUtil.untrust("00000"), # [0]-cmdid
+ TkUtil.untrust("00000") # [1]-winid
+ ]
Tk_IDs.instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
@@ -70,7 +75,7 @@ module TkComm
Tk_WINDOWS.freeze
self.instance_eval{
- @cmdtbl = [].taint
+ @cmdtbl = TkUtil.untrust([])
}
unless const_defined?(:GET_CONFIGINFO_AS_ARRAY)
@@ -113,15 +118,22 @@ module TkComm
gen_class_name = ruby_class_name
classname_def = ''
else # ruby_class == nil
- mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)}
- mods.each{|mod|
- begin
- mod.const_get(tk_class) # auto_load
- break if (ruby_class = WidgetClassNames[tk_class])
- rescue LoadError
- # ignore load error
- end
- }
+ if Tk.const_defined?(tk_class)
+ mod.const_get(tk_class) # auto_load
+ ruby_class = WidgetClassNames[tk_class]
+ end
+
+ unless ruby_class
+ mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)}
+ mods.each{|mod|
+ begin
+ mod.const_get(tk_class) # auto_load
+ break if (ruby_class = WidgetClassNames[tk_class])
+ rescue LoadError
+ # ignore load error
+ end
+ }
+ end
unless ruby_class
std_class = 'Tk' << tk_class
@@ -131,6 +143,14 @@ module TkComm
end
end
+ unless ruby_class
+ if Tk.const_defined?('TOPLEVEL_ALIASES') &&
+ Tk::TOPLEVEL_ALIASES.const_defined?(std_class)
+ Tk::TOPLEVEL_ALIASES.const_get(std_class) # auto_load
+ ruby_class = WidgetClassNames[tk_class]
+ end
+ end
+
if ruby_class
# found
ruby_class_name = ruby_class.name
@@ -613,11 +633,35 @@ end
val
end
end
- private :bool, :number, :string, :num_or_str
- private :list, :simplelist, :window, :procedure
- module_function :bool, :number, :num_or_str, :string
+ private :bool, :number, :num_or_str, :num_or_nil, :string
+ private :list, :simplelist, :window, :image_obj, :procedure
+ module_function :bool, :number, :num_or_str, :num_or_nil, :string
module_function :list, :simplelist, :window, :image_obj, :procedure
+ if (RUBY_VERSION.split('.').map{|n| n.to_i} <=> [1,8,7]) < 0
+ def slice_ary(ary, size)
+ sliced = []
+ wk_ary = ary.dup
+ until wk_ary.size.zero?
+ sub_ary = []
+ size.times{ sub_ary << wk_ary.shift }
+ yield(sub_ary) if block_given?
+ sliced << sub_ary
+ end
+ (block_given?)? ary: sliced
+ end
+ else
+ def slice_ary(ary, size, &b)
+ if b
+ ary.each_slice(size, &b)
+ else
+ ary.each_slice(size).to_a
+ end
+ end
+ end
+ private :slice_ary
+ module_function :slice_ary
+
def subst(str, *opts)
# opts := :nobackslashes | :nocommands | novariables
tk_call('subst',
@@ -803,7 +847,7 @@ end
TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd)
end
@cmdtbl = [] unless defined? @cmdtbl
- @cmdtbl.taint unless @cmdtbl.tainted?
+ TkUtil.untrust(@cmdtbl) unless @cmdtbl.tainted?
@cmdtbl.push id
if local_cmdtbl && local_cmdtbl.kind_of?(Array)
@@ -1130,30 +1174,42 @@ module TkCore
opts = ''
end
- if WITH_RUBY_VM ### check Ruby 1.9 !!!!!!!
- # *** NEED TO FIX ***
- ip = TclTkIp.new(name, opts)
- if ip._invoke_without_enc('tk', 'windowingsystem') == 'aqua' &&
- (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
- # *** KNOWN BUG ***
- # Main event loop thread of TkAqua (> Tk8.4.9) must be the main
- # application thread. So, ruby1.9 users must call Tk.mainloop on
- # the main application thread.
- RUN_EVENTLOOP_ON_MAIN_THREAD = true
- INTERP = ip
- else
- unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
- RUN_EVENTLOOP_ON_MAIN_THREAD = false
- end
- if RUN_EVENTLOOP_ON_MAIN_THREAD
+ unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
+ if WITH_RUBY_VM ### check Ruby 1.9 !!!!!!!
+ # *** NEED TO FIX ***
+ ip = TclTkIp.new(name, opts)
+ if ip._invoke_without_enc('tk', 'windowingsystem') == 'aqua' &&
+ (TclTkLib.get_version<=>[8,4,TclTkLib::RELEASE_TYPE::FINAL,6]) > 0
+ # *** KNOWN BUG ***
+ # Main event loop thread of TkAqua (> Tk8.4.9) must be the main
+ # application thread. So, ruby1.9 users must call Tk.mainloop on
+ # the main application thread.
+ #
+ # *** ADD (2009/05/10) ***
+ # In some cases (I don't know the description of conditions),
+ # TkAqua 8.4.7 has a same kind of hang-up trouble.
+ # So, if 8.4.7 or later, set RUN_EVENTLOOP_ON_MAIN_THREAD to true.
+ # When you want to control this mode, please call the following
+ # (set true/false as you want) before "require 'tk'".
+ # ----------------------------------------------------------
+ # module TkCore; RUN_EVENTLOOP_ON_MAIN_THREAD = true; end
+ # ----------------------------------------------------------
+ #
+ RUN_EVENTLOOP_ON_MAIN_THREAD = true
INTERP = ip
else
- ip.delete
+ unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
+ RUN_EVENTLOOP_ON_MAIN_THREAD = false
+ end
+ if RUN_EVENTLOOP_ON_MAIN_THREAD
+ INTERP = ip
+ else
+ ip.delete
+ end
end
- end
- ip = nil
- else
- unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD
+ ip = nil
+
+ else # Ruby 1.8.x
RUN_EVENTLOOP_ON_MAIN_THREAD = false
end
end
@@ -1183,13 +1239,29 @@ module TkCore
#sleep
begin
- Thread.current[:status].value = TclTkLib.mainloop(true)
- rescue Exception=>e
- Thread.current[:status].value = e
+ begin
+ #TclTkLib.mainloop_abort_on_exception = false
+ #Thread.current[:status].value = TclTkLib.mainloop(true)
+ interp.mainloop_abort_on_exception = true
+ Thread.current[:status].value = interp.mainloop(true)
+ rescue SystemExit=>e
+ Thread.current[:status].value = e
+ rescue Exception=>e
+ Thread.current[:status].value = e
+ retry if interp.has_mainwindow?
+ ensure
+ INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }
+ end
+
+ #Thread.current[:status].value = TclTkLib.mainloop(false)
+ Thread.current[:status].value = interp.mainloop(false)
+
ensure
- INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast }
+ # interp must be deleted before the thread for interp is dead.
+ # If not, raise Tcl_Panic on Tcl_AsyncDelete because async handler
+ # deleted by the wrong thread.
+ interp.delete
end
- Thread.current[:status].value = TclTkLib.mainloop(false)
}
until INTERP_THREAD[:interp]
@@ -1210,10 +1282,11 @@ module TkCore
end
INTERP.instance_eval{
- # @tk_cmd_tbl = {}.taint
- @tk_cmd_tbl = Hash.new{|hash, key|
- fail IndexError, "unknown command ID '#{key}'"
- }.taint
+ # @tk_cmd_tbl = TkUtil.untrust({})
+ @tk_cmd_tbl =
+ TkUtil.untrust(Hash.new{|hash, key|
+ fail IndexError, "unknown command ID '#{key}'"
+ })
def @tk_cmd_tbl.[]=(idx,val)
if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default
fail SecurityError,"cannot change the entried command"
@@ -1221,15 +1294,15 @@ module TkCore
super(idx,val)
end
- @tk_windows = {}.taint
+ @tk_windows = TkUtil.untrust({})
- @tk_table_list = [].taint
+ @tk_table_list = TkUtil.untrust([])
- @init_ip_env = [].taint # table of Procs
- @add_tk_procs = [].taint # table of [name, args, body]
+ @init_ip_env = TkUtil.untrust([]) # table of Procs
+ @add_tk_procs = TkUtil.untrust([]) # table of [name, args, body]
- @force_default_encoding ||= [false].taint
- @encoding ||= [nil].taint
+ @force_default_encoding ||= TkUtil.untrust([false])
+ @encoding ||= TkUtil.untrust([nil])
def @encoding.to_s; self.join(nil); end
@cb_entry_class = Class.new(TkCallbackEntry){
@@ -1283,7 +1356,7 @@ module TkCore
end
def INTERP.create_table
id = @tk_table_list.size
- (tbl = {}).tainted? || tbl.taint
+ (tbl = {}).tainted? || TkUtil.untrust(tbl)
@tk_table_list << tbl
# obj = Object.new
# obj.instance_eval <<-EOD
@@ -1321,7 +1394,8 @@ module TkCore
@add_tk_procs.delete_if{|elem|
elem.kind_of?(Array) && elem[0].to_s == name
}
- self._invoke('rename', name, '')
+ #self._invoke('rename', name, '')
+ self.__invoke__('rename', name, '')
}
end
def INTERP.init_ip_internal
@@ -1704,11 +1778,14 @@ module TkCore
elsif TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD
# if TclTkLib::WINDOWING_SYSTEM == 'aqua' &&
- if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='aqua' &&
- Thread.current != Thread.main &&
- (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
- raise RuntimeError,
- "eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only"
+ #if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='aqua' &&
+ # Thread.current != Thread.main &&
+ # (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0
+ # raise RuntimeError,
+ # "eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only"
+ #end
+ if Thread.current != Thread.main
+ raise RuntimeError, "Tk.mainloop is allowed on the main thread only"
end
TclTkLib.mainloop(check_root)
@@ -1911,7 +1988,7 @@ module TkCore
puts 'invoke args => ' + args.inspect if $DEBUG
### print "=> ", args.join(" ").inspect, "\n" if $DEBUG
begin
- # res = INTERP._invoke(*args).taint
+ # res = TkUtil.untrust(INTERP._invoke(*args))
# res = INTERP._invoke(enc_mode, *args)
res = _ip_invoke_core(enc_mode, *args)
# >>>>> _invoke returns a TAINTED string <<<<<
@@ -1919,7 +1996,7 @@ module TkCore
# err = $!
begin
args.unshift "unknown"
- #res = INTERP._invoke(*args).taint
+ #res = TkUtil.untrust(INTERP._invoke(*args))
#res = INTERP._invoke(enc_mode, *args)
res = _ip_invoke_core(enc_mode, *args)
# >>>>> _invoke returns a TAINTED string <<<<<
@@ -3028,7 +3105,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
=begin
if ext_enc_obj == Tk::Encoding::UNKNOWN
- if defind? DEFAULT_TK_ENCODING
+ if defined? DEFAULT_TK_ENCODING
if DEFAULT_TK_ENCODING.kind_of?(::Encoding)
tk_enc_name = DEFAULT_TK_ENCODING.name
tksys_enc_name = DEFAULT_TK_ENCODING.name
@@ -3126,7 +3203,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK)
#if ext_enc_name && ext_enc_name != tksys_enc_name
int_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(int_enc_obj)
if int_enc_name
- # use default_external
+ # use default_internal
enc_name = int_enc_name
else
# use Tk.encoding_system
@@ -3279,10 +3356,10 @@ module TkTreatFont
TkFont.init_widget_font(pathname, *__confinfo_cmd)
else
fonts = {}
- optkeys.each{|key|
- key = key.to_s
- pathname = [win, tag, key].join(';')
- fonts[key] =
+ optkeys.each{|k|
+ k = k.to_s
+ pathname = [win, tag, k].join(';')
+ fonts[k] =
TkFont.used_on(pathname) ||
TkFont.init_widget_font(pathname, *__confinfo_cmd)
}
@@ -3407,7 +3484,7 @@ module TkTreatFont
if fobj.kind_of?(TkFont)
if ltn.kind_of?(TkFont)
conf = {}
- ltn.latin_configinfo.each{|key,val| conf[key] = val}
+ ltn.latin_configinfo.each{|k,val| conf[k] = val}
if keys
fobj.latin_configure(conf.update(keys))
else
@@ -3467,7 +3544,7 @@ module TkTreatFont
if fobj.kind_of?(TkFont)
if knj.kind_of?(TkFont)
conf = {}
- knj.kanji_configinfo.each{|key,val| conf[key] = val}
+ knj.kanji_configinfo.each{|k,val| conf[k] = val}
if keys
fobj.kanji_configure(conf.update(keys))
else
@@ -3701,11 +3778,17 @@ module TkConfigMethod
val
end
+ def cget_tkstring(option)
+ opt = option.to_s
+ fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.length == 0
+ tk_call_without_enc(*(__cget_cmd << "-#{opt}"))
+ end
+
def __cget_core(slot)
orig_slot = slot
slot = slot.to_s
- if slot.length == 0
+ if slot.length == 0
fail ArgumentError, "Invalid option `#{orig_slot.inspect}'"
end
@@ -4106,7 +4189,8 @@ module TkConfigMethod
else
# conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}"))))
- conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true)
+ # conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true)
+ conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 1, false, true)
end
conf[__configinfo_struct[:key]] =
conf[__configinfo_struct[:key]][1..-1]
@@ -4296,8 +4380,8 @@ module TkConfigMethod
end
}
- __methodcall_optkeys.each{|optkey, method|
- ret << [optkey.to_s, '', '', '', self.__send__(method)]
+ __methodcall_optkeys.each{|optkey, m|
+ ret << [optkey.to_s, '', '', '', self.__send__(m)]
}
ret
@@ -4335,7 +4419,7 @@ module TkConfigMethod
if slot
slot = slot.to_s
- alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot}
+ alias_name, real_name = __optkey_aliases.find{|k,var| k.to_s == slot}
if real_name
slot = real_name.to_s
end
@@ -4682,8 +4766,8 @@ module TkConfigMethod
end
}
- __methodcall_optkeys.each{|optkey, method|
- ret[optkey.to_s] = ['', '', '', self.__send__(method)]
+ __methodcall_optkeys.each{|optkey, m|
+ ret[optkey.to_s] = ['', '', '', self.__send__(m)]
}
ret
@@ -4721,18 +4805,18 @@ module TkConfigMethod
"there is a configure alias loop about '#{org_slot}'"
else
ret = {}
- configinfo().each{|conf|
+ configinfo().each{|cnf|
if ( ! __configinfo_struct[:alias] \
- || conf.size > __configinfo_struct[:alias] + 1 )
- ret[conf[0]] = conf[-1]
+ || cnf.size > __configinfo_struct[:alias] + 1 )
+ ret[cnf[0]] = cnf[-1]
end
}
ret
end
else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
ret = {}
- configinfo(slot).each{|key, conf|
- ret[key] = conf[-1] if conf.kind_of?(Array)
+ configinfo(slot).each{|key, cnf|
+ ret[key] = cnf[-1] if cnf.kind_of?(Array)
}
ret
end
@@ -4864,6 +4948,7 @@ class TkWindow<TkObject
include TkWinfo
extend TkBindCore
include Tk::Wm_for_General
+ include Tk::Busy
@@WIDGET_INSPECT_FULL = false
def TkWindow._widget_inspect_full_?
@@ -5551,7 +5636,7 @@ TkWidget = TkWindow
#Tk.freeze
module Tk
- RELEASE_DATE = '2009-01-13'.freeze
+ RELEASE_DATE = '2009-07-12'.freeze
autoload :AUTO_PATH, 'tk/variable'
autoload :TCL_PACKAGE_PATH, 'tk/variable'
diff --git a/ext/tk/lib/tk/autoload.rb b/ext/tk/lib/tk/autoload.rb
index df888eb927..2ebee9ea24 100644
--- a/ext/tk/lib/tk/autoload.rb
+++ b/ext/tk/lib/tk/autoload.rb
@@ -27,6 +27,8 @@ def TkPlace(*args); TkPlace.configure(*args); end
############################################
# classes on Tk module
module Tk
+ autoload :Busy, 'tk/busy'
+
autoload :Button, 'tk/button'
autoload :Canvas, 'tk/canvas'
@@ -319,9 +321,16 @@ module Tk
@TOPLEVEL_ALIAS_SETUP_PROC = {}
+ @AUTOLOAD_FILE_SYM_TABLE = Hash.new{|h,k| h[k]={}} # TABLE[file][sym] -> obj
+
@current_default_widget_set = nil
+
+ module TOPLEVEL_ALIASES; end
end
+class Object
+ include Tk::TOPLEVEL_ALIASES
+end
############################################
# methods to control default widget set
@@ -343,50 +352,387 @@ class << Tk
_replace_toplevel_aliases(target)
end
- def __set_toplevel_aliases__(target, obj, *symbols)
+ def widget_set_symbols
+ @TOPLEVEL_ALIAS_TABLE.keys
+ end
+
+ def toplevel_aliases_on_widget_set(widget_set)
+ if (tbl = @TOPLEVEL_ALIAS_TABLE[widget_set.to_sym])
+ tbl.collect{|k, v| (v.nil?)? nil: k}.compact
+ else
+ fail ArgumentError, "unknown widget_set #{widget_set.to_sym.inspect}"
+ end
+ end
+
+ def __toplevel_alias_setup_proc__(*target_list, &cmd)
+ target_list.each{|target| @TOPLEVEL_ALIAS_SETUP_PROC[target.to_sym] = cmd}
+ end
+
+ def topobj_defined?(sym) #=> alias_filename or object or false
+ Object.autoload?(sym) ||
+ (Object.const_defined?(sym) && Object.const_get(sym))
+ end
+ def topalias_defined?(sym) #=> alias_filename or object or false
+ Tk::TOPLEVEL_ALIASES.autoload?(sym) ||
+ (Tk::TOPLEVEL_ALIASES.const_defined?(sym) &&
+ Tk::TOPLEVEL_ALIASES.const_get(sym))
+ end
+ def define_topobj(sym, obj)
+ if obj.kind_of? String
+ # obj is an autoload path
+ Object.autoload(sym, obj)
+ unless Object.autoload?(sym)
+ # file is autoloaded?
+ if @AUTOLOAD_FILE_SYM_TABLE.has_key?(obj) &&
+ (loaded_obj = @AUTOLOAD_FILE_SYM_TABLE[obj][sym])
+ Object.const_set(sym, loaded_obj)
+ else
+ fail ArgumentError, "cannot define autoload file (already loaded?)"
+ end
+ end
+ else
+ # object
+ Object.const_set(sym, obj)
+ end
+ end
+ def define_topalias(sym, obj)
+ if obj.kind_of? String
+ # obj is an autoload path
+ Tk::TOPLEVEL_ALIASES.autoload(sym, obj)
+ unless Tk::TOPLEVEL_ALIASES.autoload?(sym)
+ # file is autoloaded?
+ if @AUTOLOAD_FILE_SYM_TABLE.has_key?(obj) &&
+ (loaded_obj = @AUTOLOAD_FILE_SYM_TABLE[obj][sym])
+ Tk::TOPLEVEL_ALIASES.const_set(sym, loaded_obj)
+ else
+ fail ArgumentError, "cannot define autoload file (already loaded?)"
+ end
+ end
+ else
+ # object
+ Tk::TOPLEVEL_ALIASES.const_set(sym, obj)
+ end
+ end
+ def replace_topobj(sym, obj) #=> old_obj (alias_filename or object) or nil
+ if old_obj = topobj_defined?(sym)
+ Object.class_eval{remove_const sym} rescue nil # ignore err
+ end
+ define_topobj(sym, obj)
+ old_obj
+ end
+ def replace_topalias(sym, obj) #=> old_obj (alias_filename or object) or nil
+ if old_obj = topalias_defined?(sym)
+ Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} rescue nil #ignore err
+ end
+ define_topalias(sym, obj)
+ old_obj
+ end
+ private :topobj_defined?, :topalias_defined?
+ private :define_topobj, :define_topalias
+ private :replace_topobj, :replace_topalias
+
+ def __regist_toplevel_aliases__(target, obj, *symbols)
+ # initial regist
@TOPLEVEL_ALIAS_TABLE[target = target.to_sym] ||= {}
symbols.each{|sym|
@TOPLEVEL_ALIAS_TABLE[target][sym = sym.to_sym] = obj
- # if @current_default_widget_set == target
- if @TOPLEVEL_ALIAS_OWNER[sym] == target
- Object.class_eval{remove_const sym} if Object.const_defined?(sym)
- Object.const_set(sym, obj)
+ if !topalias_defined?(sym) || target == @current_default_widget_set
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj) unless obj.kind_of?(String) # NOT autoload
end
}
end
- ###################################
- private
- def _replace_toplevel_aliases(target)
- # check already autoloaded
- if (table = @TOPLEVEL_ALIAS_TABLE[current = @current_default_widget_set])
- table.each{|sym, file|
- if !Object.autoload?(sym) && Object.const_defined?(sym) &&
- @TOPLEVEL_ALIAS_TABLE[current][sym].kind_of?(String)
- # autoload -> class
- @TOPLEVEL_ALIAS_TABLE[current][sym] = Object.const_get(sym)
+ def regist_sym_for_loaded_file(auto, obj, sym)
+ @AUTOLOAD_FILE_SYM_TABLE[auto][sym] = obj
+
+ reg = /^#{Regexp.quote(auto)}(\.rb|\.so|)$/
+ @TOPLEVEL_ALIAS_TABLE.each_key{|set|
+ if @TOPLEVEL_ALIAS_TABLE[set][sym] =~ reg
+ @TOPLEVEL_ALIAS_TABLE[set][sym] = obj
+ if @TOPLEVEL_ALIAS_OWNER[sym].nil? || @TOPLEVEL_ALIAS_OWNER[sym] == set
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj) if set == @current_default_widget_set
end
- }
+ end
+ }
+ if (f = Object.autoload?(sym)) && f =~ reg
+ replace_topobj(sym, obj)
end
+ if (f = Tk::TOPLEVEL_ALIASES.autoload?(sym)) && f =~ reg
+ replace_topalias(sym, obj)
+ end
+ end
+ private :regist_sym_for_loaded_file
+
+ def set_topalias(target, obj, sym)
+ # obj is a kind of String : define autoload path
+ # Class : use the class object
+ if target == @current_default_widget_set
+ case @TOPLEVEL_ALIAS_OWNER[sym]
+ when false
+ # Object::sym is out of control. --> not change
+ # Make ALIAS::sym under control, because target widget set is current.
+ # Keep OWNER[sym]
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+
+ when target
+ if current_obj = topobj_defined?(sym)
+ if current_obj == obj
+ # Make current_obj under control.
+ # Keep Object::sym.
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+
+ else # current_obj != obj
+ if current_obj == topalias_defined?(sym)
+ # Change controlled object
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+
+ else # current_obj != topalias_defined?(sym)
+ # Maybe current_obj is defined by user. --> OWNER[sym] = faise
+ # Keep Object::sym.
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ end
+ end
+
+ else # NOT topobj_defined?(sym)
+ # New definition for sym at target.
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ define_topobj(sym, obj)
+ end
+
+ when nil
+ # New definition for sym at target.
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+
+ else # others
+ # Maybe planning to make sym under control.
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+ end
+
+ else # target != @current_default_widget_set
+ case @TOPLEVEL_ALIAS_OWNER[sym]
+ when false
+ # Object::sym is out of control. --> not change
+ if topalias_defined?(sym)
+ # ALIAS[sym] may be defined by other widget set.
+ # Keep Object::sym (even if it is not defined)
+ # Keep ALIAS[sym].
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+
+ else # NOT topalias_defined?(sym)
+ # Nobody controls ALIAS[sym].
+ # At leaset, current widget set doesn't control ALIAS[sym].
+ # Keep Object::sym (even if it is not defined)
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ define_topalias(sym, obj)
+ end
+
+ when target
+ # Maybe change controlled object, because Object::sym is under control.
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+
+ when nil
+ # New definition for sym
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+
+ else # others
+ # An other widget set controls sym.
+ # Keep Object::sym (even if it is not defined)
+ # Keep ALIAS[sym].
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[target][sym] = obj
+
+ end
+ end
+
+ sym
+ end
+ private :set_topalias
- # setup autoloads
- @TOPLEVEL_ALIAS_TABLE[target].each{|sym, file|
- Object.class_eval{remove_const sym} if Object.const_defined?(sym)
- if file.kind_of?(String)
- # file => autoload target file
- Object.autoload(sym, file)
+ def __set_toplevel_aliases__(target, obj, *symbols)
+ # obj is a kind of String : define autoload path
+ # Class : use the class object
+ target = target.to_sym
+ symbols.each{|sym| set_topalias(target, obj, sym.to_sym)}
+ end
+
+ def __set_loaded_toplevel_aliases__(autopath, target, obj, *symbols)
+ # autopath is an autoload file
+ # Currently, this method doesn't support that autoload loads
+ # different toplevels between <basename>.rb and <basename>.so extension.
+ shortpath = (autopath =~ /^(.*)(.rb|.so)$/)? $1: autopath
+ target = target.to_sym
+ symbols.map!{|sym| sym.to_sym}
+
+ symbols.each{|sym| regist_sym_for_loaded_file(shortpath, obj, sym) }
+ symbols.each{|sym| set_topalias(target, obj, sym)}
+ end
+
+ def backup_current_topdef(sym)
+ return if (current = @current_default_widget_set).nil?
+
+ case @TOPLEVEL_ALIAS_OWNER[sym]
+ when false
+ # Object::sym is out of control.
+ if (cur_alias = topalias_defined?(sym)) && ! cur_alias.kind_of?(String)
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = cur_alias
+ end
+
+ when current
+ if cur_obj = topobj_defined?(sym)
+ if ! cur_obj.kind_of?(String) && (cur_alias = topalias_defined?(sym))
+ if cur_alias.kind_of?(String)
+ # Mayby, user replaced Object::sym.
+ # Make Object::sym out of control.
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ elsif cur_obj == cur_alias
+ # Possibley, defined normally. Backup it
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = cur_alias
+ else
+ # Mayby, user replaced Object::sym.
+ # Make Object::sym out of control.
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ end
+ end
+ else
+ # Mayby, user replaced Object::sym.
+ # Make Object::sym out of control.
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ end
+
+ when nil
+ # Object::sym is out of control.
+ if (cur_alias = topalias_defined?(sym)) && ! cur_alias.kind_of?(String)
+ # Possibley, defined normally. Backup it.
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = cur_alias
+ end
+ else
+ # No authority to control Object::sym and ALIASES::sym.
+ # Do nothing.
+ end
+ end
+ private :backup_current_topdef
+
+ def _replace_toplevel_aliases(target)
+ # backup
+ @TOPLEVEL_ALIAS_TABLE[target].each_key{|sym|
+ backup_current_topdef(sym)
+ }
+
+ # replace
+ @TOPLEVEL_ALIAS_TABLE[target].each_key{|sym|
+ next if (obj = @TOPLEVEL_ALIAS_TABLE[target][sym]).nil?
+ if @TOPLEVEL_ALIAS_OWNER[sym] == false
+ # Object::sym is out of control. --> not change
+ # Keep OWNER[sym].
+ replace_topalias(sym, obj)
else
- # file => loaded class object
- Object.const_set(sym, file)
+ # New definition
+ @TOPLEVEL_ALIAS_OWNER[sym] = target
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
end
- @TOPLEVEL_ALIAS_OWNER[sym] = target
}
- # update current alias
+ # change default_widget_set
@current_default_widget_set = target
end
+ private :_replace_toplevel_aliases
+
+ def __import_toplevel_aliases__(target, *symbols)
+ current = @current_default_widget_set
+ symbols.each{|sym|
+ sym = sym.to_sym
+ if (obj = @TOPLEVEL_ALIAS_TABLE[target][sym]).nil?
+ # remove
+ @TOPLEVEL_ALIAS_TABLE[current].delete(sym)
+ @TOPLEVEL_ALIAS_OWNER.delete(sym)
+ Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} if topalias_defined?(sym)
+ Object.class_eval{remove_const sym} if topobj_defined?(sym)
+
+ elsif obj == false
+ # remove, but OWNER[sym] <- false and not treat Object::sym
+ @TOPLEVEL_ALIAS_TABLE[current].delete(sym)
+ @TOPLEVEL_ALIAS_OWNER[sym] = false
+ Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} if topalias_defined?(sym)
+
+ elsif @TOPLEVEL_ALIAS_OWNER[sym] == false
+ # Object::sym is out of control. --> not change
+ # Keep OWNER[sym].
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = obj
+ replace_topalias(sym, obj)
+
+ else
+ # new definition under control
+ @TOPLEVEL_ALIAS_OWNER[sym] = current
+ @TOPLEVEL_ALIAS_TABLE[current][sym] = obj
+ replace_topalias(sym, obj)
+ replace_topobj(sym, obj)
+ end
+ }
+ end
+
+ def __remove_toplevel_aliases__(*symbols)
+ # remove toplevel aliases of current widget set
+ current = @current_default_widget_set
+ symbols.each{|sym|
+ sym = sym.to_sym
+ @TOPLEVEL_ALIAS_TABLE[current].delete(sym)
+ @TOPLEVEL_ALIAS_OWNER.delete(sym)
+ Tk::TOPLEVEL_ALIASES.module_eval{remove_const sym} if topalias_defined?(sym)
+ Object.class_eval{remove_const sym} if topobj_defined?(sym)
+ }
+ end
+
+ def __reset_toplevel_owner__(*symbols)
+ symbols.each{|sym| @TOPLEVEL_ALIAS_OWNER.delete(sym.to_sym)}
+ end
+
+ def __disable_toplevel_control__(*symbols)
+ symbols.each{|sym| @TOPLEVEL_ALIAS_OWNER[sym.to_sym] = false}
+ end
+
+ def __create_widget_set__(new_set, src_set={})
+ new_set = new_set.to_sym
+ if @TOPLEVEL_ALIAS_TABLE[new_set]
+ fail RuntimeError, "A widget-set #{new_set.inspect} is already exist."
+ end
+ if src_set.kind_of?(Symbol)
+ # new_set is an alias name of existed widget set.
+ @TOPLEVEL_ALIAS_TABLE[new_set] = @TOPLEVEL_ALIAS_TABLE[src_set]
+ else
+ @TOPLEVEL_ALIAS_TABLE[new_set] = {}
+ src_set.each{|sym, obj| set_topalias(new_set, obj, sym.to_sym) }
+ end
+ end
end
+
############################################
# setup default widget set => :Tk
Tk.default_widget_set = :Tk
diff --git a/ext/tk/lib/tk/bindtag.rb b/ext/tk/lib/tk/bindtag.rb
index 88c8367a88..23b4e0b7c3 100644
--- a/ext/tk/lib/tk/bindtag.rb
+++ b/ext/tk/lib/tk/bindtag.rb
@@ -9,7 +9,7 @@ class TkBindTag
#BTagID_TBL = {}
BTagID_TBL = TkCore::INTERP.create_table
- (Tk_BINDTAG_ID = ["btag".freeze, "00000".taint]).instance_eval{
+ (Tk_BINDTAG_ID = ["btag".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/busy.rb b/ext/tk/lib/tk/busy.rb
new file mode 100644
index 0000000000..7f4f89f524
--- /dev/null
+++ b/ext/tk/lib/tk/busy.rb
@@ -0,0 +1,118 @@
+#
+# tk/busy.rb: support 'tk busy' command (Tcl/Tk8.6 or later)
+#
+require 'tk'
+
+module Tk::Busy
+ include TkCore
+ extend TkCore
+ extend TkItemConfigMethod
+end
+
+class << Tk::Busy
+ def __item_cget_cmd(win)
+ # maybe need to override
+ ['tk', 'busy', 'cget', win.path]
+ end
+ private :__item_cget_cmd
+
+ def __item_config_cmd(win)
+ # maybe need to override
+ ['tk', 'busy', 'configure', win.path]
+ end
+ private :__item_config_cmd
+
+ def __item_confinfo_cmd(win)
+ # maybe need to override
+ __item_config_cmd(win)
+ end
+ private :__item_confinfo_cmd
+
+ alias cget_tkstring itemcget_tkstring
+ alias cget itemcget
+ alias cget_strict itemcget_strict
+ alias configure itemconfigure
+ alias configinfo itemconfiginfo
+ alias current_configinfo current_itemconfiginfo
+
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
+ private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+
+ def method_missing(id, *args)
+ name = id.id2name
+ case args.length
+ when 1
+ if name[-1] == ?=
+ configure name[0..-2], args[0]
+ args[0]
+ else
+ configure name, args[0]
+ self
+ end
+ when 0
+ begin
+ cget(name)
+ rescue
+ super(id, *args)
+ end
+ else
+ super(id, *args)
+ end
+ end
+
+ def hold(win, keys={})
+ tk_call_without_enc('tk', 'busy', 'hold', win, *hash_kv(keys))
+ win
+ end
+
+ def forget(*wins)
+ tk_call_without_enc('tk', 'busy', 'forget', *wins)
+ self
+ end
+
+ def current(pat=None)
+ list(tk_call('tk', 'busy', 'current', pat))
+ end
+
+ def status(win)
+ bool(tk_call_without_enc('tk', 'busy', 'status', win))
+ end
+end
+
+module Tk::Busy
+ def busy_configinfo(option=nil)
+ Tk::Busy.configinfo(self, option)
+ end
+
+ def busy_current_configinfo(option=nil)
+ Tk::Busy.current_configinfo(self, option)
+ end
+
+ def busy_configure(option, value=None)
+ Tk::Busy.configure(self, option, value)
+ self
+ end
+
+ def busy_cget(option)
+ Tk::Busy.configure(self, option)
+ end
+
+ def busy(keys={})
+ Tk::Busy.hold(self, keys)
+ self
+ end
+ alias busy_hold busy
+
+ def busy_forget
+ Tk::Busy.forget(self)
+ self
+ end
+
+ def busy_current?
+ ! Tk::Busy.current(self.path).empty?
+ end
+
+ def busy_status
+ Tk::Busy.status(self)
+ end
+end
diff --git a/ext/tk/lib/tk/button.rb b/ext/tk/lib/tk/button.rb
index 770a5785bb..65233c91b6 100644
--- a/ext/tk/lib/tk/button.rb
+++ b/ext/tk/lib/tk/button.rb
@@ -7,7 +7,7 @@ require 'tk/label'
class Tk::Button<Tk::Label
TkCommandNames = ['button'.freeze].freeze
WidgetClassName = 'Button'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('button', @path, *hash_kv(keys, true))
@@ -27,4 +27,5 @@ class Tk::Button<Tk::Label
end
#TkButton = Tk::Button unless Object.const_defined? :TkButton
-Tk.__set_toplevel_aliases__(:Tk, Tk::Button, :TkButton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Button, :TkButton)
+Tk.__set_loaded_toplevel_aliases__('tk/button.rb', :Tk, Tk::Button, :TkButton)
diff --git a/ext/tk/lib/tk/canvas.rb b/ext/tk/lib/tk/canvas.rb
index b05a619939..1e24c0be97 100644
--- a/ext/tk/lib/tk/canvas.rb
+++ b/ext/tk/lib/tk/canvas.rb
@@ -45,7 +45,7 @@ class Tk::Canvas<TkWindow
TkCommandNames = ['canvas'.freeze].freeze
WidgetClassName = 'Canvas'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __destroy_hook__
TkcItem::CItemID_TBL.delete(@path)
@@ -265,6 +265,12 @@ class Tk::Canvas<TkWindow
self
end
+ def imove(tagOrId, idx, x, y)
+ tk_send_without_enc('imove', tagid(tagOrId), idx, x, y)
+ self
+ end
+ alias i_move imove
+
def index(tagOrId, idx)
number(tk_send_without_enc('index', tagid(tagOrId), idx))
end
@@ -523,11 +529,18 @@ class Tk::Canvas<TkWindow
self
end
- def move(tag, x, y)
- tk_send_without_enc('move', tagid(tag), x, y)
+ def move(tag, dx, dy)
+ tk_send_without_enc('move', tagid(tag), dx, dy)
self
end
+ def moveto(tag, x, y)
+ # Tcl/Tk 8.6 or later
+ tk_send_without_enc('moveto', tagid(tag), x, y)
+ self
+ end
+ alias move_to moveto
+
def postscript(keys)
tk_send("postscript", *hash_kv(keys))
end
@@ -541,6 +554,15 @@ class Tk::Canvas<TkWindow
self
end
+ def rchars(tag, first, last, str_or_coords)
+ # Tcl/Tk 8.6 or later
+ str_or_coords = str_or_coords.flatten if str_or_coords.kinad_of? Array
+ tk_send_without_enc('rchars', tagid(tag), first, last, str_or_coords)
+ self
+ end
+ alias replace_chars rchars
+ alias replace_coords rchars
+
def scale(tag, x, y, xs, ys)
tk_send_without_enc('scale', tagid(tag), x, y, xs, ys)
self
@@ -581,7 +603,8 @@ class Tk::Canvas<TkWindow
end
#TkCanvas = Tk::Canvas unless Object.const_defined? :TkCanvas
-Tk.__set_toplevel_aliases__(:Tk, Tk::Canvas, :TkCanvas)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Canvas, :TkCanvas)
+Tk.__set_loaded_toplevel_aliases__('tk/canvas.rb', :Tk, Tk::Canvas, :TkCanvas)
class TkcItem<TkObject
diff --git a/ext/tk/lib/tk/canvastag.rb b/ext/tk/lib/tk/canvastag.rb
index 4e57a159bf..495d92a9a8 100644
--- a/ext/tk/lib/tk/canvastag.rb
+++ b/ext/tk/lib/tk/canvastag.rb
@@ -60,6 +60,9 @@ module TkcTagAccess
@c.itembindinfo(@id, seq)
end
+ def cget_tkstring(option)
+ @c.itemcget_tkstring(@id, option)
+ end
def cget(option)
@c.itemcget(@id, option)
end
@@ -116,6 +119,13 @@ module TkcTagAccess
self
end
+ def imove(idx, x, y)
+ # Tcl/Tk 8.6 or later
+ @c.imove(@id, idx, x, y)
+ self
+ end
+ alias i_move imove
+
def index(idx)
@c.index(@id, idx)
end
@@ -135,6 +145,13 @@ module TkcTagAccess
self
end
+ def moveto(x, y)
+ # Tcl/Tk 8.6 or later
+ @c.moveto(@id, x, y)
+ self
+ end
+ alias move_to moveto
+
def raise(abovethis=None)
@c.raise(@id, abovethis)
self
@@ -145,6 +162,14 @@ module TkcTagAccess
self
end
+ def rchars(first, last, str_or_coords)
+ # Tcl/Tk 8.6 or later
+ @c.rchars(@id, first, last, str_or_coords)
+ self
+ end
+ alias replace_chars rchars
+ alias replace_coords rchars
+
def select_adjust(index)
@c.select('adjust', @id, index)
self
@@ -203,7 +228,7 @@ class TkcTag<TkObject
CTagID_TBL = TkCore::INTERP.create_table
- (Tk_CanvasTag_ID = ['ctag'.freeze, '00000'.taint]).instance_eval{
+ (Tk_CanvasTag_ID = ['ctag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -389,7 +414,7 @@ class TkcTagCurrent<TkcTagString
end
class TkcGroup<TkcTag
- (Tk_cGroup_ID = ['tkcg'.freeze, '00000'.taint]).instance_eval{
+ (Tk_cGroup_ID = ['tkcg'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/checkbutton.rb b/ext/tk/lib/tk/checkbutton.rb
index c1c4905c5e..b7449541c5 100644
--- a/ext/tk/lib/tk/checkbutton.rb
+++ b/ext/tk/lib/tk/checkbutton.rb
@@ -7,7 +7,7 @@ require 'tk/radiobutton'
class Tk::CheckButton<Tk::RadioButton
TkCommandNames = ['checkbutton'.freeze].freeze
WidgetClassName = 'Checkbutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('checkbutton', @path, *hash_kv(keys, true))
@@ -26,5 +26,7 @@ end
Tk::Checkbutton = Tk::CheckButton
#TkCheckButton = Tk::CheckButton unless Object.const_defined? :TkCheckButton
#TkCheckbutton = Tk::Checkbutton unless Object.const_defined? :TkCheckbutton
-Tk.__set_toplevel_aliases__(:Tk, Tk::CheckButton,
- :TkCheckButton, :TkCheckbutton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::CheckButton,
+# :TkCheckButton, :TkCheckbutton)
+Tk.__set_loaded_toplevel_aliases__('tk/checkbutton.rb', :Tk, Tk::CheckButton,
+ :TkCheckButton, :TkCheckbutton)
diff --git a/ext/tk/lib/tk/composite.rb b/ext/tk/lib/tk/composite.rb
index 9a4aafda18..e267c7a22b 100644
--- a/ext/tk/lib/tk/composite.rb
+++ b/ext/tk/lib/tk/composite.rb
@@ -145,16 +145,34 @@ module TkComposite
str.chop << ' @epath=' << @epath.inspect << '>'
end
+ def _get_opt_method_list(arg)
+ m_set, m_cget, m_info = arg
+ m_set = m_set.to_s
+ m_cget = m_set if !m_cget && self.method(m_set).arity == -1
+ m_cget = m_cget.to_s if m_cget
+ m_info = m_info.to_s if m_info
+ [m_set, m_cget, m_info]
+ end
+ private :_get_opt_method_list
+
def option_methods(*opts)
- opts.each{|m_set, m_cget, m_info|
- m_set = m_set.to_s
- m_cget = m_set if !m_cget && self.method(m_set).arity == -1
- m_cget = m_cget.to_s if m_cget
- m_info = m_info.to_s if m_info
- @option_methods[m_set] = {
- :set => m_set, :cget => m_cget, :info => m_info
+ if opts.size == 1 && opts[0].kind_of?(Hash)
+ # {name => [m_set, m_cget, m_info], name => method} style
+ opts[0].each{|name, arg|
+ m_set, m_cget, m_info = _get_opt_method_list(arg)
+ @option_methods[name.to_s] = {
+ :set => m_set, :cget => m_cget, :info => m_info
+ }
}
- }
+ else
+ # [m_set, m_cget, m_info] or method style
+ opts.each{|arg|
+ m_set, m_cget, m_info = _get_opt_method_list(arg)
+ @option_methods[m_set] = {
+ :set => m_set, :cget => m_cget, :info => m_info
+ }
+ }
+ end
end
def delegate_alias(alias_opt, option, *wins)
@@ -215,6 +233,14 @@ module TkComposite
end
private :__cget_delegates
+ def cget_tkstring(slot)
+ if (ret = __cget_delegates(slot)) == None
+ super(slot)
+ else
+ _get_eval_string(ret)
+ end
+ end
+
def cget(slot)
if (ret = __cget_delegates(slot)) == None
super(slot)
diff --git a/ext/tk/lib/tk/entry.rb b/ext/tk/lib/tk/entry.rb
index 8ce8def1e7..d4aa03f2b6 100644
--- a/ext/tk/lib/tk/entry.rb
+++ b/ext/tk/lib/tk/entry.rb
@@ -13,7 +13,7 @@ class Tk::Entry<Tk::Label
TkCommandNames = ['entry'.freeze].freeze
WidgetClassName = 'Entry'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# super(__conv_vcmd_on_hash_kv(keys))
@@ -116,4 +116,5 @@ class Tk::Entry<Tk::Label
end
#TkEntry = Tk::Entry unless Object.const_defined? :TkEntry
-Tk.__set_toplevel_aliases__(:Tk, Tk::Entry, :TkEntry)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Entry, :TkEntry)
+Tk.__set_loaded_toplevel_aliases__('tk/entry.rb', :Tk, Tk::Entry, :TkEntry)
diff --git a/ext/tk/lib/tk/event.rb b/ext/tk/lib/tk/event.rb
index d07b3b5a85..bf4e122322 100644
--- a/ext/tk/lib/tk/event.rb
+++ b/ext/tk/lib/tk/event.rb
@@ -8,7 +8,7 @@ end
########################
require 'tkutil'
-require 'tk'
+require 'tk' unless Object.const_defined? :TkComm
########################
@@ -482,6 +482,26 @@ module TkEvent
end
})
end
+ elsif cmd.respond_to?(:arity) && cmd.arity == 0 # args.size == 0
+ args = ''
+ if cmd.kind_of?(String)
+ id = cmd
+ elsif cmd.kind_of?(TkCallbackEntry)
+ id = install_cmd(cmd)
+ else
+ id = install_cmd(proc{
+ begin
+ TkUtil.eval_cmd(cmd)
+ rescue Exception=>e
+ if TkCore::INTERP.kind_of?(TclTkIp)
+ fail e
+ else
+ # MultiTkIp
+ fail Exception, "#{e.class}: #{e.message.dup}"
+ end
+ end
+ })
+ end
else
keys, args = klass._get_all_subst_keys
diff --git a/ext/tk/lib/tk/font.rb b/ext/tk/lib/tk/font.rb
index da6482c122..03db850f96 100644
--- a/ext/tk/lib/tk/font.rb
+++ b/ext/tk/lib/tk/font.rb
@@ -11,7 +11,7 @@ class TkFont
TkCommandNames = ['font'.freeze].freeze
- (Tk_FontID = ["@font".freeze, "00000".taint]).instance_eval{
+ (Tk_FontID = ["@font".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -211,7 +211,7 @@ class TkFont
end
end
def TkFont.actual_hash(fnt, option=nil)
- Hash[TkFont.actual_hash(fnt, option)]
+ Hash[TkFont.actual(fnt, option)]
end
def TkFont.actual_displayof(fnt, win, option=nil)
@@ -224,7 +224,7 @@ class TkFont
end
end
def TkFont.actual_hash_displayof(fnt, option=nil)
- Hash[TkFont.actual_hash_displayof(fnt, option)]
+ Hash[TkFont.actual_displayof(fnt, option)]
end
def TkFont.configure(fnt, slot, value=None)
@@ -2199,7 +2199,7 @@ module TkFont::CoreMethods
alias measure_core measure_core_tk4x
alias metrics_core metrics_core_tk4x
- when /^8\.[0-5]/
+ when /^8\.[0-9]/
alias actual_core actual_core_tk8x
alias configure_core configure_core_tk8x
alias configinfo_core configinfo_core_tk8x
@@ -2342,3 +2342,10 @@ if Tk::TCL_MAJOR_VERSION > 8 ||
'systemDetailSystemFont', 'systemDetailEmphasizedSystemFont'
]
end
+
+#######################################
+# autoload
+#######################################
+class TkFont
+ autoload :Chooser, 'tk/fontchooser'
+end
diff --git a/ext/tk/lib/tk/fontchooser.rb b/ext/tk/lib/tk/fontchooser.rb
new file mode 100644
index 0000000000..f9f816be59
--- /dev/null
+++ b/ext/tk/lib/tk/fontchooser.rb
@@ -0,0 +1,166 @@
+#
+# tk/fontchooser.rb -- "tk fontchooser" support (Tcl/Tk8.6 or later)
+#
+require 'tk'
+require 'tk/font'
+
+module TkFont::Chooser
+ extend TkCore
+end
+
+class << TkFont::Chooser
+ def method_missing(id, *args)
+ name = id.id2name
+ case args.length
+ when 1
+ if name[-1] == ?=
+ configure name[0..-2], args[0]
+ args[0]
+ else
+ configure name, args[0]
+ self
+ end
+ when 0
+ begin
+ cget(name)
+ rescue
+ super(id, *args)
+ end
+ else
+ super(id, *args)
+ end
+ end
+
+ def __conviginfo_value(key, val)
+ case key
+ when 'parent'
+ window(val)
+ when 'title'
+ val
+ when 'font'
+ if (lst = tk_split_simplelist(val)).size == 1
+ lst[0]
+ else
+ lst.map{|elem| num_or_str(elem)}
+ end
+ when 'command'
+ tk_tcl2ruby(val)
+ when 'visible'
+ bool(val)
+ else # unkown
+ val
+ end
+ end
+ private :__conviginfo_value
+
+ def configinfo(option=nil)
+ if !option && TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
+ lst = tk_split_simplelist(tk_call('tk', 'fontchooser', 'configure'))
+ ret = []
+ TkComm.slice_ary(lst, 2){|k, v|
+ k = k[1..-1]
+ ret << [k, __conviginfo_value(k, v)]
+ }
+ ret
+ else
+ current_configinfo(option)
+ end
+ end
+
+ def current_configinfo(option=nil)
+ if option
+ opt = option.to_s
+ fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.empty?
+ __conviginfo_value(option.to_s, tk_call('tk','fontchooser',
+ 'configure',"-#{opt}"))
+ else
+ lst = tk_split_simplelist(tk_call('tk', 'fontchooser', 'configure'))
+ ret = {}
+ TkComm.slice_ary(lst, 2){|k, v|
+ k = k[1..-1]
+ ret[k] = __conviginfo_value(k, v)
+ }
+ ret
+ end
+ end
+
+ def configure(option, value=None)
+ if option.kind_of? Hash
+ tk_call('tk', 'fontchooser', 'configure',
+ *hash_kv(_symbolkey2str(option)))
+ else
+ opt = option.to_s
+ fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.empty?
+ tk_call('tk', 'fontchooser', 'configure', "-#{opt}", value)
+ end
+ self
+ end
+
+ def configure_cmd(slot, value)
+ configure(slot, install_cmd(value))
+ end
+
+ def command(cmd=nil, &b)
+ if cmd
+ configure_cmd('command', cmd)
+ elsif b
+ configure_cmd('command', Proc.new(&b))
+ else
+ cget('command')
+ end
+ end
+
+ def cget(slot)
+ configinfo slot
+ end
+
+ def [](slot)
+ cget slot
+ end
+
+ def []=(slot, val)
+ configure slot, val
+ val
+ end
+
+ def show
+ tk_call('tk', 'fontchooser', 'show')
+ self
+ end
+
+ def hide
+ tk_call('tk', 'fontchooser', 'hide')
+ self
+ end
+
+ def toggle
+ cget(:visible) ? hide: show
+ self
+ end
+
+ def set_for(target, title="Font")
+ if target.kind_of? TkFont
+ configs = {
+ :font=>target.actual_hash,
+ :command=>proc{|fnt, *args|
+ target.configure(TkFont.actual_hash(fnt))
+ }
+ }
+ else
+ configs = {
+ :font=>target.cget_tkstring(:font),
+ :command=>proc{|fnt, *args|
+ target.font = TkFont.actual_hash_displayof(fnt, target)
+ }
+ }
+ end
+
+ configs[:title] = title if title
+ configure(configs)
+ target
+ end
+
+ def unset
+ configure(:command, nil)
+ end
+end
diff --git a/ext/tk/lib/tk/frame.rb b/ext/tk/lib/tk/frame.rb
index 263b160f29..5118939732 100644
--- a/ext/tk/lib/tk/frame.rb
+++ b/ext/tk/lib/tk/frame.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::Frame<TkWindow
TkCommandNames = ['frame'.freeze].freeze
WidgetClassName = 'Frame'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
################# old version
# def initialize(parent=nil, keys=nil)
@@ -128,4 +128,5 @@ class Tk::Frame<TkWindow
end
#TkFrame = Tk::Frame unless Object.const_defined? :TkFrame
-Tk.__set_toplevel_aliases__(:Tk, Tk::Frame, :TkFrame)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Frame, :TkFrame)
+Tk.__set_loaded_toplevel_aliases__('tk/frame.rb', :Tk, Tk::Frame, :TkFrame)
diff --git a/ext/tk/lib/tk/image.rb b/ext/tk/lib/tk/image.rb
index 09f173909d..79d9ce8d00 100644
--- a/ext/tk/lib/tk/image.rb
+++ b/ext/tk/lib/tk/image.rb
@@ -11,7 +11,7 @@ class TkImage<TkObject
Tk_IMGTBL = TkCore::INTERP.create_table
- (Tk_Image_ID = ['i'.freeze, '00000'.taint]).instance_eval{
+ (Tk_Image_ID = ['i'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/itemconfig.rb b/ext/tk/lib/tk/itemconfig.rb
index cd05d7ea53..14396048ba 100644
--- a/ext/tk/lib/tk/itemconfig.rb
+++ b/ext/tk/lib/tk/itemconfig.rb
@@ -162,6 +162,13 @@ module TkItemConfigMethod
################################################
+
+ def itemcget_tkstring(tagOrId, option)
+ opt = option.to_s
+ fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.length == 0
+ tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{opt}"))
+ end
+
def __itemcget_core(tagOrId, option)
orig_opt = option
option = option.to_s
diff --git a/ext/tk/lib/tk/label.rb b/ext/tk/lib/tk/label.rb
index 80b3d778f1..05e430e49b 100644
--- a/ext/tk/lib/tk/label.rb
+++ b/ext/tk/lib/tk/label.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::Label<TkWindow
TkCommandNames = ['label'.freeze].freeze
WidgetClassName = 'Label'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('label', @path, *hash_kv(keys, true))
@@ -18,4 +18,5 @@ class Tk::Label<TkWindow
end
#TkLabel = Tk::Label unless Object.const_defined? :TkLabel
-Tk.__set_toplevel_aliases__(:Tk, Tk::Label, :TkLabel)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Label, :TkLabel)
+Tk.__set_loaded_toplevel_aliases__('tk/label.rb', :Tk, Tk::Label, :TkLabel)
diff --git a/ext/tk/lib/tk/labelframe.rb b/ext/tk/lib/tk/labelframe.rb
index 995b5b7e72..6f679e55b5 100644
--- a/ext/tk/lib/tk/labelframe.rb
+++ b/ext/tk/lib/tk/labelframe.rb
@@ -7,7 +7,7 @@ require 'tk/frame'
class Tk::LabelFrame<Tk::Frame
TkCommandNames = ['labelframe'.freeze].freeze
WidgetClassName = 'Labelframe'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('labelframe', @path, *hash_kv(keys, true))
@@ -26,4 +26,6 @@ end
Tk::Labelframe = Tk::LabelFrame
#TkLabelFrame = Tk::LabelFrame unless Object.const_defined? :TkLabelFrame
#TkLabelframe = Tk::Labelframe unless Object.const_defined? :TkLabelframe
-Tk.__set_toplevel_aliases__(:Tk, Tk::LabelFrame, :TkLabelFrame, :TkLabelframe)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::LabelFrame, :TkLabelFrame, :TkLabelframe)
+Tk.__set_loaded_toplevel_aliases__('tk/labelframe.rb', :Tk, Tk::LabelFrame,
+ :TkLabelFrame, :TkLabelframe)
diff --git a/ext/tk/lib/tk/listbox.rb b/ext/tk/lib/tk/listbox.rb
index 4357fafc27..6742b2132c 100644
--- a/ext/tk/lib/tk/listbox.rb
+++ b/ext/tk/lib/tk/listbox.rb
@@ -21,7 +21,7 @@ class Tk::Listbox<TkTextWin
TkCommandNames = ['listbox'.freeze].freeze
WidgetClassName = 'Listbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
@@ -279,4 +279,6 @@ class Tk::Listbox<TkTextWin
end
#TkListbox = Tk::Listbox unless Object.const_defined? :TkListbox
-Tk.__set_toplevel_aliases__(:Tk, Tk::Listbox, :TkListbox)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Listbox, :TkListbox)
+Tk.__set_loaded_toplevel_aliases__('tk/listbox.rb', :Tk, Tk::Listbox,
+ :TkListbox)
diff --git a/ext/tk/lib/tk/macpkg.rb b/ext/tk/lib/tk/macpkg.rb
index 67b0a4bb60..3ca7953c13 100644
--- a/ext/tk/lib/tk/macpkg.rb
+++ b/ext/tk/lib/tk/macpkg.rb
@@ -23,7 +23,9 @@ end
module Tk::MacResource
end
#TkMacResource = Tk::MacResource
-Tk.__set_toplevel_aliases__(:Tk, Tk::MacResource, :TkMacResource)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::MacResource, :TkMacResource)
+Tk.__set_loaded_toplevel_aliases__('tk/macpkg.rb', :Tk, Tk::MacResource,
+ :TkMacResource)
module Tk::MacResource
extend Tk
diff --git a/ext/tk/lib/tk/menu.rb b/ext/tk/lib/tk/menu.rb
index 3e122e6987..bcd250026d 100644
--- a/ext/tk/lib/tk/menu.rb
+++ b/ext/tk/lib/tk/menu.rb
@@ -33,13 +33,14 @@ module TkMenuEntryConfig
end
private :__item_val2ruby_optkeys
+ alias entrycget_tkstring itemcget_tkstring
alias entrycget itemcget
alias entrycget_strict itemcget_strict
alias entryconfigure itemconfigure
alias entryconfiginfo itemconfiginfo
alias current_entryconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
@@ -50,7 +51,7 @@ class Tk::Menu<TkWindow
TkCommandNames = ['menu'.freeze].freeze
WidgetClassName = 'Menu'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
@@ -386,8 +387,32 @@ class Tk::Menu<TkWindow
end
#TkMenu = Tk::Menu unless Object.const_defined? :TkMenu
-Tk.__set_toplevel_aliases__(:Tk, Tk::Menu, :TkMenu)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Menu, :TkMenu)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::Menu, :TkMenu)
+
+
+module Tk::Menu::TkInternalFunction; end
+class << Tk::Menu::TkInternalFunction
+ # These methods calls internal functions of Tcl/Tk.
+ # So, They may not work on your Tcl/Tk.
+ def next_menu(menu, dir='next')
+ dir = dir.to_s
+ case dir
+ when 'next', 'forward', 'down'
+ dir = 'right'
+ when 'previous', 'backward', 'up'
+ dir = 'left'
+ end
+
+ Tk.tk_call('::tk::MenuNextMenu', menu, dir)
+ end
+ def next_entry(menu, delta)
+ # delta is increment value of entry index.
+ # For example, +1 denotes 'next entry' and -1 denotes 'previous entry'.
+ Tk.tk_call('::tk::MenuNextEntry', menu, delta)
+ end
+end
class Tk::MenuClone<Tk::Menu
=begin
@@ -446,7 +471,9 @@ end
Tk::CloneMenu = Tk::MenuClone
#TkMenuClone = Tk::MenuClone unless Object.const_defined? :TkMenuClone
#TkCloneMenu = Tk::CloneMenu unless Object.const_defined? :TkCloneMenu
-Tk.__set_toplevel_aliases__(:Tk, Tk::MenuClone, :TkMenuClone, :TkCloneMenu)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::MenuClone, :TkMenuClone, :TkCloneMenu)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::MenuClone,
+ :TkMenuClone, :TkCloneMenu)
module Tk::SystemMenu
def initialize(parent, keys=nil)
@@ -480,7 +507,9 @@ class Tk::SysMenu_Help<Tk::Menu
SYSMENU_NAME = 'help'
end
#TkSysMenu_Help = Tk::SysMenu_Help unless Object.const_defined? :TkSysMenu_Help
-Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Help, :TkSysMenu_Help)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Help, :TkSysMenu_Help)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::SysMenu_Help,
+ :TkSysMenu_Help)
class Tk::SysMenu_System<Tk::Menu
@@ -489,7 +518,9 @@ class Tk::SysMenu_System<Tk::Menu
SYSMENU_NAME = 'system'
end
#TkSysMenu_System = Tk::SysMenu_System unless Object.const_defined? :TkSysMenu_System
-Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_System, :TkSysMenu_System)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_System, :TkSysMenu_System)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::SysMenu_System,
+ :TkSysMenu_System)
class Tk::SysMenu_Apple<Tk::Menu
@@ -498,13 +529,15 @@ class Tk::SysMenu_Apple<Tk::Menu
SYSMENU_NAME = 'apple'
end
#TkSysMenu_Apple = Tk::SysMenu_Apple unless Object.const_defined? :TkSysMenu_Apple
-Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Apple, :TkSysMenu_Apple)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::SysMenu_Apple, :TkSysMenu_Apple)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::SysMenu_Apple,
+ :TkSysMenu_Apple)
class Tk::Menubutton<Tk::Label
TkCommandNames = ['menubutton'.freeze].freeze
WidgetClassName = 'Menubutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
@@ -541,7 +574,9 @@ end
Tk::MenuButton = Tk::Menubutton
#TkMenubutton = Tk::Menubutton unless Object.const_defined? :TkMenubutton
#TkMenuButton = Tk::MenuButton unless Object.const_defined? :TkMenuButton
-Tk.__set_toplevel_aliases__(:Tk, Tk::Menubutton, :TkMenubutton, :TkMenuButton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Menubutton, :TkMenubutton, :TkMenuButton)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::Menubutton,
+ :TkMenubutton, :TkMenuButton)
class Tk::OptionMenubutton<Tk::Menubutton
@@ -677,5 +712,7 @@ end
Tk::OptionMenuButton = Tk::OptionMenubutton
#TkOptionMenubutton = Tk::OptionMenubutton unless Object.const_defined? :TkOptionMenubutton
#TkOptionMenuButton = Tk::OptionMenuButton unless Object.const_defined? :TkOptionMenuButton
-Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton,
- :TkOptionMenubutton, :TkOptionMenuButton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton,
+# :TkOptionMenubutton, :TkOptionMenuButton)
+Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::OptionMenubutton,
+ :TkOptionMenubutton, :TkOptionMenuButton)
diff --git a/ext/tk/lib/tk/menubar.rb b/ext/tk/lib/tk/menubar.rb
index ac537cb4ec..9d5571c470 100644
--- a/ext/tk/lib/tk/menubar.rb
+++ b/ext/tk/lib/tk/menubar.rb
@@ -93,24 +93,30 @@ class TkMenubar<Tk::Frame
include TkComposite
include TkMenuSpec
- def initialize(parent = nil, spec = nil, options = nil)
+ def initialize(parent = nil, spec = nil, options = {})
if parent.kind_of? Hash
- options = _symbolkey2str(parent)
- spec = options.delete('spec')
- super(options)
- else
- super(parent, options)
+ options = parent
+ parent = nil
+ spec = (options.has_key?('spec'))? options.delete('spec'): nil
end
+ _symbolkey2str(options)
+ menuspec_opt = {}
+ TkMenuSpec::MENUSPEC_OPTKEYS.each{|key|
+ menuspec_opt[key] = options.delete(key) if options.has_key?(key)
+ }
+
+ super(parent, options)
+
@menus = []
- spec.each{|info| add_menu(info)} if spec
+ spec.each{|info| add_menu(info, menuspec_opt)} if spec
options.each{|key, value| configure(key, value)} if options
end
- def add_menu(menu_info)
- mbtn, menu = _create_menubutton(@frame, menu_info)
+ def add_menu(menu_info, menuspec_opt={})
+ mbtn, menu = _create_menubutton(@frame, menu_info, menuspec_opt)
submenus = _get_cascade_menus(menu).flatten
diff --git a/ext/tk/lib/tk/menuspec.rb b/ext/tk/lib/tk/menuspec.rb
index 3f38ab5140..d7521555cd 100644
--- a/ext/tk/lib/tk/menuspec.rb
+++ b/ext/tk/lib/tk/menuspec.rb
@@ -7,9 +7,12 @@
# This file can be distributed under the terms of the Ruby.
#
# The format of the menu_spec is:
-# [ menu_info, menu_info, ... ]
+# [ menubutton_info, menubutton_info, ... ]
#
-# And the format of the menu_info is:
+# The format of the menubutton_info is:
+# [ menubutton_info, entry_info, entry_info, ... ]
+#
+# And each format of *_info is:
# [
# [text, underline, configs], # menu button/entry (*1)
# [label, command, underline, accelerator, configs], # command entry
@@ -22,12 +25,24 @@
# ...
# ]
#
+# A menu_info is an array of menu entries:
+# [ entry_info, entry_info, ... ]
+#
+#
# underline, accelerator, and configs are optional pearameters.
# Hashes are OK instead of Arrays. Then the entry type ('command',
# 'checkbutton', 'radiobutton' or 'cascade') is given by 'type' key
# (e.g. :type=>'cascade'). When type is 'cascade', an array of menu_info
# is acceptable for 'menu' key (then, create sub-menu).
#
+# If the value of underline is true instead of an integer,
+# check whether the text/label string contains a '&' character.
+# When includes, the first '&' is removed and its following character is
+# converted the corresponding 'underline' option (first '&' is removed).
+# Else if the value of underline is a String or a Regexp,
+# use the result of label.index(underline) as the index of underline
+# (don't remove matched substring).
+#
# NOTE: (*1)
# If you want to make special menus (*.help for UNIX, *.system for Win,
# and *.apple for Mac), append 'menu_name'=>name (name is 'help' for UNIX,
@@ -39,6 +54,10 @@
# to the configs of the cascade entry.
module TkMenuSpec
+ extend TkMenuSpec
+
+ MENUSPEC_OPTKEYS = [ 'layout_proc' ]
+
def _create_menu(parent, menu_info, menu_name = nil,
tearoff = false, default_opts = nil)
if tearoff.kind_of?(Hash)
@@ -59,6 +78,7 @@ module TkMenuSpec
end
tearoff = orig_opts.delete('tearoff') if orig_opts.key?('tearoff')
+ tearoff = false unless tearoff # nil --> false
if menu_name
#menu = Tk::Menu.new(parent, :widgetname=>menu_name, :tearoff=>tearoff)
@@ -84,6 +104,23 @@ module TkMenuSpec
tearoff, menu_opts)
options['menu'] = submenu
end
+ case options['underline']
+ when String, Regexp
+ if options['label'] &&
+ (idx = options['label'].index(options['underline']))
+ options['underline'] = idx
+ else
+ options['underline'] = -1
+ end
+ when true
+ if options['label'] && (idx = options['label'].index('&'))
+ options['label'] = options['label'].dup
+ options['label'][idx] = ''
+ options['underline'] = idx
+ else
+ options['underline'] = -1
+ end
+ end
menu.add(item_type, options)
elsif item_info.kind_of?(Array)
@@ -138,6 +175,25 @@ module TkMenuSpec
end
options.update(opts)
end
+
+ case options['underline']
+ when String, Regexp
+ if options['label'] &&
+ (idx = options['label'].index(options['underline']))
+ options['underline'] = idx
+ else
+ options['underline'] = -1
+ end
+ when true
+ if options['label'] && (idx = options['label'].index('&'))
+ options['label'] = options['label'].dup
+ options['label'][idx] = ''
+ options['underline'] = idx
+ else
+ options['underline'] = -1
+ end
+ end
+
menu.add(item_type, options)
elsif /^-+$/ =~ item_info
@@ -177,7 +233,7 @@ module TkMenuSpec
end
private :_create_menu_for_menubar
- def _create_menubutton(parent, menu_info, tearoff=false, default_opts = nil)
+ def _create_menubutton(parent, menu_info, tearoff=false, default_opts = {})
btn_info = menu_info[0]
if tearoff.kind_of?(Hash)
@@ -186,14 +242,49 @@ module TkMenuSpec
end
if default_opts.kind_of?(Hash)
- keys = _symbolkey2str(default_opts)
- else
- keys = {}
+ default_opts = _symbolkey2str(default_opts)
+
+ if default_opts.has_key?('layout_proc')
+ layout_proc = default_opts.delete('layout_proc')
+ end
+
+ _vertical_mbar_bind_proc = proc{|m, dir|
+ Tk::Menu::TkInternalFunction.next_menu(m, dir) rescue nil
+ # ignore error when the internal function doesn't exist
+ }
+
+ case layout_proc
+ when :vertical, 'vertical', :vertical_left, 'vertical_left'
+ layout_proc = proc{|_parent, _mbtn|
+ _mbtn.direction :right
+ _mbtn.pack(:side=>:top, :fill=>:x)
+
+ menu = _mbtn.menu
+ menu.bind('Tab', _vertical_mbar_bind_proc, :widget, 'forward')
+ menu.bind('Alt-Tab', _vertical_mbar_bind_proc, :widget, 'backward')
+ }
+ when :vertical_right, 'vertical_right'
+ layout_proc = proc{|_parent, _mbtn|
+ _mbtn.direction :left
+ _mbtn.pack(:side=>:top, :fill=>:x)
+
+ menu = _mbtn.menu
+ menu.bind('Tab', _vertical_mbar_bind_proc, :widget, 'forward')
+ menu.bind('Alt-Tab', _vertical_mbar_bind_proc, :widget, 'backward')
+ }
+ when :horizontal, 'horizontal'
+ layout_proc = proc{|_parent, _mbtn| _mbtn.pack(:side=>:left)}
+ else
+ # do nothing
+ end
end
+ keys = default_opts.dup
+
tearoff = keys.delete('tearoff') if keys.key?('tearoff')
+ tearoff = false unless tearoff # nil --> false
- if _use_menubar?(parent)
+ if _use_menubar?(parent) && ! layout_proc
# menubar by menu entries
mbar = _create_menu_for_menubar(parent)
@@ -202,14 +293,52 @@ module TkMenuSpec
if btn_info.kind_of?(Hash)
keys.update(_symbolkey2str(btn_info))
menu_name = keys.delete('menu_name')
- keys['label'] = keys.delete('text') if keys.key?('text')
+ keys['label'] = keys.delete('text') || ''
+
+ case keys['underline']
+ when String, Regexp
+ if idx = keys['label'].index(keys['underline'])
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ when true
+ if idx = keys['label'].index('&')
+ keys['label'] = keys['label'].dup
+ keys['label'][idx] = ''
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ end
+
elsif btn_info.kind_of?(Array)
keys['label'] = btn_info[0] if btn_info[0]
- keys['underline'] = btn_info[1] if btn_info[1]
+
+ case btn_info[1]
+ when Integer
+ keys['underline'] = btn_info[1]
+ when String, Regexp
+ if idx = keys['label'].index(btn_info[1])
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ when true
+ if idx = keys['label'].index('&')
+ keys['label'] = keys['label'].dup
+ keys['label'][idx] = ''
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ end
+
if btn_info[2]&&btn_info[2].kind_of?(Hash)
keys.update(_symbolkey2str(btn_info[2]))
menu_name = keys.delete('menu_name')
end
+
else
keys = {:label=>btn_info}
end
@@ -234,9 +363,42 @@ module TkMenuSpec
if btn_info.kind_of?(Hash)
keys.update(_symbolkey2str(btn_info))
menu_name = keys.delete('menu_name')
- keys['text'] = keys.delete('label') if keys.key?('label')
+ keys['text'] = keys.delete('label') || ''
+ case keys['underline']
+ when String, Regexp
+ if idx = keys['text'].index(keys['underline'])
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ when true
+ if idx = keys['text'].index('&')
+ keys['text'] = keys['text'].dup
+ keys['text'][idx] = ''
+ keys['underline'] = idx
+ else
+ keys['underline'] = -1
+ end
+ end
mbtn.configure(keys)
+
elsif btn_info.kind_of?(Array)
+ case btn_info[1]
+ when String, Regexp
+ if btn_info[0] && (idx = btn_info[0].index(btn_info[1]))
+ btn_info[1] = idx
+ else
+ btn_info[1] = -1
+ end
+ when true
+ if btn_info[0] && (idx = btn_info[0].index('&'))
+ btn_info[0] = btn_info[0].dup
+ btn_info[0][idx] = ''
+ btn_info[1] = idx
+ else
+ btn_info[1] = -1
+ end
+ end
mbtn.configure('text', btn_info[0]) if btn_info[0]
mbtn.configure('underline', btn_info[1]) if btn_info[1]
# mbtn.configure('accelerator', btn_info[2]) if btn_info[2]
@@ -245,22 +407,41 @@ module TkMenuSpec
menu_name = keys.delete('menu_name')
mbtn.configure(keys)
end
+
else
mbtn.configure('text', btn_info)
end
- mbtn.pack('side' => 'left')
-
menu = _create_menu(mbtn, menu_info[1..-1], menu_name,
tearoff, default_opts)
-
mbtn.menu(menu)
+ if layout_proc.kind_of?(Proc) || layout_proc.kind_of?(Method)
+ # e.g. make a vertical menubar
+ # :layout_proc => proc{|parent, btn| btn.pack(:side=>:top, :fill=>:x)}
+ layout_proc.call(parent, mbtn)
+ else
+ mbtn.pack('side' => 'left')
+ end
+
[mbtn, menu]
end
end
private :_create_menubutton
+ def _create_menubar(parent, menu_spec, tearoff = false, opts = nil)
+ if tearoff.kind_of?(Hash)
+ opts = tearoff
+ tearoff = false
+ end
+ tearoff = false unless tearoff # nil --> false
+ menu_spec.each{|menu_info|
+ _create_menubutton(parent, menu_info, tearoff, opts)
+ }
+ parent
+ end
+ private :_create_menubar
+
def _get_cascade_menus(menu)
menus = []
(0..(menu.index('last'))).each{|idx|
diff --git a/ext/tk/lib/tk/message.rb b/ext/tk/lib/tk/message.rb
index 946b68c704..5f73b3066f 100644
--- a/ext/tk/lib/tk/message.rb
+++ b/ext/tk/lib/tk/message.rb
@@ -7,7 +7,7 @@ require 'tk/label'
class Tk::Message<Tk::Label
TkCommandNames = ['message'.freeze].freeze
WidgetClassName = 'Message'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('message', @path, *hash_kv(keys, true))
@@ -19,4 +19,6 @@ class Tk::Message<Tk::Label
end
#TkMessage = Tk::Message unless Object.const_defined? :TkMessage
-Tk.__set_toplevel_aliases__(:Tk, Tk::Message, :TkMessage)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Message, :TkMessage)
+Tk.__set_loaded_toplevel_aliases__('tk/message.rb', :Tk, Tk::Message,
+ :TkMessage)
diff --git a/ext/tk/lib/tk/msgcat.rb b/ext/tk/lib/tk/msgcat.rb
index f90dbc5efa..4abbcad85e 100644
--- a/ext/tk/lib/tk/msgcat.rb
+++ b/ext/tk/lib/tk/msgcat.rb
@@ -36,7 +36,7 @@ class TkMsgCatalog < TkObject
MSGCAT_EXT = '.msg'
- UNKNOWN_CBTBL = Hash.new{|hash,key| hash[key] = {}}.taint
+ UNKNOWN_CBTBL = TkUtil.untrust(Hash.new{|hash,key| hash[key] = {}})
TkCore::INTERP.add_tk_procs('::msgcat::mcunknown', 'args', <<-'EOL')
if {[set st [catch {eval {ruby_cmd TkMsgCatalog callback} [namespace current] $args} ret]] != 0} {
diff --git a/ext/tk/lib/tk/namespace.rb b/ext/tk/lib/tk/namespace.rb
index dfb162cda8..4af891995e 100644
--- a/ext/tk/lib/tk/namespace.rb
+++ b/ext/tk/lib/tk/namespace.rb
@@ -13,7 +13,7 @@ class TkNamespace < TkObject
Tk_Namespace_ID_TBL = TkCore::INTERP.create_table
- (Tk_Namespace_ID = ["ns".freeze, "00000".taint]).instance_eval{
+ (Tk_Namespace_ID = ["ns".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/optiondb.rb b/ext/tk/lib/tk/optiondb.rb
index 9d366c13ea..0f3be30ff7 100644
--- a/ext/tk/lib/tk/optiondb.rb
+++ b/ext/tk/lib/tk/optiondb.rb
@@ -8,7 +8,7 @@ module TkOptionDB
extend Tk
TkCommandNames = ['option'.freeze].freeze
- (CmdClassID = ['CMD_CLASS'.freeze, '00000'.taint]).instance_eval{
+ (CmdClassID = ['CMD_CLASS'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/panedwindow.rb b/ext/tk/lib/tk/panedwindow.rb
index 4e70ede9bf..04407802ea 100644
--- a/ext/tk/lib/tk/panedwindow.rb
+++ b/ext/tk/lib/tk/panedwindow.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::PanedWindow<TkWindow
TkCommandNames = ['panedwindow'.freeze].freeze
WidgetClassName = 'Panedwindow'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('panedwindow', @path, *hash_kv(keys, true))
@@ -254,5 +254,7 @@ end
Tk::Panedwindow = Tk::PanedWindow
#TkPanedWindow = Tk::PanedWindow unless Object.const_defined? :TkPanedWindow
#TkPanedwindow = Tk::Panedwindow unless Object.const_defined? :TkPanedwindow
-Tk.__set_toplevel_aliases__(:Tk, Tk::PanedWindow,
- :TkPanedWindow, :TkPanedwindow)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::PanedWindow,
+# :TkPanedWindow, :TkPanedwindow)
+Tk.__set_loaded_toplevel_aliases__('tk/panedwindow.rb', :Tk, Tk::PanedWindow,
+ :TkPanedWindow, :TkPanedwindow)
diff --git a/ext/tk/lib/tk/radiobutton.rb b/ext/tk/lib/tk/radiobutton.rb
index 1d75dc220d..627df6d9cf 100644
--- a/ext/tk/lib/tk/radiobutton.rb
+++ b/ext/tk/lib/tk/radiobutton.rb
@@ -7,7 +7,7 @@ require 'tk/button'
class Tk::RadioButton<Tk::Button
TkCommandNames = ['radiobutton'.freeze].freeze
WidgetClassName = 'Radiobutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#def create_self(keys)
# if keys and keys != None
# tk_call_without_enc('radiobutton', @path, *hash_kv(keys, true))
@@ -67,5 +67,7 @@ end
Tk::Radiobutton = Tk::RadioButton
#TkRadioButton = Tk::RadioButton unless Object.const_defined? :TkRadioButton
#TkRadiobutton = Tk::Radiobutton unless Object.const_defined? :TkRadiobutton
-Tk.__set_toplevel_aliases__(:Tk, Tk::RadioButton,
- :TkRadioButton, :TkRadiobutton)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::RadioButton,
+# :TkRadioButton, :TkRadiobutton)
+Tk.__set_loaded_toplevel_aliases__('tk/radiobutton.rb', :Tk, Tk::RadioButton,
+ :TkRadioButton, :TkRadiobutton)
diff --git a/ext/tk/lib/tk/root.rb b/ext/tk/lib/tk/root.rb
index ca6260927a..b4f0bd107f 100644
--- a/ext/tk/lib/tk/root.rb
+++ b/ext/tk/lib/tk/root.rb
@@ -52,7 +52,7 @@ class Tk::Root<TkWindow
end
WidgetClassName = 'Tk'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.to_eval
# self::WidgetClassName
diff --git a/ext/tk/lib/tk/scale.rb b/ext/tk/lib/tk/scale.rb
index 58283216b8..0bdcead7f2 100644
--- a/ext/tk/lib/tk/scale.rb
+++ b/ext/tk/lib/tk/scale.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::Scale<TkWindow
TkCommandNames = ['scale'.freeze].freeze
WidgetClassName = 'Scale'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
@@ -108,4 +108,5 @@ class Tk::Scale<TkWindow
end
#TkScale = Tk::Scale unless Object.const_defined? :TkScale
-Tk.__set_toplevel_aliases__(:Tk, Tk::Scale, :TkScale)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Scale, :TkScale)
+Tk.__set_loaded_toplevel_aliases__('tk/scale.rb', :Tk, Tk::Scale, :TkScale)
diff --git a/ext/tk/lib/tk/scrollbar.rb b/ext/tk/lib/tk/scrollbar.rb
index decc4205c4..c0ac201acb 100644
--- a/ext/tk/lib/tk/scrollbar.rb
+++ b/ext/tk/lib/tk/scrollbar.rb
@@ -6,7 +6,7 @@ require 'tk'
class Tk::Scrollbar<TkWindow
TkCommandNames = ['scrollbar'.freeze].freeze
WidgetClassName = 'Scrollbar'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
@assigned = []
@@ -148,7 +148,9 @@ class Tk::Scrollbar<TkWindow
end
#TkScrollbar = Tk::Scrollbar unless Object.const_defined? :TkScrollbar
-Tk.__set_toplevel_aliases__(:Tk, Tk::Scrollbar, :TkScrollbar)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Scrollbar, :TkScrollbar)
+Tk.__set_loaded_toplevel_aliases__('tk/scrollbar.rb', :Tk, Tk::Scrollbar,
+ :TkScrollbar)
class Tk::XScrollbar<Tk::Scrollbar
@@ -161,7 +163,9 @@ class Tk::XScrollbar<Tk::Scrollbar
end
#TkXScrollbar = Tk::XScrollbar unless Object.const_defined? :TkXScrollbar
-Tk.__set_toplevel_aliases__(:Tk, Tk::XScrollbar, :TkXScrollbar)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::XScrollbar, :TkXScrollbar)
+Tk.__set_loaded_toplevel_aliases__('tk/scrollbar.rb', :Tk, Tk::XScrollbar,
+ :TkXScrollbar)
class Tk::YScrollbar<Tk::Scrollbar
@@ -174,4 +178,6 @@ class Tk::YScrollbar<Tk::Scrollbar
end
#TkYScrollbar = Tk::YScrollbar unless Object.const_defined? :TkYScrollbar
-Tk.__set_toplevel_aliases__(:Tk, Tk::YScrollbar, :TkYScrollbar)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::YScrollbar, :TkYScrollbar)
+Tk.__set_loaded_toplevel_aliases__('tk/scrollbar.rb', :Tk, Tk::YScrollbar,
+ :TkYScrollbar)
diff --git a/ext/tk/lib/tk/spinbox.rb b/ext/tk/lib/tk/spinbox.rb
index 2fcc916237..f2917d60ca 100644
--- a/ext/tk/lib/tk/spinbox.rb
+++ b/ext/tk/lib/tk/spinbox.rb
@@ -8,7 +8,7 @@ require 'tk/entry'
class Tk::Spinbox<Tk::Entry
TkCommandNames = ['spinbox'.freeze].freeze
WidgetClassName = 'Spinbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
class SpinCommand < TkValidateCommand
class ValidateArgs < TkUtil::CallbackSubst
@@ -100,13 +100,36 @@ class Tk::Spinbox<Tk::Entry
tk_send_without_enc('identify', x, y)
end
+ def invoke(elem)
+ tk_send_without_enc('invoke', elem)
+ self
+ end
+
def spinup
- tk_send_without_enc('invoke', 'spinup')
+ begin
+ tk_send_without_enc('invoke', 'buttonup')
+ rescue RuntimeError => e
+ # old version of element?
+ begin
+ tk_send_without_enc('invoke', 'spinup')
+ rescue
+ fail e
+ end
+ end
self
end
def spindown
- tk_send_without_enc('invoke', 'spindown')
+ begin
+ tk_send_without_enc('invoke', 'buttondown')
+ rescue RuntimeError => e
+ # old version of element?
+ begin
+ tk_send_without_enc('invoke', 'spinup')
+ rescue
+ fail e
+ end
+ end
self
end
@@ -116,4 +139,6 @@ class Tk::Spinbox<Tk::Entry
end
#TkSpinbox = Tk::Spinbox unless Object.const_defined? :TkSpinbox
-Tk.__set_toplevel_aliases__(:Tk, Tk::Spinbox, :TkSpinbox)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Spinbox, :TkSpinbox)
+Tk.__set_loaded_toplevel_aliases__('tk/spinbox.rb', :Tk, Tk::Spinbox,
+ :TkSpinbox)
diff --git a/ext/tk/lib/tk/text.rb b/ext/tk/lib/tk/text.rb
index 42b8be475e..bc2aa0a293 100644
--- a/ext/tk/lib/tk/text.rb
+++ b/ext/tk/lib/tk/text.rb
@@ -29,6 +29,9 @@ module TkTextTagConfig
end
private :__item_pathname
+ def tag_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['tag', tagOrId], option)
+ end
def tag_cget(tagOrId, option)
itemcget(['tag', tagOrId], option)
end
@@ -45,6 +48,9 @@ module TkTextTagConfig
current_itemconfiginfo(['tag', tagOrId], slot)
end
+ def window_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['window', tagOrId], option)
+ end
def window_cget(tagOrId, option)
itemcget(['window', tagOrId], option)
end
@@ -61,7 +67,7 @@ module TkTextTagConfig
current_itemconfiginfo(['window', tagOrId], slot)
end
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
@@ -251,7 +257,7 @@ class Tk::Text<TkTextWin
TkCommandNames = ['text'.freeze].freeze
WidgetClassName = 'Text'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.new(*args, &block)
obj = super(*args){}
@@ -1570,7 +1576,8 @@ class Tk::Text<TkTextWin
end
#TkText = Tk::Text unless Object.const_defined? :TkText
-Tk.__set_toplevel_aliases__(:Tk, Tk::Text, :TkText)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Text, :TkText)
+Tk.__set_loaded_toplevel_aliases__('tk/text.rb', :Tk, Tk::Text, :TkText)
#######################################
@@ -1587,7 +1594,8 @@ class Tk::Text::Peer < Tk::Text
def create_self(keys)
if keys and keys != None
- tk_call_without_enc(@src_text.path, 'peer', 'create', @path)
+ tk_call_without_enc(@src_text.path, 'peer', 'create',
+ @path, *hash_kv(keys, true))
else
tk_call_without_enc(@src_text.path, 'peer', 'create', @path)
end
diff --git a/ext/tk/lib/tk/textmark.rb b/ext/tk/lib/tk/textmark.rb
index e9743475e0..d1888c5e54 100644
--- a/ext/tk/lib/tk/textmark.rb
+++ b/ext/tk/lib/tk/textmark.rb
@@ -9,7 +9,7 @@ class TkTextMark<TkObject
TMarkID_TBL = TkCore::INTERP.create_table
- (Tk_TextMark_ID = ['mark'.freeze, '00000'.taint]).instance_eval{
+ (Tk_TextMark_ID = ['mark'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/texttag.rb b/ext/tk/lib/tk/texttag.rb
index 7bd59bf8ee..96692014e4 100644
--- a/ext/tk/lib/tk/texttag.rb
+++ b/ext/tk/lib/tk/texttag.rb
@@ -11,7 +11,7 @@ class TkTextTag<TkObject
TTagID_TBL = TkCore::INTERP.create_table
- (Tk_TextTag_ID = ['tag'.freeze, '00000'.taint]).instance_eval{
+ (Tk_TextTag_ID = ['tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -129,6 +129,9 @@ class TkTextTag<TkObject
val
end
+ def cget_tkstring(key)
+ @t.tag_cget_tkstring @id, key
+ end
def cget(key)
@t.tag_cget @id, key
end
diff --git a/ext/tk/lib/tk/timer.rb b/ext/tk/lib/tk/timer.rb
index 686d4bd483..be2a8919e4 100644
--- a/ext/tk/lib/tk/timer.rb
+++ b/ext/tk/lib/tk/timer.rb
@@ -11,13 +11,13 @@ class TkTimer
TkCommandNames = ['after'.freeze].freeze
- (Tk_CBID = ['a'.freeze, '00000'.taint]).instance_eval{
+ (Tk_CBID = ['a'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
- Tk_CBTBL = {}.taint
+ Tk_CBTBL = TkUtil.untrust({})
TkCore::INTERP.add_tk_procs('rb_after', 'id', <<-'EOL')
if {[set st [catch {eval {ruby_cmd TkTimer callback} $id} ret]] != 0} {
diff --git a/ext/tk/lib/tk/toplevel.rb b/ext/tk/lib/tk/toplevel.rb
index 917264aef7..30ef009517 100644
--- a/ext/tk/lib/tk/toplevel.rb
+++ b/ext/tk/lib/tk/toplevel.rb
@@ -11,7 +11,7 @@ class Tk::Toplevel<TkWindow
TkCommandNames = ['toplevel'.freeze].freeze
WidgetClassName = 'Toplevel'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
################# old version
# def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
@@ -259,4 +259,6 @@ class Tk::Toplevel<TkWindow
end
#TkToplevel = Tk::Toplevel unless Object.const_defined? :TkToplevel
-Tk.__set_toplevel_aliases__(:Tk, Tk::Toplevel, :TkToplevel)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::Toplevel, :TkToplevel)
+Tk.__set_loaded_toplevel_aliases__('tk/toplevel.rb', :Tk, Tk::Toplevel,
+ :TkToplevel)
diff --git a/ext/tk/lib/tk/ttk_selector.rb b/ext/tk/lib/tk/ttk_selector.rb
index 7a0dd34038..522249e6a9 100644
--- a/ext/tk/lib/tk/ttk_selector.rb
+++ b/ext/tk/lib/tk/ttk_selector.rb
@@ -53,21 +53,43 @@ module Tk
:TkTreeview => 'tkextlib/tile/treeview',
}
- @TOPLEVEL_ALIAS_TABLE[:Tile] = @TOPLEVEL_ALIAS_TABLE[:Ttk]
+
+ # @TOPLEVEL_ALIAS_TABLE[:Tile] = @TOPLEVEL_ALIAS_TABLE[:Ttk]
+ Tk.__create_widget_set__(:Tile, :Ttk)
+
+ ############################################
+ # depend on the version of Tcl/Tk
+ major, minor, type, patchlevel = TclTkLib.get_version
+
+ # ttk::spinbox is supported on Tcl/Tk8.6b1 or later
+ if ([major,minor,type,patchlevel] <=>
+ [8,6,TclTkLib::RELEASE_TYPE::BETA,1]) >= 0
+ @TOPLEVEL_ALIAS_TABLE[:Ttk].update(
+ :TkSpinbox => 'tkextlib/tile/tspinbox'
+ )
+ end
################################################
# register some Ttk widgets as default
# (Ttk is a standard library on Tcl/Tk8.5+)
@TOPLEVEL_ALIAS_TABLE[:Ttk].each{|sym, file|
- unless Object.autoload?(sym) || Object.const_defined?(sym)
- Object.autoload(sym, file)
- end
+ #unless Tk::TOPLEVEL_ALIASES.autoload?(sym) || Tk::TOPLEVEL_ALIASES.const_defined?(sym)
+ # @TOPLEVEL_ALIAS_OWNER[sym] = :Ttk
+ # Tk::TOPLEVEL_ALIASES.autoload(sym, file)
+ #end
+ Tk.__regist_toplevel_aliases__(:Ttk, file, sym)
}
################################################
- @TOPLEVEL_ALIAS_SETUP_PROC[:Tile] =
- @TOPLEVEL_ALIAS_SETUP_PROC[:Ttk] = proc{|mod|
+ # @TOPLEVEL_ALIAS_SETUP_PROC[:Tile] =
+ # @TOPLEVEL_ALIAS_SETUP_PROC[:Ttk] = proc{|mod|
+ # unless Tk.autoload?(:Tile) || Tk.const_defined?(:Tile)
+ # Object.autoload :Ttk, 'tkextlib/tile'
+ # Tk.autoload :Tile, 'tkextlib/tile'
+ # end
+ # }
+ Tk.__toplevel_alias_setup_proc__(:Ttk, :Tile){|mod|
unless Tk.autoload?(:Tile) || Tk.const_defined?(:Tile)
Object.autoload :Ttk, 'tkextlib/tile'
Tk.autoload :Tile, 'tkextlib/tile'
diff --git a/ext/tk/lib/tk/variable.rb b/ext/tk/lib/tk/variable.rb
index bdd441705b..6fc2ffdf2f 100644
--- a/ext/tk/lib/tk/variable.rb
+++ b/ext/tk/lib/tk/variable.rb
@@ -16,7 +16,7 @@ class TkVariable
#TkVar_ID_TBL = {}
TkVar_CB_TBL = TkCore::INTERP.create_table
TkVar_ID_TBL = TkCore::INTERP.create_table
- (Tk_VARIABLE_ID = ["v".freeze, "00000".taint]).instance_eval{
+ (Tk_VARIABLE_ID = ["v".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -1239,6 +1239,14 @@ end
end
end
+ def ===(other)
+ if other.kind_of?(TkVariable)
+ self.id == other.id
+ else
+ super
+ end
+ end
+
def zero?
numeric.zero?
end
diff --git a/ext/tk/lib/tk/virtevent.rb b/ext/tk/lib/tk/virtevent.rb
index ba771da647..19c0dac380 100644
--- a/ext/tk/lib/tk/virtevent.rb
+++ b/ext/tk/lib/tk/virtevent.rb
@@ -9,7 +9,7 @@ class TkVirtualEvent<TkObject
TkCommandNames = ['event'.freeze].freeze
- (TkVirtualEventID = ["VirtEvent".freeze, "00000".taint]).instance_eval{
+ (TkVirtualEventID = ["VirtEvent".freeze, TkUtil.untrust("00000")]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tk/winpkg.rb b/ext/tk/lib/tk/winpkg.rb
index a131731560..80e0439ace 100644
--- a/ext/tk/lib/tk/winpkg.rb
+++ b/ext/tk/lib/tk/winpkg.rb
@@ -10,7 +10,8 @@ require 'tk'
module Tk::WinDDE
end
#TkWinDDE = Tk::WinDDE
-Tk.__set_toplevel_aliases__(:Tk, Tk::WinDDE, :TkWinDDE)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::WinDDE, :TkWinDDE)
+Tk.__set_loaded_toplevel_aliases__('tk/winpkg.rb', :Tk, Tk::WinDDE, :TkWinDDE)
module Tk::WinDDE
extend Tk
@@ -93,7 +94,9 @@ end
module Tk::WinRegistry
end
#TkWinRegistry = Tk::WinRegistry
-Tk.__set_toplevel_aliases__(:Tk, Tk::WinRegistry, :TkWinRegistry)
+#Tk.__set_toplevel_aliases__(:Tk, Tk::WinRegistry, :TkWinRegistry)
+Tk.__set_loaded_toplevel_aliases__('tk/winpkg.rb', :Tk, Tk::WinRegistry,
+ :TkWinRegistry)
module Tk::WinRegistry
extend Tk
diff --git a/ext/tk/lib/tkextlib/SUPPORT_STATUS b/ext/tk/lib/tkextlib/SUPPORT_STATUS
index cfbe274c86..6b31ababb3 100644
--- a/ext/tk/lib/tkextlib/SUPPORT_STATUS
+++ b/ext/tk/lib/tkextlib/SUPPORT_STATUS
@@ -55,18 +55,20 @@ script may give you some hints about that.
===< support with some examples (may be beta quality) >=======================
-Tcllib 1.8
-Tklib 0.4.1 http://sourceforge.net/projects/tcllib ==> tcllib
+Tcllib 1.11.1
+Tklib 0.5 http://sourceforge.net/projects/tcllib ==> tcllib
+ ( partial support; primary support target is Tklib)
IWidgets 4.0.2 http://sourceforge.net/projects/incrtcl ==> iwidgets
-BWidgets 1.7 http://sourceforge.net/projects/tcllib ==> bwidget
+BWidget 1.8 [ CVS/Hd(2009-07-02) ]
+ http://sourceforge.net/projects/tcllib ==> bwidget
-TkTable 2.9 http://sourceforge.net/projects/tktable ==> tktable
+TkTable 2.10 http://sourceforge.net/projects/tktable ==> tktable
* see also <http://www.korus.hu/~fery/ruby/tktable.rb>
written by Ferenc Engard (ferenc@engard.hu)
-vu 2.3.0 http://sourceforge.net/projects/tktable ==> vu
+Vu widgets 2.3.0 http://sourceforge.net/projects/tktable ==> vu
TkHTML 2.0 http://www.hwaci.com/sw/tkhtml/ ==> tkHTML
@@ -80,25 +82,25 @@ BLT 2.4z http://sourceforge.net/projects/blt
(http://raa.ruby-lang.org/)
==> blt
-TkTreeCtrl CVS/Hd(2005-12-02)
- http://sourceforge.net/projects/tktreectrl ==> treectrl
+TkTreeCtrl 2.2.9
+ http://tktreectrl.sourceforge.net/ ==> treectrl
-Tile 0.8.0/8.5.1
+Tile 0.8.3/8.6b1
http://sourceforge.net/projects/tktable ==> tile
===< support (may be alpha or beta quality) >=================================
-IncrTcl CVS/Hd(2005-02-14)
+IncrTcl CVS/Hd(2008-12-15)
http://sourceforge.net/projects/incrtcl ==> itcl, itk
-TclX CVS/Hd(2005-02-07)
+TclX CVS/Hd(2008-12-15)
http://sourceforge.net/projects/tclx
==> tclx (partial support; infox command and
XPG/3 message catalogs only)
-Trofs 0.4.3 http://math.nist.gov/~DPorter/tcltk/trofs/
+Trofs 0.4.4 http://math.nist.gov/~DPorter/tcltk/trofs/
diff --git a/ext/tk/lib/tkextlib/blt.rb b/ext/tk/lib/tkextlib/blt.rb
index 8d58c1f1bc..8b132e41a7 100644
--- a/ext/tk/lib/tkextlib/blt.rb
+++ b/ext/tk/lib/tkextlib/blt.rb
@@ -19,6 +19,8 @@ TkPackage.require('BLT')
module Tk
module BLT
TkComm::TkExtlibAutoloadModule.unshift(self)
+ # Require autoload-symbols which is a same name as widget classname.
+ # Those are used at TkComm._genobj_for_tkwidget method.
extend TkCore
diff --git a/ext/tk/lib/tkextlib/blt/barchart.rb b/ext/tk/lib/tkextlib/blt/barchart.rb
index 8e71c3f5e0..a86b91c959 100644
--- a/ext/tk/lib/tkextlib/blt/barchart.rb
+++ b/ext/tk/lib/tkextlib/blt/barchart.rb
@@ -11,7 +11,7 @@ module Tk::BLT
class Barchart < TkWindow
TkCommandNames = ['::blt::barchart'.freeze].freeze
WidgetClassName = 'Barchart'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
include PlotComponent
include GraphCommand
@@ -33,7 +33,7 @@ module Tk::BLT
private :__tkvariable_optkeys
=begin
- BarElement_ID = ['blt_barchart_bar'.freeze, '00000'.taint].freeze
+ BarElement_ID = ['blt_barchart_bar'.freeze, TkUtil.untrust('00000')].freeze
def bar(elem=nil, keys={})
if elem.kind_of?(Hash)
diff --git a/ext/tk/lib/tkextlib/blt/bitmap.rb b/ext/tk/lib/tkextlib/blt/bitmap.rb
index 23c6d2d064..3254b63116 100644
--- a/ext/tk/lib/tkextlib/blt/bitmap.rb
+++ b/ext/tk/lib/tkextlib/blt/bitmap.rb
@@ -14,7 +14,7 @@ module Tk::BLT
BITMAP_ID_TBL = TkCore::INTERP.create_table
- (BITMAP_ID = ['blt_bitmap_id'.freeze, '00000'.taint]).instance_eval{
+ (BITMAP_ID = ['blt_bitmap_id'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tkextlib/blt/busy.rb b/ext/tk/lib/tkextlib/blt/busy.rb
index 2f807fcd9c..b5287fb5b7 100644
--- a/ext/tk/lib/tkextlib/blt/busy.rb
+++ b/ext/tk/lib/tkextlib/blt/busy.rb
@@ -44,6 +44,7 @@ class << Tk::BLT::Busy
private :__item_config_cmd
undef itemcget
+ undef itemcget_tkstring
alias configure itemconfigure
alias configinfo itemconfiginfo
alias current_configinfo current_itemconfiginfo
diff --git a/ext/tk/lib/tkextlib/blt/component.rb b/ext/tk/lib/tkextlib/blt/component.rb
index 74cbcb56ae..20db035fdd 100644
--- a/ext/tk/lib/tkextlib/blt/component.rb
+++ b/ext/tk/lib/tkextlib/blt/component.rb
@@ -82,6 +82,9 @@ module Tk::BLT
end
private :__item_pathname
+ def axis_cget_tkstring(id, option)
+ ret = itemcget_tkstring(['axis', tagid(id)], option)
+ end
def axis_cget(id, option)
ret = itemcget(['axis', tagid(id)], option)
end
@@ -118,6 +121,9 @@ module Tk::BLT
current_itemconfiginfo(['axis', tagid(id)], slot)
end
+ def crosshairs_cget_tkstring(option)
+ itemcget_tkstring('crosshairs', option)
+ end
def crosshairs_cget(option)
itemcget('crosshairs', option)
end
@@ -134,6 +140,9 @@ module Tk::BLT
current_itemconfiginfo('crosshairs', slot)
end
+ def element_cget_tkstring(id, option)
+ itemcget_tkstring(['element', tagid(id)], option)
+ end
def element_cget(id, option)
itemcget(['element', tagid(id)], option)
end
@@ -158,6 +167,9 @@ module Tk::BLT
current_itemconfiginfo(['element', tagid(id)], slot)
end
+ def bar_cget_tkstring(id, option)
+ itemcget_tkstring(['bar', tagid(id)], option)
+ end
def bar_cget(id, option)
itemcget(['bar', tagid(id)], option)
end
@@ -182,6 +194,9 @@ module Tk::BLT
current_itemconfiginfo(['bar', tagid(id)], slot)
end
+ def line_cget_tkstring(id, option)
+ itemcget_tkstring(['line', tagid(id)], option)
+ end
def line_cget(id, option)
itemcget(['line', tagid(id)], option)
end
@@ -206,6 +221,9 @@ module Tk::BLT
current_itemconfiginfo(['line', tagid(id)], slot)
end
+ def gridline_cget_tkstring(option)
+ itemcget_tkstring('grid', option)
+ end
def gridline_cget(option)
itemcget('grid', option)
end
@@ -222,6 +240,9 @@ module Tk::BLT
current_itemconfiginfo('grid', slot)
end
+ def legend_cget_tkstring(option)
+ itemcget_tkstring('legend', option)
+ end
def legend_cget(option)
itemcget('legend', option)
end
@@ -238,6 +259,9 @@ module Tk::BLT
current_itemconfiginfo('legend', slot)
end
+ def pen_cget_tkstring(id, option)
+ itemcget_tkstring(['pen', tagid(id)], option)
+ end
def pen_cget(id, option)
itemcget(['pen', tagid(id)], option)
end
@@ -262,6 +286,9 @@ module Tk::BLT
current_itemconfiginfo(['pen', tagid(id)], slot)
end
+ def postscript_cget_tkstring(option)
+ itemcget_tkstring('postscript', option)
+ end
def postscript_cget(option)
itemcget('postscript', option)
end
@@ -278,6 +305,9 @@ module Tk::BLT
current_itemconfiginfo('postscript', slot)
end
+ def marker_cget_tkstring(id, option)
+ itemcget_tkstring(['marker', tagid(id)], option)
+ end
def marker_cget(id, option)
itemcget(['marker', tagid(id)], option)
end
@@ -302,12 +332,16 @@ module Tk::BLT
current_itemconfiginfo(['marker', tagid(id)], slot)
end
+ alias __itemcget_tkstring itemcget_tkstring
alias __itemcget itemcget
alias __itemcget_strict itemcget_strict
alias __itemconfiginfo itemconfiginfo
alias __current_itemconfiginfo current_itemconfiginfo
- private :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo
+ private :__itemcget_tkstring, :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo
+ def itemcget_tkstring(tagOrId, option)
+ __itemcget_tkstring(tagid(tagOrId), option)
+ end
def itemcget_strict(tagOrId, option)
ret = __itemcget(tagid(tagOrId), option)
if option == 'bindtags' || option == :bindtags
@@ -373,13 +407,13 @@ module Tk::BLT
ret
end
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
#################
class Axis < TkObject
- (OBJ_ID = ['blt_chart_axis'.freeze, '00000'.taint]).instance_eval{
+ (OBJ_ID = ['blt_chart_axis'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -477,6 +511,9 @@ module Tk::BLT
@id
end
+ def cget_tkstring(option)
+ @chart.axis_cget_tkstring(@id, option)
+ end
def cget(option)
@chart.axis_cget(@id, option)
end
@@ -582,6 +619,9 @@ module Tk::BLT
@id
end
+ def cget_tkstring(option)
+ @chart.crosshair_cget_tkstring(option)
+ end
def cget(option)
@chart.crosshair_cget(option)
end
@@ -631,7 +671,7 @@ module Tk::BLT
ElementID_TBL.mutex.synchronize{ ElementID_TBL.clear }
}
- (OBJ_ID = ['blt_chart_element'.freeze, '00000'.taint]).instance_eval{
+ (OBJ_ID = ['blt_chart_element'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -729,6 +769,10 @@ module Tk::BLT
@id
end
+ def cget_tkstring(option)
+ # @chart.element_cget(@id, option)
+ @chart.__send__(@typename + '_cget_tkstring', @id, option)
+ end
def cget(option)
# @chart.element_cget(@id, option)
@chart.__send__(@typename + '_cget', @id, option)
@@ -833,6 +877,9 @@ module Tk::BLT
@id
end
+ def cget_tkstring(option)
+ @chart.gridline_cget_tkstring(option)
+ end
def cget(option)
@chart.gridline_cget(option)
end
@@ -907,6 +954,9 @@ module Tk::BLT
@id
end
+ def cget_tkstring(option)
+ @chart.legend_cget_tkstring(option)
+ end
def cget(option)
@chart.legend_cget(option)
end
@@ -940,7 +990,7 @@ module Tk::BLT
#################
class Pen < TkObject
- (OBJ_ID = ['blt_chart_pen'.freeze, '00000'.taint]).instance_eval{
+ (OBJ_ID = ['blt_chart_pen'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -1036,6 +1086,9 @@ module Tk::BLT
@id
end
+ def cget_tkstring(option)
+ @chart.pen_cget_tkstring(@id, option)
+ end
def cget(option)
@chart.pen_cget(@id, option)
end
@@ -1106,6 +1159,9 @@ module Tk::BLT
@id
end
+ def cget_tkstring(option)
+ @chart.postscript_cget_tkstring(option)
+ end
def cget(option)
@chart.postscript_cget(option)
end
@@ -1269,6 +1325,9 @@ module Tk::BLT
@id
end
+ def cget_tkstring(option)
+ @chart.marker_cget_tkstring(@id, option)
+ end
def cget(option)
@chart.marker_cget(@id, option)
end
@@ -1854,6 +1913,9 @@ module Tk::BLT
###################
+ def xaxis_cget_tkstring(option)
+ itemcget_tkstring('xaxis', option)
+ end
def xaxis_cget(option)
itemcget('xaxis', option)
end
@@ -1926,6 +1988,9 @@ module Tk::BLT
end
end
+ def x2axis_cget_tkstring(option)
+ itemcget_tkstring('x2axis', option)
+ end
def x2axis_cget(option)
itemcget('x2axis', option)
end
@@ -1998,6 +2063,9 @@ module Tk::BLT
end
end
+ def yaxis_cget_tkstring(option)
+ itemcget_tkstring('yaxis', option)
+ end
def yaxis_cget(option)
itemcget('yaxis', option)
end
@@ -2070,6 +2138,9 @@ module Tk::BLT
end
end
+ def y2axis_cget_tkstring(option)
+ itemcget_tkstring('y2axis', option)
+ end
def y2axis_cget(option)
itemcget('y2axis', option)
end
diff --git a/ext/tk/lib/tkextlib/blt/container.rb b/ext/tk/lib/tkextlib/blt/container.rb
index cdbec21f25..be05828d95 100644
--- a/ext/tk/lib/tkextlib/blt/container.rb
+++ b/ext/tk/lib/tkextlib/blt/container.rb
@@ -10,7 +10,7 @@ module Tk::BLT
class Container < TkWindow
TkCommandNames = ['::blt::container'.freeze].freeze
WidgetClassName = 'Container'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'name'
diff --git a/ext/tk/lib/tkextlib/blt/dragdrop.rb b/ext/tk/lib/tkextlib/blt/dragdrop.rb
index d11d8bc41a..aa5c5654c2 100644
--- a/ext/tk/lib/tkextlib/blt/dragdrop.rb
+++ b/ext/tk/lib/tkextlib/blt/dragdrop.rb
@@ -15,7 +15,7 @@ module Tk::BLT
class Token < TkWindow
WidgetClassName = 'DragDropToken'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def initialize(arg)
if arg.kind_of?(Hash) # arg is a hash includes the widgetpath of token
@@ -55,6 +55,7 @@ module Tk::BLT
private :__item_strval_optkeys
undef itemcget
+ undef itemcget_tkstring
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
def source_configure(win, slot, value=None)
diff --git a/ext/tk/lib/tkextlib/blt/graph.rb b/ext/tk/lib/tkextlib/blt/graph.rb
index 9ae99bff5c..6bd4424065 100644
--- a/ext/tk/lib/tkextlib/blt/graph.rb
+++ b/ext/tk/lib/tkextlib/blt/graph.rb
@@ -11,7 +11,7 @@ module Tk::BLT
class Graph < TkWindow
TkCommandNames = ['::blt::graph'.freeze].freeze
WidgetClassName = 'Graph'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
include PlotComponent
include GraphCommand
@@ -27,7 +27,7 @@ module Tk::BLT
private :__strval_optkeys
=begin
- BarElement_ID = ['blt_graph_bar'.freeze, '00000'.taint].freeze
+ BarElement_ID = ['blt_graph_bar'.freeze, TkUtil.untrust('00000')].freeze
def bar(elem=nil, keys={})
if elem.kind_of?(Hash)
diff --git a/ext/tk/lib/tkextlib/blt/htext.rb b/ext/tk/lib/tkextlib/blt/htext.rb
index 0d9cb30185..878bd9982d 100644
--- a/ext/tk/lib/tkextlib/blt/htext.rb
+++ b/ext/tk/lib/tkextlib/blt/htext.rb
@@ -19,8 +19,9 @@ module Tk::BLT
TkCommandNames = ['::blt::htext'.freeze].freeze
WidgetClassName = 'Htext'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
+ alias window_cget_tkstring itemcget_tkstring
alias window_cget itemcget
alias window_cget_strict itemcget_strict
alias window_configure itemconfigure
diff --git a/ext/tk/lib/tkextlib/blt/stripchart.rb b/ext/tk/lib/tkextlib/blt/stripchart.rb
index a6b0f354e2..74093f1868 100644
--- a/ext/tk/lib/tkextlib/blt/stripchart.rb
+++ b/ext/tk/lib/tkextlib/blt/stripchart.rb
@@ -11,7 +11,7 @@ module Tk::BLT
class Stripchart < TkWindow
TkCommandNames = ['::blt::stripchart'.freeze].freeze
WidgetClassName = 'Stripchart'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
include PlotComponent
include GraphCommand
@@ -28,7 +28,7 @@ module Tk::BLT
private :__strval_optkeys
=begin
- BarElement_ID = ['blt_stripchart_bar'.freeze, '00000'.taint].freeze
+ BarElement_ID = ['blt_stripchart_bar'.freeze, TkUtil.untrust('00000')].freeze
def bar(elem=nil, keys={})
if elem.kind_of?(Hash)
diff --git a/ext/tk/lib/tkextlib/blt/table.rb b/ext/tk/lib/tkextlib/blt/table.rb
index dfa10269ed..205e29e6c5 100644
--- a/ext/tk/lib/tkextlib/blt/table.rb
+++ b/ext/tk/lib/tkextlib/blt/table.rb
@@ -26,6 +26,9 @@ module Tk::BLT
self
end
+ def blt_table_cget_tkstring(*args)
+ Tk::BLT::Table.cget_tkstring(self, *args)
+ end
def blt_table_cget(*args)
Tk::BLT::Table.cget(self, *args)
end
@@ -92,6 +95,9 @@ module Tk::BLT
self
end
+ def blt_table_itemcget_tkstring(*args)
+ Tk::BLT::Table.itemcget_tkstring(self, *args)
+ end
def blt_table_itemcget(*args)
Tk::BLT::Table.itemcget(self, *args)
end
@@ -141,13 +147,14 @@ class << Tk::BLT::Table
end
private :__item_pathname
+ alias __itemcget_tkstring itemcget_tkstring
alias __itemcget itemcget
alias __itemcget_strict itemcget_strict
alias __itemconfigure itemconfigure
alias __itemconfiginfo itemconfiginfo
alias __current_itemconfiginfo current_itemconfiginfo
- private :__itemcget, :__itemcget_strict
+ private :__itemcget_tkstring, :__itemcget, :__itemcget_strict
private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo
def __boolval_optkeys
@@ -180,6 +187,9 @@ class << Tk::BLT::Table
############################################
+ def cget_tkstring(container, option)
+ __itemcget_tkstring([container], option)
+ end
def cget(container, option)
__itemcget([container], option)
end
@@ -199,6 +209,9 @@ class << Tk::BLT::Table
__current_itemconfiginfo([container], *args)
end
+ def itemcget_tkstring(container, item, option)
+ __itemcget_tkstring([container, tagid(item)], option)
+ end
def itemcget(container, item, option)
__itemcget([container, tagid(item)], option)
end
diff --git a/ext/tk/lib/tkextlib/blt/tabnotebook.rb b/ext/tk/lib/tkextlib/blt/tabnotebook.rb
index 738ba7c601..82936c67d3 100644
--- a/ext/tk/lib/tkextlib/blt/tabnotebook.rb
+++ b/ext/tk/lib/tkextlib/blt/tabnotebook.rb
@@ -11,7 +11,7 @@ module Tk::BLT
class Tabnotebook < Tabset
TkCommandNames = ['::blt::tabnotebook'.freeze].freeze
WidgetClassName = 'Tabnotebook'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
class Tab < Tk::BLT::Tabset::Tab
def self.new(parent, pos=nil, name=nil, keys={})
diff --git a/ext/tk/lib/tkextlib/blt/tabset.rb b/ext/tk/lib/tkextlib/blt/tabset.rb
index b5e076db3a..c4716c7304 100644
--- a/ext/tk/lib/tkextlib/blt/tabset.rb
+++ b/ext/tk/lib/tkextlib/blt/tabset.rb
@@ -13,7 +13,7 @@ module Tk::BLT
TabID_TBL = TkCore::INTERP.create_table
- (TabsetTab_ID = ['blt_tabset_tab'.freeze, '00000'.taint]).instance_eval{
+ (TabsetTab_ID = ['blt_tabset_tab'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -132,6 +132,9 @@ module Tk::BLT
@t.tab_bindinfo(@id, context)
end
+ def cget_tkstring(*args)
+ @t.tab_cget_tkstring(@id, *args)
+ end
def cget(*args)
@t.tab_cget(@id, *args)
end
@@ -210,7 +213,7 @@ module Tk::BLT
TkCommandNames = ['::blt::tabset'.freeze].freeze
WidgetClassName = 'Tabset'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __destroy_hook__
Tk::BLT::Tabset::Tab::TabID_TBL.mutex.synchronize{
@@ -249,6 +252,7 @@ module Tk::BLT
end
private :__item_pathname
+ alias tab_cget_tkstring itemcget_tkstring
alias tab_cget itemcget
alias tab_cget_strict itemcget_strict
alias tab_configure itemconfigure
diff --git a/ext/tk/lib/tkextlib/blt/ted.rb b/ext/tk/lib/tkextlib/blt/ted.rb
index 670265fc78..53ab9acdaa 100644
--- a/ext/tk/lib/tkextlib/blt/ted.rb
+++ b/ext/tk/lib/tkextlib/blt/ted.rb
@@ -30,9 +30,12 @@ module Tk::BLT
end
private :__item_config_cmd
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+ def cget_tkstring(master, option)
+ itemcget_tkstring(master, option)
+ end
def cget(master, option)
itemcget(master, option)
end
diff --git a/ext/tk/lib/tkextlib/blt/tile.rb b/ext/tk/lib/tkextlib/blt/tile.rb
index 5f5242f299..c67cafd8d6 100644
--- a/ext/tk/lib/tkextlib/blt/tile.rb
+++ b/ext/tk/lib/tkextlib/blt/tile.rb
@@ -8,6 +8,10 @@ require 'tkextlib/blt.rb'
module Tk::BLT
module Tile
+ TkComm::TkExtlibAutoloadModule.unshift(self)
+ # Require autoload-symbols which is a same name as widget classname.
+ # Those are used at TkComm._genobj_for_tkwidget method.
+
autoload :Button, 'tkextlib/blt/tile/button.rb'
autoload :CheckButton, 'tkextlib/blt/tile/checkbutton.rb'
autoload :Checkbutton, 'tkextlib/blt/tile/checkbutton.rb'
diff --git a/ext/tk/lib/tkextlib/blt/tree.rb b/ext/tk/lib/tkextlib/blt/tree.rb
index 605a64daa6..da53a6ed04 100644
--- a/ext/tk/lib/tkextlib/blt/tree.rb
+++ b/ext/tk/lib/tkextlib/blt/tree.rb
@@ -272,7 +272,7 @@ module Tk::BLT
TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear }
}
- (TreeTag_ID = ['blt_tree_tag'.freeze, '00000'.taint]).instance_eval{
+ (TreeTag_ID = ['blt_tree_tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -578,7 +578,7 @@ module Tk::BLT
TreeID_TBL = TkCore::INTERP.create_table
- (Tree_ID = ['blt_tree'.freeze, '00000'.taint]).instance_eval{
+ (Tree_ID = ['blt_tree'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tkextlib/blt/treeview.rb b/ext/tk/lib/tkextlib/blt/treeview.rb
index 550422ee2e..046cf7f837 100644
--- a/ext/tk/lib/tkextlib/blt/treeview.rb
+++ b/ext/tk/lib/tkextlib/blt/treeview.rb
@@ -95,6 +95,9 @@ module Tk::BLT::Treeview::ConfigMethod
end
private :__item_pathname
+ def column_cget_tkstring(name, option)
+ itemcget_tkstring(['column', name], option)
+ end
def column_cget(name, option)
itemcget(['column', name], option)
end
@@ -111,6 +114,9 @@ module Tk::BLT::Treeview::ConfigMethod
current_itemconfiginfo(['column', name], slot)
end
+ def button_cget_tkstring(option)
+ itemcget_tkstring('button', option)
+ end
def button_cget(option)
itemcget('button', option)
end
@@ -127,6 +133,9 @@ module Tk::BLT::Treeview::ConfigMethod
current_itemconfiginfo('button', slot)
end
+ def entry_cget_tkstring(option)
+ itemcget_tkstring('entry', option)
+ end
def entry_cget(option)
ret = itemcget('entry', option)
if option == 'bindtags' || option == :bindtags
@@ -181,6 +190,9 @@ module Tk::BLT::Treeview::ConfigMethod
ret
end
+ def sort_cget_tkstring(option)
+ itemcget_tkstring('sort', option)
+ end
def sort_cget(option)
itemcget('sort', option)
end
@@ -197,6 +209,9 @@ module Tk::BLT::Treeview::ConfigMethod
current_itemconfiginfo('sort', slot)
end
+ def text_cget_tkstring(option)
+ itemcget_tkstring('text', option)
+ end
def text_cget(option)
itemcget('text', option)
end
@@ -213,14 +228,14 @@ module Tk::BLT::Treeview::ConfigMethod
current_itemconfiginfo('text', slot)
end
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
class Tk::BLT::Treeview
TkCommandNames = ['::blt::treeview'.freeze].freeze
WidgetClassName = 'TreeView'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
include Scrollable
include ValidateConfigure
@@ -1029,7 +1044,7 @@ class Tk::BLT::Treeview::Node < TkObject
TreeNodeID_TBL = TkCore::INTERP.create_table
- (TreeNode_ID = ['blt_treeview_node'.freeze, '00000'.taint]).instance_eval{
+ (TreeNode_ID = ['blt_treeview_node'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -1150,7 +1165,7 @@ class Tk::BLT::Treeview::Tag < TkObject
TreeTagID_TBL = TkCore::INTERP.create_table
- (TreeTag_ID = ['blt_treeview_tag'.freeze, '00000'.taint]).instance_eval{
+ (TreeTag_ID = ['blt_treeview_tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -1268,5 +1283,5 @@ end
class Tk::BLT::Hiertable
TkCommandNames = ['::blt::hiertable'.freeze].freeze
WidgetClassName = 'Hiertable'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
end
diff --git a/ext/tk/lib/tkextlib/blt/unix_dnd.rb b/ext/tk/lib/tkextlib/blt/unix_dnd.rb
index 445002d7a5..8996f7c891 100644
--- a/ext/tk/lib/tkextlib/blt/unix_dnd.rb
+++ b/ext/tk/lib/tkextlib/blt/unix_dnd.rb
@@ -30,9 +30,12 @@ module Tk::BLT
end
private :__item_config_cmd
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+ def cget_tkstring(win, option)
+ itemcget_tkstring(['cget', win], option)
+ end
def cget(win, option)
itemcget(['cget', win], option)
end
@@ -49,6 +52,9 @@ module Tk::BLT
current_itemconfiginfo(['configure', win], slot)
end
+ def token_cget_tkstring(win, option)
+ itemcget_tkstring(['token', 'cget', win], option)
+ end
def token_cget(win, option)
itemcget(['token', 'cget', win], option)
end
diff --git a/ext/tk/lib/tkextlib/blt/watch.rb b/ext/tk/lib/tkextlib/blt/watch.rb
index 219ff78e97..292623ff58 100644
--- a/ext/tk/lib/tkextlib/blt/watch.rb
+++ b/ext/tk/lib/tkextlib/blt/watch.rb
@@ -14,7 +14,7 @@ module Tk::BLT
WATCH_ID_TBL = TkCore::INTERP.create_table
- (BLT_WATCH_ID = ['blt_watch_id'.freeze, '00000'.taint]).instance_eval{
+ (BLT_WATCH_ID = ['blt_watch_id'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tkextlib/bwidget.rb b/ext/tk/lib/tkextlib/bwidget.rb
index 62631d8b54..7a1eff51d8 100644
--- a/ext/tk/lib/tkextlib/bwidget.rb
+++ b/ext/tk/lib/tkextlib/bwidget.rb
@@ -18,6 +18,8 @@ TkPackage.require('BWidget')
module Tk
module BWidget
TkComm::TkExtlibAutoloadModule.unshift(self)
+ # Require autoload-symbols which is a same name as widget classname.
+ # Those are used at TkComm._genobj_for_tkwidget method.
extend TkCore
diff --git a/ext/tk/lib/tkextlib/bwidget/arrowbutton.rb b/ext/tk/lib/tkextlib/bwidget/arrowbutton.rb
index 770e5e9ef1..13fe9e59bf 100644
--- a/ext/tk/lib/tkextlib/bwidget/arrowbutton.rb
+++ b/ext/tk/lib/tkextlib/bwidget/arrowbutton.rb
@@ -17,5 +17,5 @@ end
class Tk::BWidget::ArrowButton
TkCommandNames = ['ArrowButton'.freeze].freeze
WidgetClassName = 'ArrowButton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
end
diff --git a/ext/tk/lib/tkextlib/bwidget/button.rb b/ext/tk/lib/tkextlib/bwidget/button.rb
index 8f3087d098..e139fb6708 100644
--- a/ext/tk/lib/tkextlib/bwidget/button.rb
+++ b/ext/tk/lib/tkextlib/bwidget/button.rb
@@ -17,7 +17,7 @@ end
class Tk::BWidget::Button
TkCommandNames = ['Button'.freeze].freeze
WidgetClassName = 'Button'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'helptext'
diff --git a/ext/tk/lib/tkextlib/bwidget/buttonbox.rb b/ext/tk/lib/tkextlib/bwidget/buttonbox.rb
index 8d6d212189..a6de33c40c 100644
--- a/ext/tk/lib/tkextlib/bwidget/buttonbox.rb
+++ b/ext/tk/lib/tkextlib/bwidget/buttonbox.rb
@@ -17,7 +17,7 @@ end
class Tk::BWidget::ButtonBox
TkCommandNames = ['ButtonBox'.freeze].freeze
WidgetClassName = 'ButtonBox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
include TkItemConfigMethod
diff --git a/ext/tk/lib/tkextlib/bwidget/combobox.rb b/ext/tk/lib/tkextlib/bwidget/combobox.rb
index 1c58a4ccb0..16143dfbc6 100644
--- a/ext/tk/lib/tkextlib/bwidget/combobox.rb
+++ b/ext/tk/lib/tkextlib/bwidget/combobox.rb
@@ -21,7 +21,12 @@ class Tk::BWidget::ComboBox
TkCommandNames = ['ComboBox'.freeze].freeze
WidgetClassName = 'ComboBox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
+
+ def __boolval_optkeys
+ super() << 'autocomplete' << 'autopost'
+ end
+ private :__boolval_optkeys
def get_listbox(&b)
win = window(tk_send_without_enc('getlistbox'))
@@ -35,6 +40,12 @@ class Tk::BWidget::ComboBox
win
end
+ def clear_value
+ tk_send_without_enc('clearvalue')
+ self
+ end
+ alias clearvalue clear_value
+
def icursor(idx)
tk_send_without_enc('icursor', idx)
end
diff --git a/ext/tk/lib/tkextlib/bwidget/dialog.rb b/ext/tk/lib/tkextlib/bwidget/dialog.rb
index 13527f96ad..3b0656f021 100644
--- a/ext/tk/lib/tkextlib/bwidget/dialog.rb
+++ b/ext/tk/lib/tkextlib/bwidget/dialog.rb
@@ -18,12 +18,17 @@ end
class Tk::BWidget::Dialog
TkCommandNames = ['Dialog'.freeze].freeze
WidgetClassName = 'Dialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
include TkItemConfigMethod
+ def __numstrval_optkeys
+ super() << 'buttonwidth'
+ end
+ private :__numstrval_optkeys
+
def __strval_optkeys
- super() << 'title'
+ super() << 'title' << 'geometry'
end
private :__strval_optkeys
@@ -59,6 +64,13 @@ class Tk::BWidget::Dialog
end
end
+ def cget_tkstring(slot)
+ if slot.to_s == 'relative'
+ super('parent')
+ else
+ super(slot)
+ end
+ end
def cget_strict(slot)
if slot.to_s == 'relative'
super('parent')
diff --git a/ext/tk/lib/tkextlib/bwidget/entry.rb b/ext/tk/lib/tkextlib/bwidget/entry.rb
index a56890f4e3..8dc4496123 100644
--- a/ext/tk/lib/tkextlib/bwidget/entry.rb
+++ b/ext/tk/lib/tkextlib/bwidget/entry.rb
@@ -19,7 +19,7 @@ class Tk::BWidget::Entry
TkCommandNames = ['Entry'.freeze].freeze
WidgetClassName = 'Entry'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'helptext' << 'insertbackground'
diff --git a/ext/tk/lib/tkextlib/bwidget/label.rb b/ext/tk/lib/tkextlib/bwidget/label.rb
index 88a504aa50..e8d9352c62 100644
--- a/ext/tk/lib/tkextlib/bwidget/label.rb
+++ b/ext/tk/lib/tkextlib/bwidget/label.rb
@@ -17,7 +17,7 @@ end
class Tk::BWidget::Label
TkCommandNames = ['Label'.freeze].freeze
WidgetClassName = 'Label'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'helptext'
diff --git a/ext/tk/lib/tkextlib/bwidget/labelentry.rb b/ext/tk/lib/tkextlib/bwidget/labelentry.rb
index 95b40946a6..16e7b46933 100644
--- a/ext/tk/lib/tkextlib/bwidget/labelentry.rb
+++ b/ext/tk/lib/tkextlib/bwidget/labelentry.rb
@@ -21,7 +21,7 @@ class Tk::BWidget::LabelEntry
TkCommandNames = ['LabelEntry'.freeze].freeze
WidgetClassName = 'LabelEntry'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg'
diff --git a/ext/tk/lib/tkextlib/bwidget/labelframe.rb b/ext/tk/lib/tkextlib/bwidget/labelframe.rb
index dc221806e4..0710f213f0 100644
--- a/ext/tk/lib/tkextlib/bwidget/labelframe.rb
+++ b/ext/tk/lib/tkextlib/bwidget/labelframe.rb
@@ -18,7 +18,7 @@ end
class Tk::BWidget::LabelFrame
TkCommandNames = ['LabelFrame'.freeze].freeze
WidgetClassName = 'LabelFrame'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'helptext'
diff --git a/ext/tk/lib/tkextlib/bwidget/listbox.rb b/ext/tk/lib/tkextlib/bwidget/listbox.rb
index 33b69b408a..930491c869 100644
--- a/ext/tk/lib/tkextlib/bwidget/listbox.rb
+++ b/ext/tk/lib/tkextlib/bwidget/listbox.rb
@@ -25,7 +25,7 @@ class Tk::BWidget::ListBox
TkCommandNames = ['ListBox'.freeze].freeze
WidgetClassName = 'ListBox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
class Event_for_Items < TkEvent::Event
def self._get_extra_args_tbl
@@ -212,7 +212,7 @@ class Tk::BWidget::ListBox::Item
ListItem_TBL = TkCore::INTERP.create_table
- (ListItem_ID = ['bw:item'.freeze, '00000'.taint]).instance_eval{
+ (ListItem_ID = ['bw:item'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -294,6 +294,9 @@ class Tk::BWidget::ListBox::Item
val
end
+ def cget_tkstring(key)
+ @listbox.itemcget_tkstring(@id, key)
+ end
def cget(key)
@listbox.itemcget(@id, key)
end
diff --git a/ext/tk/lib/tkextlib/bwidget/mainframe.rb b/ext/tk/lib/tkextlib/bwidget/mainframe.rb
index de66eaf81e..92253bd8d3 100644
--- a/ext/tk/lib/tkextlib/bwidget/mainframe.rb
+++ b/ext/tk/lib/tkextlib/bwidget/mainframe.rb
@@ -18,7 +18,7 @@ end
class Tk::BWidget::MainFrame
TkCommandNames = ['MainFrame'.freeze].freeze
WidgetClassName = 'MainFrame'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'progressfg'
@@ -111,6 +111,10 @@ class Tk::BWidget::MainFrame
win
end
+ def get_menustate(tag)
+ tk_send('getmenustate', tag) # return state name string
+ end
+
def set_menustate(tag, state)
tk_send('setmenustate', tag, state)
self
diff --git a/ext/tk/lib/tkextlib/bwidget/messagedlg.rb b/ext/tk/lib/tkextlib/bwidget/messagedlg.rb
index 9b46532934..7b62614737 100644
--- a/ext/tk/lib/tkextlib/bwidget/messagedlg.rb
+++ b/ext/tk/lib/tkextlib/bwidget/messagedlg.rb
@@ -17,7 +17,7 @@ end
class Tk::BWidget::MessageDlg
TkCommandNames = ['MessageDlg'.freeze].freeze
WidgetClassName = 'MessageDlg'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def initialize(parent=nil, keys=nil)
@relative = ''
diff --git a/ext/tk/lib/tkextlib/bwidget/notebook.rb b/ext/tk/lib/tkextlib/bwidget/notebook.rb
index 6101fa93e5..ed28bcd86a 100644
--- a/ext/tk/lib/tkextlib/bwidget/notebook.rb
+++ b/ext/tk/lib/tkextlib/bwidget/notebook.rb
@@ -19,7 +19,7 @@ class Tk::BWidget::NoteBook
TkCommandNames = ['NoteBook'.freeze].freeze
WidgetClassName = 'NoteBook'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
class Event_for_Tabs < TkEvent::Event
def self._get_extra_args_tbl
diff --git a/ext/tk/lib/tkextlib/bwidget/pagesmanager.rb b/ext/tk/lib/tkextlib/bwidget/pagesmanager.rb
index fbc2c11255..31bbf1fb8b 100644
--- a/ext/tk/lib/tkextlib/bwidget/pagesmanager.rb
+++ b/ext/tk/lib/tkextlib/bwidget/pagesmanager.rb
@@ -17,7 +17,7 @@ end
class Tk::BWidget::PagesManager
TkCommandNames = ['PagesManager'.freeze].freeze
WidgetClassName = 'PagesManager'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def tagid(id)
# id.to_s
diff --git a/ext/tk/lib/tkextlib/bwidget/panedwindow.rb b/ext/tk/lib/tkextlib/bwidget/panedwindow.rb
index 4d979fd523..54cf06cbde 100644
--- a/ext/tk/lib/tkextlib/bwidget/panedwindow.rb
+++ b/ext/tk/lib/tkextlib/bwidget/panedwindow.rb
@@ -17,7 +17,12 @@ end
class Tk::BWidget::PanedWindow
TkCommandNames = ['PanedWindow'.freeze].freeze
WidgetClassName = 'PanedWindow'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
+
+ def __strval_optkeys
+ super() << 'activator'
+ end
+ private :__strval_optkeys
def add(keys={})
window(tk_send('add', *hash_kv(keys)))
diff --git a/ext/tk/lib/tkextlib/bwidget/panelframe.rb b/ext/tk/lib/tkextlib/bwidget/panelframe.rb
index 84bae0768b..1cbf914425 100644
--- a/ext/tk/lib/tkextlib/bwidget/panelframe.rb
+++ b/ext/tk/lib/tkextlib/bwidget/panelframe.rb
@@ -17,7 +17,7 @@ end
class Tk::BWidget::PanelFrame
TkCommandNames = ['PanelFrame'.freeze].freeze
WidgetClassName = 'PanelFrame'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() + ['panelforeground', 'panelbackground']
@@ -47,11 +47,21 @@ class Tk::BWidget::PanelFrame
end
def items
- list(tk_send('items'))
+ simplelist(tk_send('items')).map{|w| window(w)}
end
def remove(*wins)
tk_send('remove', *wins)
self
end
+
+ def remove_with_destroy(*wins)
+ tk_send('remove', '-destroy', *wins)
+ self
+ end
+
+ def delete(*wins) # same to 'remove_with_destroy'
+ tk_send('delete', *wins)
+ self
+ end
end
diff --git a/ext/tk/lib/tkextlib/bwidget/passwddlg.rb b/ext/tk/lib/tkextlib/bwidget/passwddlg.rb
index 2c7153333c..ea50c87cef 100644
--- a/ext/tk/lib/tkextlib/bwidget/passwddlg.rb
+++ b/ext/tk/lib/tkextlib/bwidget/passwddlg.rb
@@ -17,7 +17,7 @@ end
class Tk::BWidget::PasswdDlg
TkCommandNames = ['PasswdDlg'.freeze].freeze
WidgetClassName = 'PasswdDlg'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'loginhelptext' << 'loginlabel' << 'logintext' <<
diff --git a/ext/tk/lib/tkextlib/bwidget/progressbar.rb b/ext/tk/lib/tkextlib/bwidget/progressbar.rb
index 0253ce2ada..18eb67349b 100644
--- a/ext/tk/lib/tkextlib/bwidget/progressbar.rb
+++ b/ext/tk/lib/tkextlib/bwidget/progressbar.rb
@@ -16,5 +16,5 @@ end
class Tk::BWidget::ProgressBar
TkCommandNames = ['ProgressBar'.freeze].freeze
WidgetClassName = 'ProgressBar'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
end
diff --git a/ext/tk/lib/tkextlib/bwidget/progressdlg.rb b/ext/tk/lib/tkextlib/bwidget/progressdlg.rb
index 32600255d5..0c0c4540bc 100644
--- a/ext/tk/lib/tkextlib/bwidget/progressdlg.rb
+++ b/ext/tk/lib/tkextlib/bwidget/progressdlg.rb
@@ -19,7 +19,7 @@ end
class Tk::BWidget::ProgressDlg
TkCommandNames = ['ProgressDlg'.freeze].freeze
WidgetClassName = 'ProgressDlg'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
# NOT create widget for reusing the object
diff --git a/ext/tk/lib/tkextlib/bwidget/scrollableframe.rb b/ext/tk/lib/tkextlib/bwidget/scrollableframe.rb
index 010c960ec5..5bd00d6870 100644
--- a/ext/tk/lib/tkextlib/bwidget/scrollableframe.rb
+++ b/ext/tk/lib/tkextlib/bwidget/scrollableframe.rb
@@ -19,7 +19,7 @@ class Tk::BWidget::ScrollableFrame
TkCommandNames = ['ScrollableFrame'.freeze].freeze
WidgetClassName = 'ScrollableFrame'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def get_frame(&b)
win = window(tk_send_without_enc('getframe'))
diff --git a/ext/tk/lib/tkextlib/bwidget/scrolledwindow.rb b/ext/tk/lib/tkextlib/bwidget/scrolledwindow.rb
index 3599fd8459..ea5a18cc66 100644
--- a/ext/tk/lib/tkextlib/bwidget/scrolledwindow.rb
+++ b/ext/tk/lib/tkextlib/bwidget/scrolledwindow.rb
@@ -17,7 +17,17 @@ end
class Tk::BWidget::ScrolledWindow
TkCommandNames = ['ScrolledWindow'.freeze].freeze
WidgetClassName = 'ScrolledWindow'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
+
+ def __strval_optkeys
+ super() << 'sides'
+ end
+ private :__strval_optkeys
+
+ def __boolval_optkeys
+ super() << 'managed'
+ end
+ private :__boolval_optkeys
def get_frame(&b)
win = window(tk_send_without_enc('getframe'))
diff --git a/ext/tk/lib/tkextlib/bwidget/scrollview.rb b/ext/tk/lib/tkextlib/bwidget/scrollview.rb
index 0546af2c43..ab27bc91cf 100644
--- a/ext/tk/lib/tkextlib/bwidget/scrollview.rb
+++ b/ext/tk/lib/tkextlib/bwidget/scrollview.rb
@@ -16,7 +16,7 @@ end
class Tk::BWidget::ScrollView
TkCommandNames = ['ScrollView'.freeze].freeze
WidgetClassName = 'ScrollView'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'fill'
diff --git a/ext/tk/lib/tkextlib/bwidget/selectcolor.rb b/ext/tk/lib/tkextlib/bwidget/selectcolor.rb
index 82bd05eb13..456175e87e 100644
--- a/ext/tk/lib/tkextlib/bwidget/selectcolor.rb
+++ b/ext/tk/lib/tkextlib/bwidget/selectcolor.rb
@@ -24,7 +24,7 @@ class Tk::BWidget::SelectColor
TkCommandNames = ['SelectColor'.freeze].freeze
WidgetClassName = 'SelectColor'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def dialog(keys={})
newkeys = @keys.dup
diff --git a/ext/tk/lib/tkextlib/bwidget/selectfont.rb b/ext/tk/lib/tkextlib/bwidget/selectfont.rb
index 71b1afded3..23419cb0fa 100644
--- a/ext/tk/lib/tkextlib/bwidget/selectfont.rb
+++ b/ext/tk/lib/tkextlib/bwidget/selectfont.rb
@@ -23,13 +23,18 @@ class Tk::BWidget::SelectFont
TkCommandNames = ['SelectFont'.freeze].freeze
WidgetClassName = 'SelectFont'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'sampletext' << 'title'
end
private :__strval_optkeys
+ def __boolval_optkeys
+ super() << 'nosizes'
+ end
+ private :__boolval_optkeys
+
def __font_optkeys
[] # without fontobj operation
end
diff --git a/ext/tk/lib/tkextlib/bwidget/separator.rb b/ext/tk/lib/tkextlib/bwidget/separator.rb
index d9c3458e51..6d92321210 100644
--- a/ext/tk/lib/tkextlib/bwidget/separator.rb
+++ b/ext/tk/lib/tkextlib/bwidget/separator.rb
@@ -16,5 +16,5 @@ end
class Tk::BWidget::Separator
TkCommandNames = ['Separator'.freeze].freeze
WidgetClassName = 'Separator'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
end
diff --git a/ext/tk/lib/tkextlib/bwidget/spinbox.rb b/ext/tk/lib/tkextlib/bwidget/spinbox.rb
index 48358baa5c..0a45b045fb 100644
--- a/ext/tk/lib/tkextlib/bwidget/spinbox.rb
+++ b/ext/tk/lib/tkextlib/bwidget/spinbox.rb
@@ -20,7 +20,7 @@ class Tk::BWidget::SpinBox
TkCommandNames = ['SpinBox'.freeze].freeze
WidgetClassName = 'SpinBox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'helptext' << 'insertbackground' << 'entryfg' << 'entrybg'
diff --git a/ext/tk/lib/tkextlib/bwidget/statusbar.rb b/ext/tk/lib/tkextlib/bwidget/statusbar.rb
index 39c678d37e..5c5dd43fe4 100644
--- a/ext/tk/lib/tkextlib/bwidget/statusbar.rb
+++ b/ext/tk/lib/tkextlib/bwidget/statusbar.rb
@@ -17,10 +17,10 @@ end
class Tk::BWidget::StatusBar
TkCommandNames = ['StatusBar'.freeze].freeze
WidgetClassName = 'StatusBar'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
- super() << 'showresize'
+ super() << 'showresize' << 'showseparator' << 'showresizesep'
end
private :__boolval_optkeys
@@ -29,7 +29,17 @@ class Tk::BWidget::StatusBar
self
end
- def delete(*wins)
+ def remove(*wins)
+ tk_send('remove', *wins)
+ self
+ end
+
+ def remove_with_destroy(*wins)
+ tk_send('remove', '-destroy', *wins)
+ self
+ end
+
+ def delete(*wins) # same to 'remove_with_destroy'
tk_send('delete', *wins)
self
end
@@ -47,6 +57,6 @@ class Tk::BWidget::StatusBar
end
def items
- list(tk_send('items'))
+ simplelist(tk_send('items')).map{|w| window(w)}
end
end
diff --git a/ext/tk/lib/tkextlib/bwidget/titleframe.rb b/ext/tk/lib/tkextlib/bwidget/titleframe.rb
index 68534e66e9..71879111c1 100644
--- a/ext/tk/lib/tkextlib/bwidget/titleframe.rb
+++ b/ext/tk/lib/tkextlib/bwidget/titleframe.rb
@@ -17,7 +17,7 @@ end
class Tk::BWidget::TitleFrame
TkCommandNames = ['TitleFrame'.freeze].freeze
WidgetClassName = 'TitleFrame'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def get_frame(&b)
win = window(tk_send_without_enc('getframe'))
diff --git a/ext/tk/lib/tkextlib/bwidget/tree.rb b/ext/tk/lib/tkextlib/bwidget/tree.rb
index 86074ab6f4..089c482fe8 100644
--- a/ext/tk/lib/tkextlib/bwidget/tree.rb
+++ b/ext/tk/lib/tkextlib/bwidget/tree.rb
@@ -22,7 +22,7 @@ class Tk::BWidget::Tree
TkCommandNames = ['Tree'.freeze].freeze
WidgetClassName = 'Tree'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
class Event_for_Items < TkEvent::Event
def self._get_extra_args_tbl
@@ -57,6 +57,37 @@ class Tk::BWidget::Tree
end
end
+ def areabind(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind_for_event_class(Event_for_Items, [path, 'bindArea'],
+ context, cmd, *args)
+ self
+ end
+
+ def areabind_append(context, *args)
+ if TkComm._callback_entry?(args[0]) || !block_given?
+ cmd = args.shift
+ else
+ cmd = Proc.new
+ end
+ _bind_append_for_event_class(Event_for_Items, [path, 'bindArea'],
+ context, cmd, *args)
+ self
+ end
+
+ def areabind_remove(*args)
+ _bind_remove_for_event_class(Event_for_Items, [path, 'bindArea'], *args)
+ self
+ end
+
+ def areabindinfo(*args)
+ _bindinfo_for_event_class(Event_for_Items, [path, 'bindArea'], *args)
+ end
+
#def imagebind(*args)
# _bind_for_event_class(Event_for_Items, [path, 'bindImage'], *args)
# self
@@ -158,6 +189,16 @@ class Tk::BWidget::Tree
bool(tk_send('exists', tagid(node)))
end
+ def find(findinfo, confine=None)
+ Tk::BWidget::Tree::Node.id2obj(self, tk_send(findinfo, confine))
+ end
+ def find_position(x, y, confine=None)
+ self.find(_at(x,y), confine)
+ end
+ def find_line(linenum)
+ self.find(linenum)
+ end
+
def index(node)
num_or_str(tk_send('index', tagid(node)))
end
@@ -167,6 +208,10 @@ class Tk::BWidget::Tree
self
end
+ def line(node)
+ number(tk_send('line', tagid(node)))
+ end
+
def move(parent, node, idx)
tk_send('move', tagid(parent), tagid(node), idx)
self
@@ -183,7 +228,7 @@ class Tk::BWidget::Tree
end
def open?(node)
- bool(@tree.itemcget(tagid(node), 'open'))
+ bool(self.itemcget(tagid(node), 'open'))
end
def open_tree(node, recurse=None)
@@ -264,7 +309,7 @@ class Tk::BWidget::Tree::Node
TreeNode_TBL = TkCore::INTERP.create_table
- (TreeNode_ID = ['bw:node'.freeze, '00000'.taint]).instance_eval{
+ (TreeNode_ID = ['bw:node'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -355,6 +400,9 @@ class Tk::BWidget::Tree::Node
val
end
+ def cget_tkstring(key)
+ @tree.itemcget_tkstring(@id, key)
+ end
def cget(key)
@tree.itemcget(@id, key)
end
@@ -450,4 +498,3 @@ class Tk::BWidget::Tree::Node
@tree.visible(@id)
end
end
-
diff --git a/ext/tk/lib/tkextlib/itcl/incr_tcl.rb b/ext/tk/lib/tkextlib/itcl/incr_tcl.rb
index 2b75d62eb9..8f6bb33abe 100644
--- a/ext/tk/lib/tkextlib/itcl/incr_tcl.rb
+++ b/ext/tk/lib/tkextlib/itcl/incr_tcl.rb
@@ -40,12 +40,12 @@ module Tk
class ItclObject < TkObject
ITCL_CLASSNAME = ''.freeze
- (ITCL_OBJ_ID = ['itclobj'.freeze, '00000'.taint]).instance_eval{
+ (ITCL_OBJ_ID = ['itclobj'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
}
- ITCL_OBJ_TBL = {}.taint
+ ITCL_OBJ_TBL = TkUtil.untrust({})
def initialize(*args)
if (@klass = self.class::ITCL_CLASSNAME).empty?
diff --git a/ext/tk/lib/tkextlib/itk/incr_tk.rb b/ext/tk/lib/tkextlib/itk/incr_tk.rb
index 8772f21b49..989585e33b 100644
--- a/ext/tk/lib/tkextlib/itk/incr_tk.rb
+++ b/ext/tk/lib/tkextlib/itk/incr_tk.rb
@@ -111,7 +111,7 @@ module Tk
class Toplevel < Archetype
TkCommandNames = ['::itk::Toplevel'].freeze
WidgetClassName = 'Toplevel'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
include Wm
include TkMenuSpec
@@ -127,7 +127,7 @@ module Tk
class Widget < Archetype
TkCommandNames = ['::itk::Widget'].freeze
WidgetClassName = 'Widget'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
end
@@ -146,7 +146,7 @@ module Tk
ComponentID_TBL = TkCore::INTERP.create_table
- (Itk_Component_ID = ['itk:component'.freeze, '00000'.taint]).instance_eval{
+ (Itk_Component_ID = ['itk:component'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb b/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb
index 05d58c386f..91e06d1b52 100644
--- a/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Buttonbox
TkCommandNames = ['::iwidgets::buttonbox'.freeze].freeze
WidgetClassName = 'Buttonbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
@@ -46,13 +46,14 @@ class Tk::Iwidgets::Buttonbox
end
end
+ alias buttoncget_tkstring itemcget_tkstring
alias buttoncget itemcget
alias buttoncget_strict itemcget_strict
alias buttonconfigure itemconfigure
alias buttonconfiginfo itemconfiginfo
alias current_buttonconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/calendar.rb b/ext/tk/lib/tkextlib/iwidgets/calendar.rb
index e85d6e4e51..a5478c7cc6 100644
--- a/ext/tk/lib/tkextlib/iwidgets/calendar.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/calendar.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Calendar
TkCommandNames = ['::iwidgets::calendar'.freeze].freeze
WidgetClassName = 'Calendar'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() + [
diff --git a/ext/tk/lib/tkextlib/iwidgets/canvasprintbox.rb b/ext/tk/lib/tkextlib/iwidgets/canvasprintbox.rb
index fa5e90ad05..398eec3f1a 100644
--- a/ext/tk/lib/tkextlib/iwidgets/canvasprintbox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/canvasprintbox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Canvasprintbox
TkCommandNames = ['::iwidgets::canvasprintbox'.freeze].freeze
WidgetClassName = 'Canvasprintbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'filename'
diff --git a/ext/tk/lib/tkextlib/iwidgets/canvasprintdialog.rb b/ext/tk/lib/tkextlib/iwidgets/canvasprintdialog.rb
index bbf507677c..e64d8154ca 100644
--- a/ext/tk/lib/tkextlib/iwidgets/canvasprintdialog.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/canvasprintdialog.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Canvasprintdialog
TkCommandNames = ['::iwidgets::canvasprintdialog'.freeze].freeze
WidgetClassName = 'Canvasprintdialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def get_output
tk_call(@path, 'getoutput')
diff --git a/ext/tk/lib/tkextlib/iwidgets/checkbox.rb b/ext/tk/lib/tkextlib/iwidgets/checkbox.rb
index c85d356c55..a7476c824e 100644
--- a/ext/tk/lib/tkextlib/iwidgets/checkbox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/checkbox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Checkbox
TkCommandNames = ['::iwidgets::checkbox'.freeze].freeze
WidgetClassName = 'Checkbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
@@ -46,13 +46,14 @@ class Tk::Iwidgets::Checkbox
end
end
+ alias buttoncget_tkstring itemcget_tkstring
alias buttoncget itemcget
alias buttoncget_strict itemcget_strict
alias buttonconfigure itemconfigure
alias buttonconfiginfo itemconfiginfo
alias current_buttonconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/combobox.rb b/ext/tk/lib/tkextlib/iwidgets/combobox.rb
index a6d54d78fa..82dcf25d0b 100644
--- a/ext/tk/lib/tkextlib/iwidgets/combobox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/combobox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Combobox
TkCommandNames = ['::iwidgets::combobox'.freeze].freeze
WidgetClassName = 'Combobox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'completion' << 'dropdown' << 'editable' << 'unique'
diff --git a/ext/tk/lib/tkextlib/iwidgets/dateentry.rb b/ext/tk/lib/tkextlib/iwidgets/dateentry.rb
index 0a8897f50d..98a0051e55 100644
--- a/ext/tk/lib/tkextlib/iwidgets/dateentry.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/dateentry.rb
@@ -16,5 +16,5 @@ end
class Tk::Iwidgets::Dateentry
TkCommandNames = ['::iwidgets::dateentry'.freeze].freeze
WidgetClassName = 'Dateentry'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
end
diff --git a/ext/tk/lib/tkextlib/iwidgets/datefield.rb b/ext/tk/lib/tkextlib/iwidgets/datefield.rb
index 632f3334dc..50d5405a3b 100644
--- a/ext/tk/lib/tkextlib/iwidgets/datefield.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/datefield.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Datefield
TkCommandNames = ['::iwidgets::datefield'.freeze].freeze
WidgetClassName = 'Datefield'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'gmt'
diff --git a/ext/tk/lib/tkextlib/iwidgets/dialog.rb b/ext/tk/lib/tkextlib/iwidgets/dialog.rb
index 8540eae1b5..2d554ca7b5 100644
--- a/ext/tk/lib/tkextlib/iwidgets/dialog.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/dialog.rb
@@ -16,5 +16,5 @@ end
class Tk::Iwidgets::Dialog
TkCommandNames = ['::iwidgets::dialog'.freeze].freeze
WidgetClassName = 'Dialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
end
diff --git a/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb b/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb
index 8d43cc07ab..e880594532 100644
--- a/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Dialogshell
TkCommandNames = ['::iwidgets::dialogshell'.freeze].freeze
WidgetClassName = 'Dialogshell'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
@@ -46,13 +46,14 @@ class Tk::Iwidgets::Dialogshell
end
end
+ alias buttoncget_tkstring itemcget_tkstring
alias buttoncget itemcget
alias buttoncget_strict itemcget_strict
alias buttonconfigure itemconfigure
alias buttonconfiginfo itemconfiginfo
alias current_buttonconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/disjointlistbox.rb b/ext/tk/lib/tkextlib/iwidgets/disjointlistbox.rb
index 9bc063ba69..07ab025cdf 100644
--- a/ext/tk/lib/tkextlib/iwidgets/disjointlistbox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/disjointlistbox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Disjointlistbox
TkCommandNames = ['::iwidgets::disjointlistbox'.freeze].freeze
WidgetClassName = 'Disjointlistbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'lhslabeltext' << 'rhslabeltext' << 'lhsbuttonlabel' << 'rhsbuttonlabel'
diff --git a/ext/tk/lib/tkextlib/iwidgets/entryfield.rb b/ext/tk/lib/tkextlib/iwidgets/entryfield.rb
index 6e1cd0053b..3e7149a662 100644
--- a/ext/tk/lib/tkextlib/iwidgets/entryfield.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/entryfield.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Entryfield
TkCommandNames = ['::iwidgets::entryfield'.freeze].freeze
WidgetClassName = 'Entryfield'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __font_optkeys
super() << 'textfont'
diff --git a/ext/tk/lib/tkextlib/iwidgets/extbutton.rb b/ext/tk/lib/tkextlib/iwidgets/extbutton.rb
index 158d9d474a..e744fba91a 100644
--- a/ext/tk/lib/tkextlib/iwidgets/extbutton.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/extbutton.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Extbutton
TkCommandNames = ['::iwidgets::extbutton'.freeze].freeze
WidgetClassName = 'Extbutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'bitmapforeground' << 'ringbackground'
diff --git a/ext/tk/lib/tkextlib/iwidgets/extfileselectionbox.rb b/ext/tk/lib/tkextlib/iwidgets/extfileselectionbox.rb
index 526dae1123..2ff15bb509 100644
--- a/ext/tk/lib/tkextlib/iwidgets/extfileselectionbox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/extfileselectionbox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Extfileselectionbox
TkCommandNames = ['::iwidgets::extfileselectionbox'.freeze].freeze
WidgetClassName = 'Extfileselectionbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() + [
diff --git a/ext/tk/lib/tkextlib/iwidgets/extfileselectiondialog.rb b/ext/tk/lib/tkextlib/iwidgets/extfileselectiondialog.rb
index 14388be7c4..509fdcf636 100644
--- a/ext/tk/lib/tkextlib/iwidgets/extfileselectiondialog.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/extfileselectiondialog.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Extfileselectiondialog
TkCommandNames = ['::iwidgets::extfileselectiondialog'.freeze].freeze
WidgetClassName = 'Extfileselectiondialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def child_site
window(tk_call(@path, 'childsite'))
diff --git a/ext/tk/lib/tkextlib/iwidgets/feedback.rb b/ext/tk/lib/tkextlib/iwidgets/feedback.rb
index 0a25237a24..29d04c8a5d 100644
--- a/ext/tk/lib/tkextlib/iwidgets/feedback.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/feedback.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Feedback
TkCommandNames = ['::iwidgets::feedback'.freeze].freeze
WidgetClassName = 'Feedback'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'barcolor'
diff --git a/ext/tk/lib/tkextlib/iwidgets/fileselectionbox.rb b/ext/tk/lib/tkextlib/iwidgets/fileselectionbox.rb
index eb4dde484f..a425b53b5f 100644
--- a/ext/tk/lib/tkextlib/iwidgets/fileselectionbox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/fileselectionbox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Fileselectionbox
TkCommandNames = ['::iwidgets::fileselectionbox'.freeze].freeze
WidgetClassName = 'Fileselectionbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() + [
diff --git a/ext/tk/lib/tkextlib/iwidgets/fileselectiondialog.rb b/ext/tk/lib/tkextlib/iwidgets/fileselectiondialog.rb
index 50f459e56d..ebcdaf8c0b 100644
--- a/ext/tk/lib/tkextlib/iwidgets/fileselectiondialog.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/fileselectiondialog.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Fileselectiondialog
TkCommandNames = ['::iwidgets::fileselectiondialog'.freeze].freeze
WidgetClassName = 'Fileselectiondialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def child_site
window(tk_call(@path, 'childsite'))
diff --git a/ext/tk/lib/tkextlib/iwidgets/finddialog.rb b/ext/tk/lib/tkextlib/iwidgets/finddialog.rb
index c46b972214..3d522e07c8 100644
--- a/ext/tk/lib/tkextlib/iwidgets/finddialog.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/finddialog.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Finddialog
TkCommandNames = ['::iwidgets::finddialog'.freeze].freeze
WidgetClassName = 'Finddialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() + [
diff --git a/ext/tk/lib/tkextlib/iwidgets/hierarchy.rb b/ext/tk/lib/tkextlib/iwidgets/hierarchy.rb
index fa16d9aad8..cb9301d0c9 100644
--- a/ext/tk/lib/tkextlib/iwidgets/hierarchy.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/hierarchy.rb
@@ -20,7 +20,7 @@ class Tk::Iwidgets::Hierarchy
TkCommandNames = ['::iwidgets::hierarchy'.freeze].freeze
WidgetClassName = 'Hierarchy'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/hyperhelp.rb b/ext/tk/lib/tkextlib/iwidgets/hyperhelp.rb
index 77b0e090cd..d4ea1aac65 100644
--- a/ext/tk/lib/tkextlib/iwidgets/hyperhelp.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/hyperhelp.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Hyperhelp
TkCommandNames = ['::iwidgets::hyperhelp'.freeze].freeze
WidgetClassName = 'Hyperhelp'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'helpdir'
diff --git a/ext/tk/lib/tkextlib/iwidgets/labeledframe.rb b/ext/tk/lib/tkextlib/iwidgets/labeledframe.rb
index e77e85045d..6595398427 100644
--- a/ext/tk/lib/tkextlib/iwidgets/labeledframe.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/labeledframe.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Labeledframe
TkCommandNames = ['::iwidgets::labeledframe'.freeze].freeze
WidgetClassName = 'Labeledframe'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'labeltext'
diff --git a/ext/tk/lib/tkextlib/iwidgets/labeledwidget.rb b/ext/tk/lib/tkextlib/iwidgets/labeledwidget.rb
index 99387710cb..d36d42878d 100644
--- a/ext/tk/lib/tkextlib/iwidgets/labeledwidget.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/labeledwidget.rb
@@ -18,7 +18,7 @@ class Tk::Iwidgets::Labeledwidget
TkCommandNames = ['::iwidgets::labeledwidget'.freeze].freeze
WidgetClassName = 'Labeledwidget'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'labeltext'
diff --git a/ext/tk/lib/tkextlib/iwidgets/mainwindow.rb b/ext/tk/lib/tkextlib/iwidgets/mainwindow.rb
index 4b2541b997..ebf48021db 100644
--- a/ext/tk/lib/tkextlib/iwidgets/mainwindow.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/mainwindow.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Mainwindow
TkCommandNames = ['::iwidgets::mainwindow'.freeze].freeze
WidgetClassName = 'Mainwindow'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'helpline' << 'statusline'
diff --git a/ext/tk/lib/tkextlib/iwidgets/menubar.rb b/ext/tk/lib/tkextlib/iwidgets/menubar.rb
index 5aaefbe50d..f9a17d0b55 100644
--- a/ext/tk/lib/tkextlib/iwidgets/menubar.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/menubar.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Menubar
TkCommandNames = ['::iwidgets::menubar'.freeze].freeze
WidgetClassName = 'Menubar'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'menubuttons'
@@ -61,13 +61,14 @@ class Tk::Iwidgets::Menubar
end
end
+ alias menucget_tkstring itemcget_tkstring
alias menucget itemcget
alias menucget_strict itemcget_strict
alias menuconfigure itemconfigure
alias menuconfiginfo itemconfiginfo
alias current_menuconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/messagebox.rb b/ext/tk/lib/tkextlib/iwidgets/messagebox.rb
index 98ac32900c..6adb53d941 100644
--- a/ext/tk/lib/tkextlib/iwidgets/messagebox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/messagebox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Messagebox
TkCommandNames = ['::iwidgets::messagebox'.freeze].freeze
WidgetClassName = 'Messagebox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
@@ -46,13 +46,14 @@ class Tk::Iwidgets::Messagebox
end
private :__item_boolval_optkeys
+ alias typecget_tkstring itemcget_tkstring
alias typecget itemcget
alias typecget_strict itemcget_strict
alias typeconfigure itemconfigure
alias typeconfiginfo itemconfiginfo
alias current_typeconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/messagedialog.rb b/ext/tk/lib/tkextlib/iwidgets/messagedialog.rb
index c19b83e517..9aa590056f 100644
--- a/ext/tk/lib/tkextlib/iwidgets/messagedialog.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/messagedialog.rb
@@ -16,5 +16,5 @@ end
class Tk::Iwidgets::Messagedialog
TkCommandNames = ['::iwidgets::messagedialog'.freeze].freeze
WidgetClassName = 'Messagedialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
end
diff --git a/ext/tk/lib/tkextlib/iwidgets/notebook.rb b/ext/tk/lib/tkextlib/iwidgets/notebook.rb
index 03b50633df..7ed4126a4d 100644
--- a/ext/tk/lib/tkextlib/iwidgets/notebook.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/notebook.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Notebook
TkCommandNames = ['::iwidgets::notebook'.freeze].freeze
WidgetClassName = 'Notebook'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
@@ -41,13 +41,14 @@ class Tk::Iwidgets::Notebook
end
end
+ alias pagecget_tkstring itemcget_tkstring
alias pagecget itemcget
alias pagecget_strict itemcget_strict
alias pageconfigure itemconfigure
alias pageconfiginfo itemconfiginfo
alias current_pageconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/optionmenu.rb b/ext/tk/lib/tkextlib/iwidgets/optionmenu.rb
index 0c74440be7..57a3cc7d2b 100644
--- a/ext/tk/lib/tkextlib/iwidgets/optionmenu.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/optionmenu.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Optionmenu
TkCommandNames = ['::iwidgets::optionmenu'.freeze].freeze
WidgetClassName = 'Optionmenu'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'cyclicon'
diff --git a/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb b/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb
index 3bf73d69fe..65463cc85a 100644
--- a/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Panedwindow
TkCommandNames = ['::iwidgets::panedwindow'.freeze].freeze
WidgetClassName = 'Panedwindow'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
@@ -41,13 +41,14 @@ class Tk::Iwidgets::Panedwindow
end
end
+ alias panecget_tkstring itemcget_tkstring
alias panecget itemcget
alias panecget_strict itemcget_strict
alias paneconfigure itemconfigure
alias paneconfiginfo itemconfiginfo
alias current_paneconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/promptdialog.rb b/ext/tk/lib/tkextlib/iwidgets/promptdialog.rb
index 620b14b5d5..7c7ff7ad62 100644
--- a/ext/tk/lib/tkextlib/iwidgets/promptdialog.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/promptdialog.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Promptdialog
TkCommandNames = ['::iwidgets::promptdialog'.freeze].freeze
WidgetClassName = 'Promptdialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
# index method is not available, because it shows index of the entry field
def default(name)
diff --git a/ext/tk/lib/tkextlib/iwidgets/pushbutton.rb b/ext/tk/lib/tkextlib/iwidgets/pushbutton.rb
index c21007ca6c..ae56788289 100644
--- a/ext/tk/lib/tkextlib/iwidgets/pushbutton.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/pushbutton.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Pushbutton
TkCommandNames = ['::iwidgets::pushbutton'.freeze].freeze
WidgetClassName = 'Pushbutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'defaultring'
diff --git a/ext/tk/lib/tkextlib/iwidgets/radiobox.rb b/ext/tk/lib/tkextlib/iwidgets/radiobox.rb
index e9d9521252..21181777b5 100644
--- a/ext/tk/lib/tkextlib/iwidgets/radiobox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/radiobox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Radiobox
TkCommandNames = ['::iwidgets::radiobox'.freeze].freeze
WidgetClassName = 'Radiobox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
@@ -46,13 +46,14 @@ class Tk::Iwidgets::Radiobox
end
end
+ alias buttoncget_tkstring itemcget_tkstring
alias buttoncget itemcget
alias buttoncget_strict itemcget_strict
alias buttonconfigure itemconfigure
alias buttonconfiginfo itemconfiginfo
alias current_buttonconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/scopedobject.rb b/ext/tk/lib/tkextlib/iwidgets/scopedobject.rb
index bddef50841..056cd85322 100644
--- a/ext/tk/lib/tkextlib/iwidgets/scopedobject.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/scopedobject.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Scopedobject
TkCommandNames = ['::iwidgets::scopedobject'.freeze].freeze
WidgetClassName = 'Scopedobject'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def initialize(obj_name, keys={})
@path = tk_call(self.class::TkCommandNames[0], obj_name, *hash_kv(keys))
diff --git a/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb b/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb
index 42368f5a56..935e04bbcc 100644
--- a/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/scrolledcanvas.rb
@@ -17,7 +17,7 @@ end
class Tk::Iwidgets::Scrolledcanvas
TkCommandNames = ['::iwidgets::scrolledcanvas'.freeze].freeze
WidgetClassName = 'Scrolledcanvas'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/scrolledframe.rb b/ext/tk/lib/tkextlib/iwidgets/scrolledframe.rb
index 8b47460357..7b7b95df1c 100644
--- a/ext/tk/lib/tkextlib/iwidgets/scrolledframe.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/scrolledframe.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Scrolledframe
TkCommandNames = ['::iwidgets::scrolledframe'.freeze].freeze
WidgetClassName = 'Scrolledframe'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def child_site
window(tk_call(@path, 'childsite'))
diff --git a/ext/tk/lib/tkextlib/iwidgets/scrolledhtml.rb b/ext/tk/lib/tkextlib/iwidgets/scrolledhtml.rb
index 9b69ef07fe..dc2966bd48 100644
--- a/ext/tk/lib/tkextlib/iwidgets/scrolledhtml.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/scrolledhtml.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Scrolledhtml
TkCommandNames = ['::iwidgets::scrolledhtml'.freeze].freeze
WidgetClassName = 'Scrolledhtml'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'update'
diff --git a/ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb b/ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb
index 7e63633a1d..20a4cd1d36 100644
--- a/ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/scrolledlistbox.rb
@@ -17,7 +17,7 @@ end
class Tk::Iwidgets::Scrolledlistbox
TkCommandNames = ['::iwidgets::scrolledlistbox'.freeze].freeze
WidgetClassName = 'Scrolledlistbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'textbackground'
diff --git a/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb b/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb
index 674298ff80..69b7d314fd 100644
--- a/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb
@@ -17,7 +17,7 @@ end
class Tk::Iwidgets::Scrolledtext
TkCommandNames = ['::iwidgets::scrolledtext'.freeze].freeze
WidgetClassName = 'Scrolledtext'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'textbackground'
@@ -116,6 +116,10 @@ class Tk::Iwidgets::Scrolledtext
get('-displaychars', *index)
end
+ def image_cget_tkstring(index, slot)
+ _fromUTF8(tk_send_without_enc('image', 'cget',
+ _get_eval_enc_str(index), "-#{slot.to_s}"))
+ end
def image_cget_strict(index, slot)
case slot.to_s
when 'text', 'label', 'show', 'data', 'file'
diff --git a/ext/tk/lib/tkextlib/iwidgets/scrolledwidget.rb b/ext/tk/lib/tkextlib/iwidgets/scrolledwidget.rb
index eef093d314..5ecd2d72d2 100644
--- a/ext/tk/lib/tkextlib/iwidgets/scrolledwidget.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/scrolledwidget.rb
@@ -16,5 +16,5 @@ end
class Tk::Iwidgets::Scrolledwidget
TkCommandNames = ['::iwidgets::scrolledwidget'.freeze].freeze
WidgetClassName = 'Scrolledwidget'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
end
diff --git a/ext/tk/lib/tkextlib/iwidgets/selectionbox.rb b/ext/tk/lib/tkextlib/iwidgets/selectionbox.rb
index bf9b5ec30a..eb8fe3ad52 100644
--- a/ext/tk/lib/tkextlib/iwidgets/selectionbox.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/selectionbox.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Selectionbox
TkCommandNames = ['::iwidgets::selectionbox'.freeze].freeze
WidgetClassName = 'Selectionbox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'itemson' << 'selectionon'
diff --git a/ext/tk/lib/tkextlib/iwidgets/selectiondialog.rb b/ext/tk/lib/tkextlib/iwidgets/selectiondialog.rb
index f772ecf8c2..45aecf3266 100644
--- a/ext/tk/lib/tkextlib/iwidgets/selectiondialog.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/selectiondialog.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Selectiondialog
TkCommandNames = ['::iwidgets::selectiondialog'.freeze].freeze
WidgetClassName = 'Selectiondialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def child_site
window(tk_call(@path, 'childsite'))
diff --git a/ext/tk/lib/tkextlib/iwidgets/shell.rb b/ext/tk/lib/tkextlib/iwidgets/shell.rb
index dabf2e6f25..c560e3ac29 100644
--- a/ext/tk/lib/tkextlib/iwidgets/shell.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/shell.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Shell
TkCommandNames = ['::iwidgets::shell'.freeze].freeze
WidgetClassName = 'Shell'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def activate
tk_call(@path, 'activate') # may return val of deactibate method
diff --git a/ext/tk/lib/tkextlib/iwidgets/spindate.rb b/ext/tk/lib/tkextlib/iwidgets/spindate.rb
index 2c98eb4629..b3de9ed989 100644
--- a/ext/tk/lib/tkextlib/iwidgets/spindate.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/spindate.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Spindate
TkCommandNames = ['::iwidgets::spindate'.freeze].freeze
WidgetClassName = 'Spindate'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'dayon' << 'monthon' << 'yearon'
diff --git a/ext/tk/lib/tkextlib/iwidgets/spinint.rb b/ext/tk/lib/tkextlib/iwidgets/spinint.rb
index 5eb944d081..bede3bb1bf 100644
--- a/ext/tk/lib/tkextlib/iwidgets/spinint.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/spinint.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Spinint
TkCommandNames = ['::iwidgets::spinint'.freeze].freeze
WidgetClassName = 'Spinint'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'wrap'
diff --git a/ext/tk/lib/tkextlib/iwidgets/spinner.rb b/ext/tk/lib/tkextlib/iwidgets/spinner.rb
index f2d9caae21..d960996e22 100644
--- a/ext/tk/lib/tkextlib/iwidgets/spinner.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/spinner.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Spinner
TkCommandNames = ['::iwidgets::spinner'.freeze].freeze
WidgetClassName = 'Spinner'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/spintime.rb b/ext/tk/lib/tkextlib/iwidgets/spintime.rb
index 0ff683ab56..20f8197a09 100644
--- a/ext/tk/lib/tkextlib/iwidgets/spintime.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/spintime.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Spintime
TkCommandNames = ['::iwidgets::spintime'.freeze].freeze
WidgetClassName = 'Spintime'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'houron' << 'militaryon' << 'minutelabel' << 'secondlabel'
diff --git a/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb b/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb
index dbb90e5102..f56efa9aaf 100644
--- a/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Tabnotebook
TkCommandNames = ['::iwidgets::tabnotebook'.freeze].freeze
WidgetClassName = 'Tabnotebook'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
@@ -46,13 +46,14 @@ class Tk::Iwidgets::Tabnotebook
end
end
+ alias pagecget_tkstring itemcget_tkstring
alias pagecget itemcget
alias pagecget_strict itemcget_strict
alias pageconfigure itemconfigure
alias pageconfiginfo itemconfiginfo
alias current_pageconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/tabset.rb b/ext/tk/lib/tkextlib/iwidgets/tabset.rb
index c1a1b29268..501ead4964 100644
--- a/ext/tk/lib/tkextlib/iwidgets/tabset.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/tabset.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Tabset
TkCommandNames = ['::iwidgets::tabset'.freeze].freeze
WidgetClassName = 'Tabset'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
####################################
@@ -41,13 +41,14 @@ class Tk::Iwidgets::Tabset
end
end
+ alias tabcget_tkstring itemcget_tkstring
alias tabcget itemcget
alias tabcget_strict itemcget_strict
alias tabconfigure itemconfigure
alias tabconfiginfo itemconfiginfo
alias current_tabconfiginfo current_itemconfiginfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
####################################
diff --git a/ext/tk/lib/tkextlib/iwidgets/timeentry.rb b/ext/tk/lib/tkextlib/iwidgets/timeentry.rb
index 588da77dc8..b0afb3afd9 100644
--- a/ext/tk/lib/tkextlib/iwidgets/timeentry.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/timeentry.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Timeentry
TkCommandNames = ['::iwidgets::timeentry'.freeze].freeze
WidgetClassName = 'Timeentry'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __strval_optkeys
super() << 'closetext'
diff --git a/ext/tk/lib/tkextlib/iwidgets/timefield.rb b/ext/tk/lib/tkextlib/iwidgets/timefield.rb
index 28e1504797..c34281d4ff 100644
--- a/ext/tk/lib/tkextlib/iwidgets/timefield.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/timefield.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Timefield
TkCommandNames = ['::iwidgets::timefield'.freeze].freeze
WidgetClassName = 'Timefield'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'gmt'
diff --git a/ext/tk/lib/tkextlib/iwidgets/toolbar.rb b/ext/tk/lib/tkextlib/iwidgets/toolbar.rb
index c9f1753c70..5b474c3816 100644
--- a/ext/tk/lib/tkextlib/iwidgets/toolbar.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/toolbar.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Toolbar
TkCommandNames = ['::iwidgets::toolbar'.freeze].freeze
WidgetClassName = 'Toolbar'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __tkvariable_optkeys
super() << 'helpvariable'
diff --git a/ext/tk/lib/tkextlib/iwidgets/watch.rb b/ext/tk/lib/tkextlib/iwidgets/watch.rb
index dd96d4f953..f10ec54cb2 100644
--- a/ext/tk/lib/tkextlib/iwidgets/watch.rb
+++ b/ext/tk/lib/tkextlib/iwidgets/watch.rb
@@ -16,7 +16,7 @@ end
class Tk::Iwidgets::Watch
TkCommandNames = ['::iwidgets::watch'.freeze].freeze
WidgetClassName = 'Watch'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'showampm'
diff --git a/ext/tk/lib/tkextlib/tcllib.rb b/ext/tk/lib/tkextlib/tcllib.rb
index c6138f4275..2831989759 100644
--- a/ext/tk/lib/tkextlib/tcllib.rb
+++ b/ext/tk/lib/tkextlib/tcllib.rb
@@ -42,19 +42,25 @@ module Tk
module Tcllib
TkComm::TkExtlibAutoloadModule.unshift(self)
+ # package:: autoscroll
+ autoload :Autoscroll, 'tkextlib/tcllib/autoscroll'
+
# package:: ctext
autoload :CText, 'tkextlib/tcllib/ctext'
+ # package:: cursor
+ autoload :Cursor, 'tkextlib/tcllib/cursor'
+
+ # package:: datefield
+ autoload :Datefield, 'tkextlib/tcllib/datefield'
+ autoload :DateField, 'tkextlib/tcllib/datefield'
+
# package:: getstring
autoload :GetString_Dialog, 'tkextlib/tcllib/getstring'
# package:: history
autoload :History, 'tkextlib/tcllib/history'
- # package:: datefield
- autoload :Datefield, 'tkextlib/tcllib/datefield'
- autoload :DateField, 'tkextlib/tcllib/datefield'
-
# package:: ico
autoload :ICO, 'tkextlib/tcllib/ico'
@@ -62,12 +68,21 @@ module Tk
autoload :IP_Entry, 'tkextlib/tcllib/ip_entry'
autoload :IPEntry, 'tkextlib/tcllib/ip_entry'
- # package:: swaplist
- autoload :Swaplist_Dialog, 'tkextlib/tcllib/swaplist'
+ # package:: khim
+ autoload :KHIM, 'tkextlib/tcllib/khim'
+
+ # package:: ntext
+ autoload :Ntext, 'tkextlib/tcllib/ntext'
# package:: Plotchart
autoload :Plotchart, 'tkextlib/tcllib/plotchart'
+ # package:: style
+ autoload :Style, 'tkextlib/tcllib/style'
+
+ # package:: swaplist
+ autoload :Swaplist_Dialog, 'tkextlib/tcllib/swaplist'
+
# package:: tablelist
autoload :Tablelist, 'tkextlib/tcllib/tablelist'
autoload :TableList, 'tkextlib/tcllib/tablelist'
@@ -81,7 +96,7 @@ module Tk
autoload :Tooltip, 'tkextlib/tcllib/tooltip'
# package:: widget
- autoload :Wdiget, 'tkextlib/tcllib/widget'
+ autoload :Widget, 'tkextlib/tcllib/widget'
end
end
diff --git a/ext/tk/lib/tkextlib/tcllib/calendar.rb b/ext/tk/lib/tkextlib/tcllib/calendar.rb
new file mode 100644
index 0000000000..b6843df176
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/calendar.rb
@@ -0,0 +1,55 @@
+#
+# tkextlib/tcllib/calendar.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * calendar widget
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('widget::calendar', '0.9')
+TkPackage.require('widget::calendar')
+
+module Tk::Tcllib
+ module Widget
+ class Calendar < TkCanvas
+ PACKAGE_NAME = 'widget::calendar'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('widget::calendar')
+ rescue
+ ''
+ end
+ end
+ end
+ end
+end
+
+class Tk::Tcllib::Widget::Calendar
+ TkCommandNames = ['::widget::calendar'.freeze].freeze
+
+ def __boolval_optkeys
+ super() << 'showpast'
+ end
+ private :__boolval_optkeys
+
+ def create_self(keys)
+ if keys and keys != None
+ tk_call_without_enc(self.class::TkCommandNames[0], @path,
+ *hash_kv(keys, true))
+ else
+ tk_call_without_enc(self.class::TkCommandNames[0], @path)
+ end
+ end
+ private :create_self
+
+ def get(what = 'all')
+ tk_send('get', what)
+ end
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/canvas_sqmap.rb b/ext/tk/lib/tkextlib/tcllib/canvas_sqmap.rb
new file mode 100644
index 0000000000..0bd59511c1
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/canvas_sqmap.rb
@@ -0,0 +1,36 @@
+#
+# tkextlib/tcllib/canvas.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# *
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('widget::canvas_sqmap', '0.2')
+TkPackage.require('widget::canvas_sqmap')
+
+module Tk::Tcllib
+ module Widget
+ class Canvas_Sqmap < Canvas
+ TkCommandNames = ['::widget::canvas_sqmap'.freeze].freeze
+
+ def image_set(cell, img)
+ tk_send('image', 'set', cell, img)
+ self
+ end
+
+ def image_unset(cell)
+ tk_send('image', 'unset', cell)
+ self
+ end
+
+ def flush
+ tk_send('flush')
+ self
+ end
+ end
+ end
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/canvas_zoom.rb b/ext/tk/lib/tkextlib/tcllib/canvas_zoom.rb
new file mode 100644
index 0000000000..e2a5061112
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/canvas_zoom.rb
@@ -0,0 +1,21 @@
+#
+# tkextlib/tcllib/canvas.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# *
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('widget::canvas_zoom', '0.1')
+TkPackage.require('widget::canvas_zoom')
+
+module Tk::Tcllib
+ module Widget
+ class Canvas_Zoom < Canvas
+ TkCommandNames = ['::widget::canvas_zoom'.freeze].freeze
+ end
+ end
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/chatwidget.rb b/ext/tk/lib/tkextlib/tcllib/chatwidget.rb
new file mode 100644
index 0000000000..860b9e899b
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/chatwidget.rb
@@ -0,0 +1,151 @@
+#
+# tkextlib/tcllib/chatwidget.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * chatwidget - Provides a multi-paned view suitable for display of
+# chat room or irc channel information
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('chatwidget', '1.1.0')
+TkPackage.require('chatwidget')
+
+module Tk::Tcllib
+ class ChatWidget < TkText
+ PACKAGE_NAME = 'chatwidget'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('chatwidget')
+ rescue
+ ''
+ end
+ end
+ end
+end
+
+class Tk::Tcllib::ChatWidget
+ TkCommandNames = ['::chatwidget::chatwidget'.freeze].freeze
+
+ def show_topic
+ tk_send_without_enc('topic', 'show')
+ self
+ end
+
+ def hide_topic
+ tk_send_without_enc('topic', 'hide')
+ self
+ end
+
+ def set_topic(topic)
+ tk_send('topic', 'set', topic)
+ end
+
+ def list_name
+ tk_split_simplelist(tk_send('name', 'list'))
+ end
+
+ def list_name_full
+ tk_split_simplelist(tk_send('name', 'list')).map{|lst|
+ nick, *opts = tk_split_simplelist(lst)
+ h_opt = {}
+ opts.slice(2){|k, v| h_opt[k[1..-1]] = tk_tcl2ruby(v)}
+ [nick, h_opt]
+ }
+ end
+
+ def add_name(nick, opts={})
+ tk_send('name', 'add', nick, *(hash_kv(opts)))
+ end
+
+ def delete_name(nick)
+ tk_send('name', 'delete', nick)
+ end
+
+ def get_name(nick)
+ lst = tk_send('name', 'get', nick)
+ return nil if lst.empty?
+ nick, *opts = tk_split_simplelist(lst)
+ h_opt = {}
+ opts.slice(2){|k, v| h_opt[k[1..-1]] = tk_tcl2ruby(v)}
+ [nick, h_opt]
+ end
+
+ def message(msg, opts={})
+ tk_send('message', msg, *(hash_kv(opts)))
+ self
+ end
+
+ def _parse_hook_list(lst)
+ tk_split_simplelist(lst).map{|hook|
+ cmd, prior = tk_split_simplelist(hook)
+ [procedure(cmd), number(prior)]
+ }
+ end
+ private :_parse_hook_list
+
+ def hook_add(type, *args, &blk) # args -> [prior, cmd], [prior], [cmd]
+ #type -> 'message', 'post', 'names_group', 'names_nick', 'chatstate', 'url'
+
+ if prior = args.shift
+ if !prior.kind_of?(Numeric)
+ cmd = prior
+ if (prior = args.shift) && !prior.kind_of?(Numeric) # error
+ args.unshift(prior)
+ end
+ args.unshift(cmd)
+ end
+ prior ||= 50 # default priority
+ end
+
+ cmd = args.shift || blk
+
+ fail ArgumentError, "invalid arguments" unless args.empty?
+ fail ArgumentError, "no callback is given" unless cmd
+
+ _parse_hook_list(tk_send('hook', 'add', type, cmd, prior))
+ end
+
+ def hook_remove(type, cmd)
+ #type -> 'message', 'post', 'names_group', 'names_nick', 'chatstate', 'url'
+ _parse_hook_list(tk_send('hook', 'remove', type, cmd))
+ end
+
+ def hook_run(type, *cmd_args)
+ #type -> 'message', 'post', 'names_group', 'names_nick', 'chatstate', 'url'
+ tk_send('hook', 'run', type, *cmd_args)
+ end
+
+ def hook_list(type)
+ #type -> 'message', 'post', 'names_group', 'names_nick', 'chatstate', 'url'
+ _parse_hook_list(tk_send('hook', 'list', type))
+ end
+
+ def show_names
+ tk_send('names', 'show')
+ self
+ end
+
+ def hide_names
+ tk_send('names', 'hide')
+ self
+ end
+
+ def names_widget
+ window(tk_send('names'))
+ end
+
+ def entry_widget
+ window(tk_send('entry'))
+ end
+
+ def chat_widget
+ window(tk_send('chat'))
+ end
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/crosshair.rb b/ext/tk/lib/tkextlib/tcllib/crosshair.rb
new file mode 100644
index 0000000000..49b5361e4f
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/crosshair.rb
@@ -0,0 +1,117 @@
+#
+# tkextlib/tcllib/crosshair.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * Crosshairs for Tk canvas
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('crosshair', '1.0.2')
+TkPackage.require('crosshair')
+
+module Tk::Tcllib
+ module Crosshair
+ PACKAGE_NAME = 'crosshair'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('crosshair')
+ rescue
+ ''
+ end
+ end
+ end
+end
+
+module Tk::Tcllib::Crosshair
+ include TkCore
+ TkCommandNames = ['::crosshair::crosshair'.freeze].freeze
+
+ def self.crosshair(w, keys={})
+ Tk.tk_call('::crosshair::crosshair', w, *hash_kv(keys))
+ w
+ end
+ def self.on(w, keys={})
+ self.crosshair(w, keys)
+ end
+
+ def self.off(w)
+ Tk.tk_call('::crosshair::off', w)
+ w
+ end
+
+ def self.track_on(w, &b)
+ Tk.tk_call('::crosshair::track_on', w, b)
+ w
+ end
+
+ def self.track_off(w)
+ Tk.tk_call('::crosshair::track_off', w)
+ w
+ end
+end
+
+class << Tk::Tcllib::Crosshair
+ include TkComm
+ include TkCanvasItemConfig
+
+ def __item_methodcall_optkeys(id)
+ {}
+ end
+ private :__item_methodcall_optkeys
+
+ def __item_config_cmd(id)
+ # maybe need to override
+ ['::crosshair::configure', id]
+ end
+ private :__item_config_cmd
+
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
+ private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
+
+ def confugure(w, slot, value=None)
+ itemconfigure(w, slot, value)
+ end
+ def confuginfo(w, slot = nil)
+ itemconfiginfo(w, slot)
+ end
+ def current_configinfo(w, slot = nil)
+ current_itemconfiginfo(w, slot)
+ end
+ def cget(w, slot)
+ current_itemconfiginfo(w, slot).values[0]
+ end
+end
+
+module Tk::Tcllib::Crosshair
+ def crosshair_on(keys={})
+ Tk::Tcllib::Crosshair.on(self, keys)
+ end
+ def crosshair_off
+ Tk::Tcllib::Crosshair.off(self)
+ end
+ def crosshair_track_on(&b)
+ Tk::Tcllib::Crosshair.track_on(self, &b)
+ end
+ def crosshair_track_off
+ Tk::Tcllib::Crosshair.track_off(self)
+ end
+ def crosshair_configure(*args)
+ Tk::Tcllib::Crosshair.configure(self, *args)
+ end
+ def crosshair_configinfo(slot = nil)
+ Tk::Tcllib::Crosshair.configinfo(self, slot)
+ end
+ def crosshair_current_configinfo(slot = nil)
+ Tk::Tcllib::Crosshair.current_configinfo(self, slot)
+ end
+ def crosshair_cget(slot)
+ Tk::Tcllib::Crosshair.cget(self, slot)
+ end
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/ctext.rb b/ext/tk/lib/tkextlib/tcllib/ctext.rb
index 21d6438b48..308847c233 100644
--- a/ext/tk/lib/tkextlib/tcllib/ctext.rb
+++ b/ext/tk/lib/tkextlib/tcllib/ctext.rb
@@ -35,7 +35,7 @@ end
class Tk::Tcllib::CText
TkCommandNames = ['ctext'.freeze].freeze
WidgetClassName = 'Ctext'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
diff --git a/ext/tk/lib/tkextlib/tcllib/dateentry.rb b/ext/tk/lib/tkextlib/tcllib/dateentry.rb
new file mode 100644
index 0000000000..77038d95bc
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/dateentry.rb
@@ -0,0 +1,62 @@
+#
+# tkextlib/tcllib/dateentry.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * dateentry widget
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('widget::dateentry', '0.91')
+TkPackage.require('widget::dateentry')
+
+module Tk::Tcllib
+ module Widget
+ class Dateentry < Tk::Tile::TEntry
+ PACKAGE_NAME = 'widget::dateentry'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('widget::dateentry')
+ rescue
+ ''
+ end
+ end
+ end
+ DateEntry = Dateentry
+ end
+end
+
+class Tk::Tcllib::Widget::Dateentry
+ TkCommandNames = ['::widget::dateentry'.freeze].freeze
+
+ def __strval_optkeys
+ super() << ['dateformat']
+ end
+ private :__strval_optkeys
+
+ def create_self(keys)
+ if keys and keys != None
+ tk_call_without_enc(self.class::TkCommandNames[0], @path,
+ *hash_kv(keys, true))
+ else
+ tk_call_without_enc(self.class::TkCommandNames[0], @path)
+ end
+ end
+ private :create_self
+
+ def post
+ tk_send('post')
+ self
+ end
+
+ def unpost
+ tk_send('unpost')
+ self
+ end
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/diagrams.rb b/ext/tk/lib/tkextlib/tcllib/diagrams.rb
new file mode 100644
index 0000000000..d24ba9d232
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/diagrams.rb
@@ -0,0 +1,224 @@
+#
+# tkextlib/tcllib/diagrams.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * Draw diagrams
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('Diagrams', '0.3')
+TkPackage.require('Diagrams')
+
+module Tk::Tcllib
+ module Diagrams
+ PACKAGE_NAME = 'Diagrams'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('Diagrams')
+ rescue
+ ''
+ end
+ end
+ end
+end
+
+class << Tk::Tcllib::Diagrams
+ include TkCore
+
+ def drawin(canvas)
+ tk_call('::Diagrams::drawin', canvas)
+ canvas
+ end
+ alias draw_in drawin
+
+ def saveps(filename)
+ tk_call('::Diagrams::saveps', filename)
+ filename
+ end
+ alias save_ps saveps
+
+ def direction(dir)
+ tk_call('::Diagrams::direction', dir)
+ dir
+ end
+
+ def currentpos(pos)
+ list(tk_call('::Diagrams::currentpos', pos))
+ end
+ alias current_pos currentpos
+ alias currentpos= currentpos
+ alias current_pos= currentpos
+
+ def getpos(anchor, obj)
+ list(tk_call('::Diagrams::getpos', anchor, obj))
+ end
+ alias get_pos getpos
+
+ def position(x, y)
+ list(tk_call('::Diagrams::position', x, y))
+ end
+
+ def box(text, width=nil, height=nil)
+ if width || height
+ width = '' unless width
+ height = '' unless height
+ list(tk_call('::Diagrams::box', text, width, height))
+ else
+ list(tk_call('::Diagrams::box', text))
+ end
+ end
+
+ def plaintext(text, width=nil, height=nil)
+ if width || height
+ width = '' unless width
+ height = '' unless height
+ list(tk_call('::Diagrams::plaintext', text, width, height))
+ else
+ list(tk_call('::Diagrams::plaintext', text))
+ end
+ end
+
+ def circle(text, radius=nil)
+ if radius
+ list(tk_call('::Diagrams::circle', text, radius))
+ else
+ list(tk_call('::Diagrams::circle', text))
+ end
+ end
+
+ def slanted(text, width=nil, height=nil, angle=nil)
+ if width || height || angle
+ width = '' unless width
+ height = '' unless height
+ if angle
+ list(tk_call('::Diagrams::slanted', text, width, height, angle))
+ else
+ list(tk_call('::Diagrams::slanted', text, width, height))
+ end
+ else
+ list(tk_call('::Diagrams::slanted', text))
+ end
+ end
+
+ def diamond(text, width=nil, height=nil)
+ if width || height
+ width = '' unless width
+ height = '' unless height
+ list(tk_call('::Diagrams::diamond', text, width, height))
+ else
+ list(tk_call('::Diagrams::diamond', text))
+ end
+ end
+
+ def drum(text, width=nil, height=nil)
+ if width || height
+ width = '' unless width
+ height = '' unless height
+ list(tk_call('::Diagrams::drum', text, width, height))
+ else
+ list(tk_call('::Diagrams::drum', text))
+ end
+ end
+
+ def arrow(text=nil, length=nil, head=nil)
+ if length || head
+ text = '' unless text
+ length = '' unless length
+ list(tk_call('::Diagrams::arrow', text, length, head))
+ else
+ if text
+ list(tk_call('::Diagrams::arrow', text))
+ else
+ list(tk_call('::Diagrams::arrow'))
+ end
+ end
+ end
+
+ def line(*args)
+ ary = []
+ args.each{|arg|
+ if arg.kind_of?(Array) && arg.length == 2 # [length, angle]
+ ary.concat arg
+ else # ["POSITION", x, y] or length or angle
+ ary << arg
+ end
+ }
+ list(tk_call('::Diagrams::line', *ary))
+ end
+
+ def bracket(dir, dist, from_pos, to_pos)
+ list(tk_call('::Diagrams::bracket', dir, dist, from_pos, to_pos))
+ end
+
+ def attach(anchor=None)
+ tk_call('::Diagrams::attach', anchor)
+ end
+
+ def color(name=None)
+ tk_call('::Diagrams::color', name)
+ end
+
+ def fillcolor(name=None)
+ tk_call('::Diagrams::fillcolor', name)
+ end
+
+ def textcolor(name=None)
+ tk_call('::Diagrams::textcolor', name)
+ end
+
+ def usegap(mode=None)
+ bool(tk_call('::Diagrams::usegap', mode))
+ end
+ alias use_gap usegap
+
+ def xgap(val=None)
+ number(tk_call('::Diagrams::xgap', val))
+ end
+
+ def ygap(val=None)
+ number(tk_call('::Diagrams::ygap', val))
+ end
+
+ def textfont(fnt=None)
+ tk_call('::Diagrams::textfont', fnt)
+ end
+
+ def linewidth(pixels=None)
+ number(tk_call('::Diagrams::linewidth', pixels))
+ end
+
+ def linestyle(style=None)
+ tk_call('::Diagrams::linestyle', style)
+ end
+
+ def pushstate
+ tk_call('::Diagrams::pushstate')
+ end
+ alias push_state pushstate
+
+ def popstate
+ tk_call('::Diagrams::popstate')
+ end
+ alias pop_state popstate
+
+ def computepos
+ list(tk_call('::Diagrams::computepos'))
+ end
+ alias compute_pos computepos
+
+ def boxcoords(x1, y1, x2, y2)
+ list(tk_call('::Diagrams::boxcoords', x1, y1, x2, y2))
+ end
+
+ def moveobject(obj)
+ list(tk_call('::Diagrams::moveobject', obj))
+ end
+ alias move_object moveobject
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/getstring.rb b/ext/tk/lib/tkextlib/tcllib/getstring.rb
index ab45c9b1ea..48711d3b66 100644
--- a/ext/tk/lib/tkextlib/tcllib/getstring.rb
+++ b/ext/tk/lib/tkextlib/tcllib/getstring.rb
@@ -34,7 +34,7 @@ end
class Tk::Tcllib::GetString_Dialog
TkCommandNames = ['::getstring::tk_getString'.freeze].freeze
WidgetClassName = 'TkSDialog'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.show(*args)
dialog = self.new(*args)
diff --git a/ext/tk/lib/tkextlib/tcllib/ico.rb b/ext/tk/lib/tkextlib/tcllib/ico.rb
index 538f7b5408..36a32c6b09 100644
--- a/ext/tk/lib/tkextlib/tcllib/ico.rb
+++ b/ext/tk/lib/tkextlib/tcllib/ico.rb
@@ -8,7 +8,7 @@
require 'tk'
require 'tk/image'
-require 'tkextlib/tcllib.rb'
+#require 'tkextlib/tcllib.rb'
# TkPackage.require('ico', '0.3')
TkPackage.require('ico')
@@ -38,9 +38,39 @@ class Tk::Tcllib::ICO
*hash_kv(keys, true)))
end
+ def self.icons(file, keys=nil)
+ tk_split_simplelist(tk_call_without_enc('::ico::icons', file,
+ *hash_kv(keys, true))).map{|elem|
+ num_or_str(elem)
+ }
+ end
+
+ def self.get_members(file, name, keys=nil)
+ tk_split_simplelist(tk_call_without_enc('::ico::getMembers', file, name,
+ *hash_kv(keys, true))).map{|elem|
+ name, width, height, bpp = tk_split_simplelist(elem)
+ [name, number(width), number(height), number(bpp)]
+ }
+ end
+
def self.get(file, index, keys=nil)
tk_call_without_enc('::ico::getIcon', file, index, *hash_kv(keys, true))
end
+ def self.get_icon(*args)
+ get(*args)
+ end
+
+ def self.get_by_name(file, name, keys=nil)
+ tk_call_without_enc('::ico::getIconByName', file, name,
+ *hash_kv(keys, true))
+ end
+ def self.get_icon_by_name(*args)
+ get_by_name(*args)
+ end
+
+ def self.get_fileicon(file, keys=nil)
+ tk_call_without_enc('::ico::getFileIcon', file, *hash_kv(keys, true))
+ end
def self.get_image(file, index, keys={})
keys = _symbolkey2str(keys)
diff --git a/ext/tk/lib/tkextlib/tcllib/ip_entry.rb b/ext/tk/lib/tkextlib/tcllib/ip_entry.rb
index a8a33f1cad..e5e0f8d42d 100644
--- a/ext/tk/lib/tkextlib/tcllib/ip_entry.rb
+++ b/ext/tk/lib/tkextlib/tcllib/ip_entry.rb
@@ -33,13 +33,18 @@ module Tk
end
end
IPEntry = IP_Entry
+
+ class IP_Entry6 < IP_Entry
+ end
+ IPEntry6 = IP_Entry6
+ IP6_Entry = IP_Entry6
end
end
class Tk::Tcllib::IP_Entry
TkCommandNames = ['::ipentry::ipentry'.freeze].freeze
WidgetClassName = 'IPEntry'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
@@ -64,3 +69,7 @@ class Tk::Tcllib::IP_Entry
tk_send_without_enc('insert', array2tk_list(ip.flatten))
end
end
+
+class Tk::Tcllib::IP_Entry6 < Tk::Tcllib::IP_Entry
+ TkCommandNames = ['::ipentry::ipentry6'.freeze].freeze
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/khim.rb b/ext/tk/lib/tkextlib/tcllib/khim.rb
new file mode 100644
index 0000000000..00acff91d9
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/khim.rb
@@ -0,0 +1,68 @@
+#
+# tkextlib/tcllib/khim.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * Kevin's Hacky Input Method
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('khim', '1.0')
+TkPackage.require('khim')
+
+module Tk::Tcllib
+ class KHIM < TkToplevel
+ PACKAGE_NAME = 'khim'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('khim')
+ rescue
+ ''
+ end
+ end
+ end
+end
+
+class Tk::Tcllib::KHIM
+ TkCommandNames = ['::khim::getOptions'.freeze].freeze
+
+ def self.get_options(parent='')
+ path = parent + '.tcllib_widget_khim_dialog'
+ self.new(:widgetname => path)
+ end
+
+ def self.get_config #=> cmd_string
+ Tk.tk_call_without_enc('::khim::getConfig')
+ end
+
+ def self.set_config(*args)
+ if args.length == 1
+ # cmd_string generated by
+ #Tk.ip_eval_without_enc(cmd_string)
+ Tk.ip_eval(cmd_string)
+ else
+ # args for setConfig command
+ #Tk.tk_call_without_enc('::khim::setConfig', *args)
+ Tk.tk_call('::khim::setConfig', *args)
+ end
+ end
+
+ def self.showHelp
+ Tk::Tcllib::KHIM::Help.new
+ end
+
+ def create_self(keys=None)
+ @db_class = @classname = nil
+ super(None) # ignore keys
+ end
+end
+
+class Tk::Tcllib::KHIM::Help < TkToplevel
+ TkCommandNames = ['::khim::showHelp'.freeze].freeze
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/menuentry.rb b/ext/tk/lib/tkextlib/tcllib/menuentry.rb
new file mode 100644
index 0000000000..f1eb2f295c
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/menuentry.rb
@@ -0,0 +1,47 @@
+#
+# tkextlib/tcllib/menuentry.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * menuentry widget
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('widget::menuentry', '1.0')
+TkPackage.require('widget::menuentry')
+
+module Tk::Tcllib
+ module Widget
+ class Menuentry < Tk::Tile::TEntry
+ PACKAGE_NAME = 'widget::menuentry'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('widget::menuentry')
+ rescue
+ ''
+ end
+ end
+ end
+ MenuEntry = Menuentry
+ end
+end
+
+class Tk::Tcllib::Widget::Menuentry
+ TkCommandNames = ['::widget::menuentry'.freeze].freeze
+
+ def create_self(keys)
+ if keys and keys != None
+ tk_call_without_enc(self.class::TkCommandNames[0], @path,
+ *hash_kv(keys, true))
+ else
+ tk_call_without_enc(self.class::TkCommandNames[0], @path)
+ end
+ end
+ private :create_self
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/ntext.rb b/ext/tk/lib/tkextlib/tcllib/ntext.rb
new file mode 100644
index 0000000000..7888ed4871
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/ntext.rb
@@ -0,0 +1,146 @@
+#
+# tkextlib/tcllib/ntext.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * Ntext bindtag
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('ntext', '0.81')
+TkPackage.require('ntext')
+
+module Tk::Tcllib
+ Ntext = TkBindTag.new_by_name('Ntext')
+end
+
+# variables
+Tk::Tcllib::Ntext.instance_eval{
+ # boolean
+ @classicAnchor = TkVarAccess.new('::ntext::classicAnchor')
+ @classicExtras = TkVarAccess.new('::ntext::classicExtras')
+ @classicMouseSelect = TkVarAccess.new('::ntext::classicMouseSelect')
+ @classicWordBreak = TkVarAccess.new('::ntext::classicWordBreak')
+ @classicWrap = TkVarAccess.new('::ntext::classicWrap')
+ @overwrite = TkVarAccess.new('::ntext::overwrite')
+
+ # regexp
+ @newWrapRegexp = TkVarAccess.new('::ntext::newWrapRegexp')
+
+ # variables (advanced use)
+ @tcl_match_wordBreakAfter = TkVarAccess.new('::ntext::tcl_match_wordBreakAfter')
+ @tcl_match_wordBreakBefore = TkVarAccess.new('::ntext::tcl_match_wordBreakBefore')
+ @tcl_match_endOfWord = TkVarAccess.new('::ntext::tcl_match_endOfWord')
+ @tcl_match_startOfNextWord = TkVarAccess.new('::ntext::tcl_match_startOfNextWord')
+ @tcl_match_startOfPreviousWord = TkVarAccess.new('::ntext::tcl_match_startOfPreviousWord')
+}
+
+class << Tk::Tcllib::Ntext
+ def wrapIndent(txt, *args)
+ TK.tk_call('::next::wrapIndent', txt, *args)
+ end
+
+ def initializeMatchPatterns
+ TK.tk_call('::next::initializeMatchPatterns')
+ self
+ end
+
+ def createMatchPatterns(*args)
+ TK.tk_call('::next::createMatchPatterns', *args)
+ self
+ end
+
+ # functions (advanced use)
+ #ntext::new_wordBreakAfter
+ #ntext::new_wordBreakBefore
+ #ntext::new_endOfWord
+ #ntext::new_startOfNextWord
+ #ntext::new_startOfPreviousWord
+
+ # accessor
+ def classicAnchor
+ @classicAnchor.bool
+ end
+ def classicAnchor=(mode)
+ @classicAnchor.bool = mode
+ end
+
+ def classicExtras
+ @classicExtras.bool
+ end
+ def classicExtras=(mode)
+ @classicExtras.bool = mode
+ end
+
+ def classicMouseSelect
+ @classicMouseSelect.bool
+ end
+ def classicMouseSelect=(mode)
+ @classicMouseSelect.bool = mode
+ end
+
+ def classicWordBreak
+ @classicWordBreak.bool
+ end
+ def classicWordBreak=(mode)
+ @classicWordBreak.bool = mode
+ end
+
+ def classicWrap
+ @classicWrap.bool
+ end
+ def classicWrap=(mode)
+ @classicWrap.bool = mode
+ end
+
+ def overwrite
+ @overwrite.bool
+ end
+ def overwrite=(mode)
+ @classic.bool = mode
+ end
+
+ def newWrapRegexp
+ @newWrapRegexp.value
+ end
+ def newWrapRegexp=(val)
+ @newWrapRegexp.value = val
+ end
+
+ def tcl_match_wordBreakAfter
+ @tcl_match_wordBreakAfter.value
+ end
+ def tcl_match_wordBreakAfter=(val)
+ @tcl_match_wordBreakAfter.value = val
+ end
+
+ def tcl_match_wordBreakBefore
+ @tcl_match_wordBreakBefore.value
+ end
+ def tcl_match_wordBreakBefore=(val)
+ @tcl_match_wordBreakBefore.value = val
+ end
+
+ def tcl_match_endOfWord
+ @tcl_match_endOfWord.value
+ end
+ def tcl_match_endOfWord=(val)
+ @tcl_match_endOfWord.value = val
+ end
+
+ def tcl_match_startOfNextWord
+ @tcl_match_startOfNextWord.value
+ end
+ def tcl_match_startOfNextWord=(val)
+ @tcl_match_startOfNextWord.value = val
+ end
+
+ def tcl_match_startOfPreviousWord
+ @tcl_match_startOfPreviousWord.value
+ end
+ def tcl_match_startOfPreviousWord=(val)
+ @tcl_match_startOfPreviousWord.value = val
+ end
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/panelframe.rb b/ext/tk/lib/tkextlib/tcllib/panelframe.rb
index 9086ad78d2..020c51cbd1 100644
--- a/ext/tk/lib/tkextlib/tcllib/panelframe.rb
+++ b/ext/tk/lib/tkextlib/tcllib/panelframe.rb
@@ -60,11 +60,17 @@ class Tk::Tcllib::Widget::PanelFrame
def remove(*wins)
tk_send('remove', *wins)
+ self
end
def remove_destroy(*wins)
tk_send('remove', '-destroy', *wins)
+ self
+ end
+
+ def delete(*wins)
+ tk_send('delete', *wins)
+ self
end
- alias delete remove_destroy
def items
simplelist(tk_send('items')).collect!{|w| window(w)}
diff --git a/ext/tk/lib/tkextlib/tcllib/plotchart.rb b/ext/tk/lib/tkextlib/tcllib/plotchart.rb
index 25a574efbc..6b7a526b75 100644
--- a/ext/tk/lib/tkextlib/tcllib/plotchart.rb
+++ b/ext/tk/lib/tkextlib/tcllib/plotchart.rb
@@ -62,6 +62,7 @@ require 'tkextlib/tcllib.rb'
# TkPackage.require('Plotchart', '0.9')
# TkPackage.require('Plotchart', '1.1')
+# TkPackage.require('Plotchart', '1.6.3')
TkPackage.require('Plotchart')
module Tk
@@ -109,6 +110,29 @@ module Tk::Tcllib::Plotchart
list(tk_call_without_enc('::Plotchart::coords3DToPixel', w.path, x, y, z))
end
+ def self.plotconfig(*args)
+ case args.length
+ when 0, 1, 2
+ # 0: (no args) --> list of chat types
+ # 1: charttype --> list of components
+ # 2: charttype, component --> list of properties
+ simplelist(tk_call('::Plotchart::plotconfig', *args))
+ when 3
+ # 3: charttype, component, property --> current value
+ tk_call('::Plotchart::plotconfig', *args)
+ else
+ # 4: charttype, component, property, value : set new value
+ # 5+: Error on Tcl/Tk
+ tk_call('::Plotchart::plotconfig', *args)
+ nil
+ end
+ end
+
+ def self.plotpack(w, dir, *plots)
+ tk_call_without_enc('::Plotchart::plotpack', w.path, dir, *plots)
+ w
+ end
+
def self.polar_coordinates(w, radmax)
tk_call_without_enc('::Plotchart::polarCoordinates', w.path, radmax)
end
@@ -157,8 +181,7 @@ module Tk::Tcllib::Plotchart
if key.kind_of?(Hash)
tk_call_without_enc(@chart, 'xconfig', *hash_kv(key, true))
else
- tk_call_without_enc(@chart, 'xconfig',
- "-#{key}", _get_eval_enc_str(value))
+ tk_call(@chart, 'xconfig', "-#{key}",value)
end
self
end
@@ -167,13 +190,86 @@ module Tk::Tcllib::Plotchart
if key.kind_of?(Hash)
tk_call_without_enc(@chart, 'yconfig', *hash_kv(key, true))
else
- tk_call_without_enc(@chart, 'yconfig',
- "-#{key}", _get_eval_enc_str(value))
+ tk_call(@chart, 'yconfig', "-#{key}", value)
+ end
+ self
+ end
+
+ def background(part, color_or_image, dir)
+ tk_call_without_enc(@chart, 'background',
+ part, color_or_image, dir)
+ self
+ end
+
+ def xticklines(color=None)
+ tk_call(@chart, 'xticklines', color)
+ self
+ end
+
+ def yticklines(color=None)
+ tk_call(@chart, 'yticklines', color)
+ self
+ end
+
+ def legendconfig(key, value=None)
+ if key.kind_of?(Hash)
+ tk_call_without_enc(@chart, 'legendconfig', *hash_kv(key, true))
+ else
+ tk_call(@chart, 'legendconfig', "-#{key}", value)
+ end
+ self
+ end
+
+ def legend(series, text)
+ tk_call_without_enc(@chart, 'legend',
+ _get_eval_enc_str(series), _get_eval_enc_str(text))
+ self
+ end
+
+ def balloon(*args) # args => (x, y, text, dir) or ([x, y], text, dir)
+ if args[0].kind_of?(Array)
+ # args => ([x, y], text, dir)
+ x, y = args.shift
+ else
+ # args => (x, y, text, dir)
+ x = args.shift
+ y = args.shift
end
+
+ text, dir = args
+
+ tk_call_without_enc(@chart, 'balloon', x, y,
+ _get_eval_enc_str(text), dir)
+ self
+ end
+
+ def balloonconfig(key, value=None)
+ if key.kind_of?(Hash)
+ tk_call_without_enc(@chart, 'balloonconfig', *hash_kv(key, true))
+ else
+ tk_call(@chart, 'balloonconfig', "-#{key}", value)
+ end
+ end
+
+ def plaintext(*args) # args => (x, y, text, dir) or ([x, y], text, dir)
+ if args[0].kind_of?(Array)
+ # args => ([x, y], text, dir)
+ x, y = args.shift
+ else
+ # args => (x, y, text, dir)
+ x = args.shift
+ y = args.shift
+ end
+
+ text, dir = args
+
+ tk_call_without_enc(@chart, 'plaintext', x, y,
+ _get_eval_enc_str(text), dir)
self
end
############################
+
def view_port(*args) # args := pxmin, pymin, pxmax, pymax
tk_call_without_enc('::Plotchart::viewPort', @path, *(args.flatten))
self
@@ -200,6 +296,11 @@ module Tk::Tcllib::Plotchart
list(tk_call_without_enc('::Plotchart::coords3DToPixel', @path, x, y, z))
end
+ def plotpack(dir, *plots)
+ tk_call_without_enc('::Plotchart::plotpack', @path, dir, *plots)
+ self
+ end
+
def polar_coordinates(radmax)
tk_call_without_enc('::Plotchart::polarCoordinates', @path, radmax)
self
@@ -281,27 +382,27 @@ module Tk::Tcllib::Plotchart
vals = array2tk_list(vals) if vals.kind_of?(Array)
clss = array2tk_list(clss) if clss.kind_of?(Array)
- tk_call_without_enc(@chart, 'contourlines', xcrd, ycrd, vals, clss)
+ tk_call(@chart, 'contourlines', xcrd, ycrd, vals, clss)
self
end
- def contourfill(xcrd, ycrd, vals, klasses=None)
+ def contourfill(xcrd, ycrd, vals, clss=None)
xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array)
ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array)
vals = array2tk_list(vals) if vals.kind_of?(Array)
clss = array2tk_list(clss) if clss.kind_of?(Array)
- tk_call_without_enc(@chart, 'contourfill', xcrd, ycrd, vals, clss)
+ tk_call(@chart, 'contourfill', xcrd, ycrd, vals, clss)
self
end
- def contourbox(xcrd, ycrd, vals, klasses=None)
+ def contourbox(xcrd, ycrd, vals, clss=None)
xcrd = array2tk_list(xcrd) if xcrd.kind_of?(Array)
ycrd = array2tk_list(ycrd) if ycrd.kind_of?(Array)
vals = array2tk_list(vals) if vals.kind_of?(Array)
clss = array2tk_list(clss) if clss.kind_of?(Array)
- tk_call_without_enc(@chart, 'contourbox', xcrd, ycrd, vals, clss)
+ tk_call(@chart, 'contourbox', xcrd, ycrd, vals, clss)
self
end
@@ -324,10 +425,70 @@ module Tk::Tcllib::Plotchart
if key.kind_of?(Hash)
tk_call_without_enc(@chart, 'dataconfig', series, *hash_kv(key, true))
else
- tk_call_without_enc(@chart, 'dataconfig', series,
- "-#{key}", _get_eval_enc_str(value))
+ tk_call(@chart, 'dataconfig', series, "-#{key}", value)
end
end
+
+ def rescale(xscale, yscale) # xscale|yscale => [newmin, newmax, newstep]
+ tk_call_without_enc(@chart, 'rescale', xscale, yscale)
+ self
+ end
+
+ def trend(series, xcrd, ycrd)
+ tk_call_without_enc(@chart, 'trend',
+ _get_eval_enc_str(series), xcrd, ycrd)
+ self
+ end
+
+ def rchart(series, xcrd, ycrd)
+ tk_call_without_enc(@chart, 'rchart',
+ _get_eval_enc_str(series), xcrd, ycrd)
+ self
+ end
+
+ def interval(series, xcrd, ymin, ymax, ycenter=None)
+ tk_call(@chart, 'interval', series, xcrd, ymin, ymax, ycenter)
+ self
+ end
+
+ def box_and_whiskers(series, xcrd, ycrd)
+ tk_call_without_enc(@chart, 'box-and-whiskers',
+ _get_eval_enc_str(series), xcrd, ycrd)
+ self
+ end
+ alias box_whiskers box_and_whiskers
+
+ def vectorconfig(series, key, value=None)
+ if key.kind_of?(Hash)
+ tk_call_without_enc(@chart, 'vectorconfig',
+ _get_eval_enc_str(series), *hash_kv(key, true))
+ else
+ tk_call(@chart, 'vectorconfig', series, "-#{key}", value)
+ end
+ self
+ end
+
+ def vector(series, xcrd, ycrd, ucmp, vcmp)
+ tk_call_without_enc(@chart, 'vector', _get_eval_enc_str(series),
+ xcrd, ycrd, ucmp, vcmp)
+ self
+ end
+
+ def dotconfig(series, key, value=None)
+ if key.kind_of?(Hash)
+ tk_call_without_enc(@chart, 'dotconfig',
+ _get_eval_enc_str(series), *hash_kv(key, true))
+ else
+ tk_call(@chart, 'dotconfig', series, "-#{key}", value)
+ end
+ self
+ end
+
+ def dot(series, xcrd, ycrd, value)
+ tk_call_without_enc(@chart, 'dot', _get_eval_enc_str(series),
+ xcrd, ycrd, value)
+ self
+ end
end
############################
@@ -339,6 +500,30 @@ module Tk::Tcllib::Plotchart
end
############################
+ class TXPlot < XYPlot
+ TkCommandNames = [
+ 'canvas'.freeze,
+ '::Plotchart::createTXPlot'.freeze
+ ].freeze
+ end
+
+ ############################
+ class XLogYPlot < XYPlot
+ TkCommandNames = [
+ 'canvas'.freeze,
+ '::Plotchart::createXLogYPlot'.freeze
+ ].freeze
+ end
+
+ ############################
+ class Histogram < XYPlot
+ TkCommandNames = [
+ 'canvas'.freeze,
+ '::Plotchart::createHistgram'.freeze
+ ].freeze
+ end
+
+ ############################
class PolarPlot < Tk::Canvas
include ChartMethod
@@ -389,10 +574,10 @@ module Tk::Tcllib::Plotchart
def dataconfig(series, key, value=None)
if key.kind_of?(Hash)
- tk_call_without_enc(@chart, 'dataconfig', series, *hash_kv(key, true))
+ tk_call_without_enc(@chart, 'dataconfig', _get_eval_enc_str(series),
+ *hash_kv(key, true))
else
- tk_call_without_enc(@chart, 'dataconfig', series,
- "-#{key}", _get_eval_enc_str(value))
+ tk_call(@chart, 'dataconfig', series, "-#{key}", value)
end
end
end
@@ -541,6 +726,15 @@ module Tk::Tcllib::Plotchart
self
end
+ def plot_line(dat, color)
+ # dat has to be provided as a 2 level array.
+ # 1st level contains rows, drawn in y-direction,
+ # and each row is an array whose elements are drawn in x-direction,
+ # for the columns.
+ tk_call_without_enc(@chart, 'plotline', dat, color)
+ self
+ end
+
def plot_data(dat)
# dat has to be provided as a 2 level array.
# 1st level contains rows, drawn in y-direction,
@@ -550,6 +744,15 @@ module Tk::Tcllib::Plotchart
self
end
+ def zconfig(key, value=None)
+ if key.kind_of?(Hash)
+ tk_call_without_enc(@chart, 'zconfig', *hash_kv(key, true))
+ else
+ tk_call(@chart, 'zconfig', "-#{key}", value)
+ end
+ self
+ end
+
def colour(fill, border)
# configure the colours to use for polygon borders and inner area
tk_call_without_enc(@chart, 'colour', fill, border)
@@ -561,6 +764,132 @@ module Tk::Tcllib::Plotchart
end
############################
+ class Barchart3D < Tk::Canvas
+ include ChartMethod
+
+ TkCommandNames = [
+ 'canvas'.freeze,
+ '::Plotchart::create3DBarchart'.freeze
+ ].freeze
+
+ def initialize(*args) # args := ([parent,] yaxis, nobars [, keys])
+ # yaxis := Array of [minimum, maximum, stepsize]
+ # nobars := number of bars
+ if args[0].kind_of?(Array)
+ @yaxis = args.shift
+ @nobars = args.shift
+
+ super(*args) # create canvas widget
+ else
+ parent = args.shift
+
+ @yaxis = args.shift
+ @nobars = args.shift
+
+ if parent.kind_of?(Tk::Canvas)
+ @path = parent.path
+ else
+ super(parent, *args) # create canvas widget
+ end
+ end
+
+ @chart = _create_chart
+ end
+
+ def _create_chart
+ p self.class::TkCommandNames[1] if $DEBUG
+ tk_call_without_enc(self.class::TkCommandNames[1], @path,
+ array2tk_list(@yaxis), @nobars)
+ end
+ private :_create_chart
+
+ def plot(label, yvalue, color)
+ tk_call_without_enc(@chart, 'plot', _get_eval_enc_str(label),
+ _get_eval_enc_str(yvalue), color)
+ self
+ end
+
+ def config(key, value=None)
+ if key.kind_of?(Hash)
+ tk_call_without_enc(@chart, 'config', *hash_kv(key, true))
+ else
+ tk_call(@chart, 'config', "-#{key}", value)
+ end
+ self
+ end
+ end
+
+ ############################
+ class RibbonChart3D < Tk::Canvas
+ include ChartMethod
+
+ TkCommandNames = [
+ 'canvas'.freeze,
+ '::Plotchart::create3DRibbonChart'.freeze
+ ].freeze
+
+ def initialize(*args) # args := ([parent,] names, yaxis, zaxis [, keys])
+ # names := Array of the series
+ # yaxis := Array of [minimum, maximum, stepsize]
+ # zaxis := Array of [minimum, maximum, stepsize]
+ if args[0].kind_of?(Array)
+ @names = args.shift
+ @yaxis = args.shift
+ @zaxis = args.shift
+
+ super(*args) # create canvas widget
+ else
+ parent = args.shift
+
+ @names = args.shift
+ @yaxis = args.shift
+ @zaxis = args.shift
+
+ if parent.kind_of?(Tk::Canvas)
+ @path = parent.path
+ else
+ super(parent, *args) # create canvas widget
+ end
+ end
+
+ @chart = _create_chart
+ end
+
+ def _create_chart
+ p self.class::TkCommandNames[1] if $DEBUG
+ tk_call_without_enc(self.class::TkCommandNames[1], @path,
+ array2tk_list(@names),
+ array2tk_list(@yaxis),
+ array2tk_list(@zaxis))
+ end
+ private :_create_chart
+
+ def line(*args) # xypairs, color
+ color = args.pop # last argument is a color
+ xypairs = TkComm.slice_ary(args.flatten, 2) # regenerate xypairs
+ tk_call_without_enc(@chart, 'line', xypairs, color)
+ self
+ end
+
+ def area(*args) # xypairs, color
+ color = args.pop # last argument is a color
+ xypairs = TkComm.slice_ary(args.flatten, 2) # regenerate xypairs
+ tk_call_without_enc(@chart, 'area', xypairs, color)
+ self
+ end
+
+ def zconfig(key, value=None)
+ if key.kind_of?(Hash)
+ tk_call_without_enc(@chart, 'zconfig', *hash_kv(key, true))
+ else
+ tk_call(@chart, 'zconfig',"-#{key}", value)
+ end
+ self
+ end
+ end
+
+
+ ############################
class Piechart < Tk::Canvas
include ChartMethod
@@ -586,9 +915,76 @@ module Tk::Tcllib::Plotchart
private :_create_chart
def plot(*dat) # argument is a list of [label, value]
- tk_call_without_enc(@chart, 'plot', dat.flatten)
+ tk_call(@chart, 'plot', dat.flatten)
+ self
+ end
+
+ def colours(*list)
+ tk_call_without_enc(@chart, 'colours', *list)
self
end
+ alias colors colours
+ end
+
+
+ ############################
+ class Radialchart < Tk::Canvas
+ include ChartMethod
+
+ TkCommandNames = [
+ 'canvas'.freeze,
+ '::Plotchart::createRadialchart'.freeze
+ ].freeze
+
+ def initialize(*args) # args := ([parent,] names, scale, style [, keys])
+ # radius_data := Array of [maximum_radius, stepsize]
+ if args[0].kind_of?(Array)
+ @names = args.shift
+ @scale = args.shift
+ @style = args.shift
+
+ super(*args) # create canvas widget
+ else
+ parent = args.shift
+
+ @names = args.shift
+ @scale = args.shift
+ @style = args.shift
+
+ if parent.kind_of?(Tk::Canvas)
+ @path = parent.path
+ else
+ super(parent, *args) # create canvas widget
+ end
+ end
+
+ @chart = _create_chart
+ end
+
+ def _create_chart
+ p self.class::TkCommandNames[1] if $DEBUG
+ tk_call_without_enc(self.class::TkCommandNames[1], @path,
+ array2tk_list(@names), @scale, @style)
+ end
+ private :_create_chart
+
+ def __destroy_hook__
+ Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.mutex.synchronize{
+ Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.delete(@path)
+ }
+ end
+
+ def plot(data, color, thickness)
+ tk_call_without_enc(@chart, 'plot', _get_eval_enc_str(data),
+ color, thickness)
+ self
+ end
+
+ def colours(*list)
+ tk_call_without_enc(@chart, 'colours', *list)
+ self
+ end
+ alias colors colours
end
############################
@@ -655,13 +1051,13 @@ module Tk::Tcllib::Plotchart
end
def plot(series, dat, col=None)
- tk_call_without_enc(@chart, 'plot', series, dat, col)
+ tk_call(@chart, 'plot', series, dat, col)
self
end
def colours(*cols)
# set the colours to be used
- tk_call_without_enc(@chart, 'colours', *cols)
+ tk_call(@chart, 'colours', *cols)
self
end
alias colour colours
@@ -678,6 +1074,102 @@ module Tk::Tcllib::Plotchart
end
############################
+ class Boxplot < Tk::Canvas
+ include ChartMethod
+
+ TkCommandNames = [
+ 'canvas'.freeze,
+ '::Plotchart::createBoxplot'.freeze
+ ].freeze
+
+ def initialize(*args) # args := ([parent,] xaxis, ylabels [, keys])
+ # xaxis := Array of [minimum, maximum, stepsize]
+ # yaxis := List of labels for the y-axis
+ if args[0].kind_of?(Array)
+ @xaxis = args.shift
+ @ylabels = args.shift
+
+ super(*args) # create canvas widget
+ else
+ parent = args.shift
+
+ @xaxis = args.shift
+ @ylabels = args.shift
+
+ if parent.kind_of?(Tk::Canvas)
+ @path = parent.path
+ else
+ super(parent, *args) # create canvas widget
+ end
+ end
+
+ @chart = _create_chart
+ end
+
+ def _create_chart
+ p self.class::TkCommandNames[1] if $DEBUG
+ tk_call_without_enc(self.class::TkCommandNames[1], @path,
+ array2tk_list(@xaxis), array2tk_list(@ylabels))
+ end
+ private :_create_chart
+
+ def __destroy_hook__
+ Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.mutex.synchronize{
+ Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.delete(@path)
+ }
+ end
+
+ def plot(label, *values)
+ tk_call(@chart, 'plot', label, values.flatten)
+ self
+ end
+ end
+
+ ############################
+ class RightAxis < Tk::Canvas
+ include ChartMethod
+
+ TkCommandNames = [
+ 'canvas'.freeze,
+ '::Plotchart::createRightAxis'.freeze
+ ].freeze
+
+ def initialize(*args) # args := ([parent,] yaxis [, keys])
+ # yaxis := Array of [minimum, maximum, stepsize]
+ if args[0].kind_of?(Array)
+ @yaxis = args.shift
+
+ super(*args) # create canvas widget
+ else
+ parent = args.shift
+
+ @yaxis = args.shift
+
+ if parent.kind_of?(Tk::Canvas)
+ @path = parent.path
+ else
+ super(parent, *args) # create canvas widget
+ end
+ end
+
+ @chart = _create_chart
+ end
+
+ def _create_chart
+ p self.class::TkCommandNames[1] if $DEBUG
+ tk_call_without_enc(self.class::TkCommandNames[1], @path,
+ array2tk_list(@yaxis))
+ end
+ private :_create_chart
+
+ def __destroy_hook__
+ Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.mutex.synchronize{
+ Tk::Tcllib::Plotchart::PlotSeries::SeriesID_TBL.delete(@path)
+ }
+ end
+ end
+
+ ############################
class Timechart < Tk::Canvas
include ChartMethod
@@ -723,46 +1215,60 @@ module Tk::Tcllib::Plotchart
private :_create_chart
def period(txt, time_begin, time_end, col=None)
- tk_call_without_enc(@chart, 'period', txt, time_begin, time_end, col)
+ tk_call(@chart, 'period', txt, time_begin, time_end, col)
self
end
def milestone(txt, time, col=None)
- tk_call_without_enc(@chart, 'milestone', txt, time, col)
+ tk_call(@chart, 'milestone', txt, time, col)
self
end
def vertline(txt, time)
- tk_call_without_enc(@chart, 'vertline', txt, time)
+ tk_call(@chart, 'vertline', txt, time)
+ self
+ end
+
+ def hscroll=(scr)
+ tk_call_without_enc(@chart, 'hscroll', scr)
+ scr
+ end
+ def hscroll(scr)
+ tk_call_without_enc(@chart, 'hscroll', scr)
+ self
+ end
+
+ def vscroll=(scr)
+ tk_call_without_enc(@chart, 'vscroll', scr)
+ scr
+ end
+ def vscroll(scr)
+ tk_call_without_enc(@chart, 'vscroll', scr)
self
end
end
############################
- class Gnattchart < Tk::Canvas
+ class Ganttchart < Tk::Canvas
include ChartMethod
TkCommandNames = [
'canvas'.freeze,
- '::Plotchart::createGnattchart'.freeze
+ '::Plotchart::createGanttchart'.freeze
].freeze
def initialize(*args)
# args := ([parent,] time_begin, time_end, items [, text_width] [, keys])
# time_begin := String of time format (e.g. "1 january 2004")
# time_end := String of time format (e.g. "1 january 2004")
- # items := Expected/maximum number of items
- # ( This determines the vertical spacing. )
+ # args := Expected/maximum number of items
+ # ( This determines the vertical spacing. ),
+ # Expected/maximum width of items,
+ # Option Hash ( { key=>value, ... } )
if args[0].kind_of?(String)
@time_begin = args.shift
@time_end = args.shift
- @items = args.shift
-
- if args[0].kind_of?(Fixnum)
- @text_width = args.shift
- else
- @text_width = None
- end
+ @args = args
super(*args) # create canvas widget
else
@@ -770,13 +1276,7 @@ module Tk::Tcllib::Plotchart
@time_begin = args.shift
@time_end = args.shift
- @items = args.shift
-
- if args[0].kind_of?(Fixnum)
- @text_width = args.shift
- else
- @text_width = None
- end
+ @args = args
if parent.kind_of?(Tk::Canvas)
@path = parent.path
@@ -790,25 +1290,25 @@ module Tk::Tcllib::Plotchart
def _create_chart
p self.class::TkCommandNames[1] if $DEBUG
- tk_call_without_enc(self.class::TkCommandNames[1], @path,
- @time_begin, @time_end, @items, @text_width)
+ tk_call(self.class::TkCommandNames[1], @path,
+ @time_begin, @time_end, *args)
end
private :_create_chart
def task(txt, time_begin, time_end, completed=0.0)
- list(tk_call_without_enc(@chart, 'task', txt, time_begin, time_end,
- completed)).collect!{|id|
+ list(tk_call(@chart, 'task', txt, time_begin, time_end,
+ completed)).collect!{|id|
TkcItem.id2obj(self, id)
}
end
def milestone(txt, time, col=None)
- tk_call_without_enc(@chart, 'milestone', txt, time, col)
+ tk_call(@chart, 'milestone', txt, time, col)
self
end
def vertline(txt, time)
- tk_call_without_enc(@chart, 'vertline', txt, time)
+ tk_call(@chart, 'vertline', txt, time)
self
end
@@ -816,23 +1316,41 @@ module Tk::Tcllib::Plotchart
from_task = array2tk_list(from_task) if from_task.kind_of?(Array)
to_task = array2tk_list(to_task) if to_task.kind_of?(Array)
- tk_call_without_enc(@chart, 'connect', from_task, to_task)
+ tk_call(@chart, 'connect', from_task, to_task)
self
end
def summary(txt, tasks)
tasks = array2tk_list(tasks) if tasks.kind_of?(Array)
- tk_call_without_enc(@chart, 'summary', tasks)
+ tk_call(@chart, 'summary', tasks)
self
end
def color_of_part(keyword, newcolor)
- tk_call_without_enc(@chart, 'color', keyword, newcolor)
+ tk_call(@chart, 'color', keyword, newcolor)
self
end
def font_of_part(keyword, newfont)
- tk_call_without_enc(@chart, 'font', keyword, newfont)
+ tk_call(@chart, 'font', keyword, newfont)
+ self
+ end
+
+ def hscroll=(scr)
+ tk_call_without_enc(@chart, 'hscroll', scr)
+ scr
+ end
+ def hscroll(scr)
+ tk_call_without_enc(@chart, 'hscroll', scr)
+ self
+ end
+
+ def vscroll=(scr)
+ tk_call_without_enc(@chart, 'vscroll', scr)
+ scr
+ end
+ def vscroll(scr)
+ tk_call_without_enc(@chart, 'vscroll', scr)
self
end
end
@@ -841,7 +1359,7 @@ module Tk::Tcllib::Plotchart
class PlotSeries < TkObject
SeriesID_TBL = TkCore::INTERP.create_table
- (Series_ID = ['series'.freeze, '00000'.taint]).instance_eval{
+ (Series_ID = ['series'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
diff --git a/ext/tk/lib/tkextlib/tcllib/scrolledwindow.rb b/ext/tk/lib/tkextlib/tcllib/scrolledwindow.rb
new file mode 100644
index 0000000000..c9488b4686
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/scrolledwindow.rb
@@ -0,0 +1,57 @@
+#
+# tkextlib/tcllib/scrolledwindow.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * scrolledwindow widget
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('widget::scrolledwindow', '1.2')
+TkPackage.require('widget::scrolledwindow')
+
+module Tk::Tcllib
+ module Widget
+ class Scrolledwindow < Tk::Tile::TFrame
+ PACKAGE_NAME = 'widget::scrolledwindow'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('widget::scrolledwindow')
+ rescue
+ ''
+ end
+ end
+ end
+ ScrolledWindow = Scrolledwindow
+ end
+end
+
+class Tk::Tcllib::Widget::ScrolledWindow
+ TkCommandNames = ['::widget::scrolledwindow'.freeze].freeze
+
+ def create_self(keys)
+ if keys and keys != None
+ tk_call_without_enc(self.class::TkCommandNames[0], @path,
+ *hash_kv(keys, true))
+ else
+ tk_call_without_enc(self.class::TkCommandNames[0], @path)
+ end
+ end
+ private :create_self
+
+ def getframe
+ window(tk_send_without_enc('getframe'))
+ end
+ alias get_frame getframe
+
+ def setwidget(w)
+ window(tk_send_without_enc('setwidget', w))
+ end
+ alias set_widget setwidget
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/statusbar.rb b/ext/tk/lib/tkextlib/tcllib/statusbar.rb
new file mode 100644
index 0000000000..46a4b9d8b6
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/statusbar.rb
@@ -0,0 +1,79 @@
+#
+# tkextlib/tcllib/statusbar.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * statusbar widget
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('widget::statusbar', '1.2')
+TkPackage.require('widget::statusbar')
+
+module Tk::Tcllib
+ module Widget
+ class Statusbar < Tk::Tile::TFrame
+ PACKAGE_NAME = 'widget::statusbar'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('widget::statusbar')
+ rescue
+ ''
+ end
+ end
+ end
+ end
+end
+
+class Tk::Tcllib::Widget::Statusbar
+ TkCommandNames = ['::widget::statusbar'.freeze].freeze
+
+ def __boolval_optkeys
+ super() << 'separator' << 'resize' << 'resizeseparator'
+ end
+ private :__boolval_optkeys
+
+ def create_self(keys)
+ if keys and keys != None
+ tk_call_without_enc(self.class::TkCommandNames[0], @path,
+ *hash_kv(keys, true))
+ else
+ tk_call_without_enc(self.class::TkCommandNames[0], @path)
+ end
+ end
+ private :create_self
+
+ def getframe
+ window(tk_send_without_enc('getframe'))
+ end
+ alias get_frame getframe
+
+ def add(w, keys={})
+ window(tk_send_without_enc('setwidget', *(hash_kv(keys))))
+ end
+
+ def remove(*wins)
+ tk_send_without_enc('remove', *wins)
+ self
+ end
+
+ def remove_with_destroy(*wins)
+ tk_send_without_enc('remove', '-destroy', *wins)
+ self
+ end
+
+ def delete(*wins)
+ tk_send_without_enc('delete', *wins)
+ self
+ end
+
+ def items(pat=None)
+ tk_split_list(tk_send('items', pat))
+ end
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/swaplist.rb b/ext/tk/lib/tkextlib/tcllib/swaplist.rb
index bb4c71cd5f..7698640534 100644
--- a/ext/tk/lib/tkextlib/tcllib/swaplist.rb
+++ b/ext/tk/lib/tkextlib/tcllib/swaplist.rb
@@ -33,7 +33,7 @@ end
class Tk::Tcllib::Swaplist_Dialog
TkCommandNames = ['::swaplist::swaplist'.freeze].freeze
WidgetClassName = 'Swaplist'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.show(*args)
dialog = self.new(*args)
diff --git a/ext/tk/lib/tkextlib/tcllib/tablelist.rb b/ext/tk/lib/tkextlib/tcllib/tablelist.rb
index efeb8fbbac..b40f7a5b8b 100644
--- a/ext/tk/lib/tkextlib/tcllib/tablelist.rb
+++ b/ext/tk/lib/tkextlib/tcllib/tablelist.rb
@@ -10,7 +10,8 @@ require 'tkextlib/tcllib.rb'
# check Tile extension :: If already loaded, use tablelist_tile.
unless defined? Tk::Tcllib::Tablelist_usingTile
- Tk::Tcllib::Tablelist_usingTile = TkPackage.provide('tile')
+ Tk::Tcllib::Tablelist_usingTile =
+ TkPackage.provide('tile') || TkPackage.provide('Ttk')
end
if Tk::Tcllib::Tablelist_usingTile
@@ -20,8 +21,8 @@ if Tk::Tcllib::Tablelist_usingTile
else
# without Tile
- # TkPackage.require('Tablelist', '4.2')
- TkPackage.require('Tablelist')
+ # TkPackage.require('tablelist', '4.2')
+ TkPackage.require('tablelist')
require 'tkextlib/tcllib/tablelist_core'
end
diff --git a/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb b/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb
index c99f62f2dc..850e75d845 100644
--- a/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb
+++ b/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb
@@ -67,6 +67,9 @@ module Tk::Tcllib::TablelistItemConfig
[self.path, mixed_id[0] + 'configure', _to_idx(mixed_id[1])]
end
+ def cell_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['cell', tagOrId], option)
+ end
def cell_cget(tagOrId, option)
itemcget(['cell', tagOrId], option)
end
@@ -82,12 +85,16 @@ module Tk::Tcllib::TablelistItemConfig
def current_cell_configinfo(tagOrId, slot=nil)
current_itemconfiginfo(['cell', tagOrId], slot)
end
+ alias cellcget_tkstring cell_cget_tkstring
alias cellcget cell_cget
alias cellcget_strict cell_cget_strict
alias cellconfigure cell_configure
alias cellconfiginfo cell_configinfo
alias current_cellconfiginfo current_cell_configinfo
+ def column_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['column', tagOrId], option)
+ end
def column_cget(tagOrId, option)
itemcget(['column', tagOrId], option)
end
@@ -103,12 +110,16 @@ module Tk::Tcllib::TablelistItemConfig
def current_column_configinfo(tagOrId, slot=nil)
current_itemconfiginfo(['column', tagOrId], slot)
end
+ alias columncget_tkstring column_cget_tkstring
alias columncget column_cget
alias columncget_strict column_cget_strict
alias columnconfigure column_configure
alias columnconfiginfo column_configinfo
alias current_columnconfiginfo current_column_configinfo
+ def row_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['row', tagOrId], option)
+ end
def row_cget(tagOrId, option)
itemcget(['row', tagOrId], option)
end
@@ -124,13 +135,14 @@ module Tk::Tcllib::TablelistItemConfig
def current_row_configinfo(tagOrId, slot=nil)
current_itemconfiginfo(['row', tagOrId], slot)
end
+ alias rowcget_tkstring row_cget_tkstring
alias rowcget row_cget
alias rowcget_strict row_cget_strict
alias rowconfigure row_configure
alias rowconfiginfo row_configinfo
alias current_rowconfiginfo current_row_configinfo
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
@@ -140,7 +152,7 @@ class Tk::Tcllib::Tablelist
TkCommandNames = ['::tablelist::tablelist'.freeze].freeze
WidgetClassName = 'Tablelist'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
@@ -165,16 +177,16 @@ class Tk::Tcllib::Tablelist
private :__strval_optkeys
def __boolval_optkeys
- super() + [
+ super() - ['takefocus'] + [
'forceeditendcommand', 'movablecolumns', 'movablerows',
- 'protecttitlecolumns', 'resizablecolumns',
+ 'protecttitlecolumns', 'resizablecolumns', 'setfocus',
'showarrow', 'showlabels', 'showseparators'
]
end
private :__boolval_optkeys
def __listval_optkeys
- super() + ['columns']
+ super() + ['columns', 'columntitles']
end
private :__listval_optkeys
@@ -186,7 +198,21 @@ class Tk::Tcllib::Tablelist
def __val2ruby_optkeys # { key=>proc, ... }
# The method is used to convert a opt-value to a ruby's object.
# When get the value of the option "key", "proc.call(value)" is called.
- super().update('stretch'=>proc{|v| (v == 'all')? v: simplelist(v)})
+ super().update('stretch'=>proc{|v|
+ (v == 'all')? v: simplelist(v)
+ },
+ 'takefocus'=>proc{|v|
+ case v
+ when '1'
+ true
+ when '0'
+ false
+ when ''
+ nil
+ else # cmd
+ tk_tcl2ruby(cmd)
+ end
+ })
end
private :__val2ruby_optkeys
@@ -196,6 +222,18 @@ class Tk::Tcllib::Tablelist
# That is, "-#{key} #{proc.call(value)}".
super().update('stretch'=>proc{|v|
(v.kind_of?(Array))? v.collect{|e| _to_idx(e)}: v
+ },
+ 'takefocus'=>proc{|v|
+ case v
+ when true
+ '1'
+ when false
+ '0'
+ when nil
+ ''
+ else
+ _get_eval_string(v)
+ end
})
end
private :__ruby2val_optkeys
@@ -211,14 +249,15 @@ class Tk::Tcllib::Tablelist
if id[0] == 'cell'
super(id) + ['title']
else
- super(id) - ['text'] + ['title']
+ super(id) - ['text'] + ['title', 'name']
end
end
private :__item_strval_optkeys
def __item_boolval_optkeys(id)
super(id) + [
- 'editable', 'hide', 'resizable', 'showarrow', 'stretchable',
+ 'changesnipside', 'editable', 'hide', 'resizable', 'selectable',
+ 'showarrow', 'showlinenumbers', 'stretchable', 'stretchwindow', 'wrap'
]
end
private :__item_boolval_optkeys
@@ -286,6 +325,23 @@ class Tk::Tcllib::Tablelist
end
alias cancelediting cancel_editing
+ def get_cellattrib(name=nil)
+ if name && name != None
+ tk_send('cellattrib', name)
+ else
+ ret = []
+ lst = simplelist(tk_send('cellattrib'))
+ until lst.empty?
+ ret << ( [lst.shift] << lst.shift )
+ end
+ ret
+ end
+ end
+ def set_cellattrib(*args)
+ tk_send('cellattrib', *(args.flatten))
+ self
+ end
+
def cellindex(idx)
_from_idx(tk_send('cellindex', _to_idx(idx)))
end
@@ -321,6 +377,23 @@ class Tk::Tcllib::Tablelist
self
end
+ def get_columnattrib(name=nil)
+ if name && name != None
+ tk_send('columnattrib', name)
+ else
+ ret = []
+ lst = simplelist(tk_send('columnattrib'))
+ until lst.empty?
+ ret << ( [lst.shift] << lst.shift )
+ end
+ ret
+ end
+ end
+ def set_columnattrib(*args)
+ tk_send('columnattrib', *(args.flatten))
+ self
+ end
+
def columncount
number(tk_send('columncount'))
end
@@ -329,6 +402,83 @@ class Tk::Tcllib::Tablelist
number(tk_send('columnindex', _to_idx(idx)))
end
+ def columnwidth(idx, opt=nil)
+ if opt
+ number(tk_send('columnwidth', _to_idx(idx), "-#{opt}"))
+ else
+ number(tk_send('columnwidth', _to_idx(idx)))
+ end
+ end
+ def requested_columnwidth(idx)
+ columnwidth(idx, 'requested')
+ end
+ def stretched_columnwidth(idx)
+ columnwidth(idx, 'stretched')
+ end
+ def total_columnwidth(idx)
+ columnwidth(idx, 'total')
+ end
+
+ def configcelllist(lst) # lst ==> [idx, opt, val, idx, opt, val, ...]
+ ary = []
+ lst.slice(3){|idx, opt, val|
+ ary << _to_idx(idx) << "-#{opt}" << val
+ }
+ tk_send('configcelllist', ary)
+ self
+ end
+ alias config_celllist configcelllist
+
+ def configcells(*args) # args ==> idx, opt, val, idx, opt, val, ...
+ ary = []
+ args.slice(3){|idx, opt, val|
+ ary << _to_idx(idx) << "-#{opt}" << val
+ }
+ tk_send('configcells', *ary)
+ self
+ end
+ alias config_cells configcells
+
+ def configcolumnlist(lst) # lst ==> [idx, opt, val, idx, opt, val, ...]
+ ary = []
+ lst.slice(3){|idx, opt, val|
+ ary << _to_idx(idx) << "-#{opt}" << val
+ }
+ tk_send('configcolumnlist', ary)
+ self
+ end
+ alias config_columnlist configcolumnlist
+
+ def configcolumns(*args) # args ==> idx, opt, val, idx, opt, val, ...
+ ary = []
+ args.slice(3){|idx, opt, val|
+ ary << _to_idx(idx) << "-#{opt}" << val
+ }
+ tk_send('configcolumns', *ary)
+ self
+ end
+ alias config_columns configcolumns
+
+ def configrowlist(lst) # lst ==> [idx, opt, val, idx, opt, val, ...]
+ ary = []
+ lst.slice(3){|idx, opt, val|
+ ary << _to_idx(idx) << "-#{opt}" << val
+ }
+ tk_send('configrowlist', ary)
+ self
+ end
+ alias config_rowlist configrowlist
+
+ def configrows(*args) # args ==> idx, opt, val, idx, opt, val, ...
+ ary = []
+ args.slice(3){|idx, opt, val|
+ ary << _to_idx(idx) << "-#{opt}" << val
+ }
+ tk_send('configrows', *ary)
+ self
+ end
+ alias config_rows configrows
+
def containing(y)
idx = num_or_str(tk_send('containing', y))
(idx.kind_of?(Fixnum) && idx < 0)? nil: idx
@@ -392,6 +542,10 @@ class Tk::Tcllib::Tablelist
end
alias editcell edit_cell
+ def editwintag
+ TkBindTag.new_by_name(tk_send('editwintag'))
+ end
+
def editwinpath
window(tk_send('editwinpath'))
end
@@ -412,6 +566,11 @@ class Tk::Tcllib::Tablelist
end
alias finishediting finish_editing
+ def formatinfo
+ key, row, col = simplelist(tk_send('formatinfo'))
+ [key, number(row), number(col)]
+ end
+
def get(first, last=nil)
if first.kind_of?(Array)
simplelist(tk_send('get', first.collect{|idx| _to_idx(idx)})).collect!{|elem| simplelist(elem) }
@@ -455,6 +614,22 @@ class Tk::Tcllib::Tablelist
end
alias getkeys get_keys
+ def has_attrib?(name)
+ bool(tk_send('hasattrib', name))
+ end
+
+ def has_cellattrib?(idx, name)
+ bool(tk_send('hascellattrib', _to_idx(idx), name))
+ end
+
+ def has_columnattrib?(idx, name)
+ bool(tk_send('hascolumnattrib', _to_idx(idx), name))
+ end
+
+ def has_rowattrib?(idx, name)
+ bool(tk_send('hasrowattrib', _to_idx(idx), name))
+ end
+
def imagelabelpath(idx)
window(tk_send('imagelabelpath', _to_idx(idx)))
end
@@ -486,6 +661,16 @@ class Tk::Tcllib::Tablelist
end
alias insertlist insert_list
+ def is_elem_snipped?(cellidx, tkvar)
+ bool(tk_send('iselemsnipped', _to_idx(cellidx), tkvar))
+ end
+ alias elem_snipped? is_elem_snipped?
+
+ def is_title_snipped?(colidx, tkvar)
+ bool(tk_send('istitlesnipped', _to_idx(colidx), tkvar))
+ end
+ alias title_snipped? is_title_snipped?
+
def itemlistvar
TkVarAccess.new(tk_send('itemlistvar'))
end
@@ -498,6 +683,10 @@ class Tk::Tcllib::Tablelist
simplelist(tk_send('labels'))
end
+ def labeltag
+ TkBindTag.new_by_name(tk_send('labeltag'))
+ end
+
def move(src, target)
tk_send('move', _to_idx(src), _to_idx(target))
self
@@ -535,6 +724,23 @@ class Tk::Tcllib::Tablelist
end
alias resetsortinfo reset_sortinfo
+ def get_rowattrib(name=nil)
+ if name && name != None
+ tk_send('rowattrib', name)
+ else
+ ret = []
+ lst = simplelist(tk_send('rowattrib'))
+ until lst.empty?
+ ret << ( [lst.shift] << lst.shift )
+ end
+ ret
+ end
+ end
+ def set_rowattrib(*args)
+ tk_send('rowattrib', *(args.flatten))
+ self
+ end
+
def scan_mark(x, y)
tk_send('scan', 'mark', x, y)
self
@@ -633,7 +839,22 @@ class Tk::Tcllib::Tablelist
self
end
- DEFAULT_sortByColumn_cmd = '::tablelist::sortByColumn'
+
+ # default of 'labelcommand' option
+ DEFAULT_labelcommand_value =
+ DEFAULT_sortByColumn_cmd = '::tablelist::sortByColumn'
+
+ # default of 'labelcommand2' option
+ DEFAULT_labelcommand2_value =
+ DEFAULT_addToSortColumns_cmd = '::tablelist::addToSortColumns'
+
+ def sortByColumn_with_event_generate(idx)
+ tk_call('::tablelist::sortByColumn', @path, _to_idx(idx))
+ end
+
+ def addToSortColumns_with_event_generate(idx)
+ tk_call('::tablelist::addToSortColumns', @path, _to_idx(idx))
+ end
def sort_by_column(idx, order=nil)
if order
@@ -659,15 +880,49 @@ class Tk::Tcllib::Tablelist
self
end
+ def sort_by_columnlist(idxlist, orderlist=None)
+ # orderlist :: list of 'increasing' or 'decreasing'
+ tk_send('sortbycolumnlist', idxlist.map{|idx| _to_idx(idx)}, orderlist)
+ self
+ end
+
def sortcolumn
idx = num_or_str(tk_send('sortcolum'))
(idx.kind_of?(Fixnum) && idx < 0)? nil: idx
end
+ def sortcolumnlist
+ simplelist(tk_send('sortcolumlist')).map{|col| num_or_str(col)}
+ end
+
def sortorder
tk_send('sortorder')
end
+ def sortorderlist
+ simplelist(tk_send('sortorderlist'))
+ end
+
+ def toggle_columnhide(first, last=nil)
+ if first.kind_of?(Array)
+ tk_send('togglecolumnhide', first.collect{|idx| _to_idx(idx)})
+ else
+ first = _to_idx(first)
+ last = (last)? _to_idx(last): first
+ tk_send('togglecolumnhide', first, last)
+ end
+ end
+
+ def toggle_rowhide(first, last=nil)
+ if first.kind_of?(Array)
+ tk_send('togglerowhide', first.collect{|idx| _to_idx(idx)})
+ else
+ first = _to_idx(first)
+ last = (last)? _to_idx(last): first
+ tk_send('togglerowhide', first, last)
+ end
+ end
+
def toggle_visibility(first, last=nil)
if first.kind_of?(Array)
tk_send('togglevisibility', first.collect{|idx| _to_idx(idx)})
@@ -680,6 +935,26 @@ class Tk::Tcllib::Tablelist
end
alias togglevisibility toggle_visibility
+ def unset_attrib(name)
+ tk_send('unsetattrib', name)
+ self
+ end
+
+ def unset_cellattrib(idx, name)
+ tk_send('unsetcellattrib', _to_idx(idx), name)
+ self
+ end
+
+ def unset_columnattrib(idx, name)
+ tk_send('unsetcolumnattrib', _to_idx(idx), name)
+ self
+ end
+
+ def unset_rowattrib(idx, name)
+ tk_send('unsetrowattrib', _to_idx(idx), name)
+ self
+ end
+
def windowpath(idx)
window(tk_send('windowpath', _to_idx(idx)))
end
@@ -692,6 +967,11 @@ class << Tk::Tcllib::Tablelist
window(Tk.tk_call('::tablelist::getTablelistPath', descendant))
end
+ def getTablelistColumn(descendant)
+ num_or_str(Tk.tk_call('::tablelist::getTablelistColumn', headerlabel))
+ end
+
+
def convEventFields(descendant, x, y)
window(Tk.tk_call('::tablelist::convEventFields', descendant, x, y))
end
@@ -767,6 +1047,16 @@ class << Tk::Tcllib::Tablelist
Tk.tk_call('::tablelist::addTimeMentry', format, separator, gmt, name)
end
+ def addDateTimeMentry(format, date_sep, time_sep, gmt=false, name=None)
+ if gmt && gmt != None
+ gmt = '-gmt'
+ else
+ gmt = None
+ end
+ Tk.tk_call('::tablelist::addDateTimeMentry',
+ format, date_sep, time_sep, gmt, name)
+ end
+
def addFixedPointMentry(count1, count2, comma=false, name=None)
if comma && comma != None
comma = '-comma'
diff --git a/ext/tk/lib/tkextlib/tcllib/tablelist_tile.rb b/ext/tk/lib/tkextlib/tcllib/tablelist_tile.rb
index 0cb4eb735d..0a1458415e 100644
--- a/ext/tk/lib/tkextlib/tcllib/tablelist_tile.rb
+++ b/ext/tk/lib/tkextlib/tcllib/tablelist_tile.rb
@@ -9,7 +9,7 @@ require 'tk'
require 'tkextlib/tcllib.rb'
# TkPackage.require('tablelist_tile', '4.2')
-TkPackage.require('Tablelist_tile')
+TkPackage.require('tablelist_tile')
unless defined? Tk::Tcllib::Tablelist_usingTile
Tk::Tcllib::Tablelist_usingTile = true
@@ -19,6 +19,24 @@ requrie 'tkextlib/tcllib/tablelist_core'
module Tk
module Tcllib
+ class Tablelist
+ # commands related to tile Themems
+ def self.set_theme(theme)
+ Tk.tk_call('::tablelist::setTheme', theme)
+ end
+
+ def self.get_current_theme
+ Tk.tk_call('::tablelist::getCurrentTheme')
+ end
+
+ def self.get_theme_list
+ TkComm.simplelist(Tk.tk_call('::tablelist::getThemes'))
+ end
+ def self.set_theme_defaults
+ Tk.tk_call('::tablelist::setThemeDefaults')
+ end
+ end
+
Tablelist_Tile = Tablelist
TableList_Tile = Tablelist
end
diff --git a/ext/tk/lib/tkextlib/tcllib/toolbar.rb b/ext/tk/lib/tkextlib/tcllib/toolbar.rb
new file mode 100644
index 0000000000..6eae4eb3e1
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tcllib/toolbar.rb
@@ -0,0 +1,175 @@
+#
+# tkextlib/tcllib/toolbar.rb
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+# * Part of tcllib extension
+# * toolbar widget
+#
+
+require 'tk'
+require 'tkextlib/tcllib.rb'
+
+# TkPackage.require('widget::toolbar', '1.2')
+TkPackage.require('widget::toolbar')
+
+module Tk::Tcllib
+ module Widget
+ class Toolbar < TkWindow
+ PACKAGE_NAME = 'widget::toolbar'.freeze
+ def self.package_name
+ PACKAGE_NAME
+ end
+
+ def self.package_version
+ begin
+ TkPackage.require('widget::toolbar')
+ rescue
+ ''
+ end
+ end
+ end
+
+ module ToolbarItemConfig
+ include TkItemConfigMethod
+ end
+ end
+end
+
+
+class Tk::Tcllib::Widget::ToolbarItem < TkObject
+ include TkTreatTagFont
+
+ ToolbarItemID_TBL = TkCore::INTERP.create_table
+
+ TkCore::INTERP.init_ip_env{
+ TTagID_TBL.mutex.synchronize{ TTagID_TBL.clear }
+ }
+
+ def ToolbarItem.id2obj(tbar, id)
+ tpath = tbar.path
+ ToolbarItemID_TBL.mutex.synchronize{
+ if ToolbarItemID_TBL[tpath]
+ ToolbarItemID_TBL[tpath][id]? ToolbarItemID_TBL[tpath][id]: id
+ else
+ id
+ end
+ }
+ end
+
+ def initaialize(parent, *args)
+ @parent = @t = parent
+ @tpath = parent.path
+
+ @path = @id = @t.tk_send('add', *args)
+ # A same id is rejected by the Tcl function.
+
+ ToolbarItemID_TBL.mutex.synchronize{
+ ToolbarItemID_TBL[@id] = self
+ ToolbarItemID_TBL[@tpath] = {} unless ToolbarItemID_TBL[@tpath]
+ ToolbarItemID_TBL[@tpath][@id] = self
+ }
+ end
+
+ def [](key)
+ cget key
+ end
+
+ def []=(key,val)
+ configure key, val
+ val
+ end
+
+ def cget_tkstring(option)
+ @t.itemcget_tkstring(@id, option)
+ end
+ def cget(option)
+ @t.itemcget(@id, option)
+ end
+ def cget_strict(option)
+ @t.itemcget_strict(@id, option)
+ end
+
+ def configure(key, value=None)
+ @t.itemconfigure(@id, key, value)
+ self
+ end
+
+ def configinfo(key=nil)
+ @t.itemconfiginfo(@id, key)
+ end
+
+ def current_configinfo(key=nil)
+ @t.current_itemconfiginfo(@id, key)
+ end
+
+ def delete
+ @t.delete(@id)
+ end
+
+ def itemid
+ @t.itemid(@id)
+ end
+
+ def remove
+ @t.remove(@id)
+ end
+ def remove_with_destroy
+ @t.remove_with_destroy(@id)
+ end
+end
+
+class Tk::Tcllib::Widget::Toolbar
+ include Tk::Tcllib::Widget::ToolbarItemConfig
+
+ TkCommandNames = ['::widget::toolbar'.freeze].freeze
+
+ def __destroy_hook__
+ Tk::Tcllib::Widget::ToolbarItem::ToolbarItemID_TBL.mutex.synchronize{
+ Tk::Tcllib::Widget::ToolbarItem::ToolbarItemID_TBL.delete(@path)
+ }
+ end
+
+ def create_self(keys)
+ if keys and keys != None
+ tk_call_without_enc(self.class::TkCommandNames[0], @path,
+ *hash_kv(keys, true))
+ else
+ tk_call_without_enc(self.class::TkCommandNames[0], @path)
+ end
+ end
+ private :create_self
+
+ def getframe
+ window(tk_send('getframe'))
+ end
+ alias get_frame getframe
+
+ def add(*args)
+ Tk::Tcllib::Widget::Toolbar.new(self, *args)
+ end
+
+ def itemid(item)
+ window(tk_send('itemid'))
+ end
+
+ def items(pattern)
+ tk_split_simplelist(tk_send('items', pattern)).map{|id|
+ Tk::Tcllib::Widget::ToolbarItem.id2obj(self, id)
+ }
+ end
+
+ def remove(*items)
+ tk_send('remove', *items)
+ self
+ end
+
+ def remove_with_destroy(*items)
+ tk_send('remove', '-destroy', *items)
+ self
+ end
+
+ def delete(*items)
+ tk_send('delete', *items)
+ self
+ end
+end
diff --git a/ext/tk/lib/tkextlib/tcllib/tooltip.rb b/ext/tk/lib/tkextlib/tcllib/tooltip.rb
index 73b7df0c22..070e63a7b5 100644
--- a/ext/tk/lib/tkextlib/tcllib/tooltip.rb
+++ b/ext/tk/lib/tkextlib/tcllib/tooltip.rb
@@ -34,6 +34,8 @@ module Tk::Tcllib::Tooltip
extend TkCore
WidgetClassName = 'Tooltip'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
def self.database_classname
self::WidgetClassName
end
@@ -64,6 +66,13 @@ module Tk::Tcllib::Tooltip
self.delay(millisecs)
end
+ def self.fade?
+ bool(tk_call_without_enc('::tooltip::tooltip', 'fade'))
+ end
+ def self.fade(mode)
+ tk_call_without_enc('::tooltip::tooltip', 'fade', mode)
+ end
+
def self.disable
tk_call_without_enc('::tooltip::tooltip', 'disable')
false
@@ -86,7 +95,7 @@ module Tk::Tcllib::Tooltip
else
args = msg
end
- tk_call_without_enc('::tooltip::tooltip', widget.path, *args)
+ tk_call('::tooltip::tooltip', widget.path, *args)
end
def self.erase(widget)
diff --git a/ext/tk/lib/tkextlib/tcllib/widget.rb b/ext/tk/lib/tkextlib/tcllib/widget.rb
index ed69f67ce6..57fdf7a575 100644
--- a/ext/tk/lib/tkextlib/tcllib/widget.rb
+++ b/ext/tk/lib/tkextlib/tcllib/widget.rb
@@ -26,10 +26,41 @@ module Tk::Tcllib
''
end
end
+
+ #--- followings may be private functions of tklib
+ def self.isa(compare_as, *args)
+ begin
+ return Tk.tk_call('::widget::isa', compare_as, *args)
+ rescue => e
+ if TkComm.bool(Tk.tk_call('info','command','::widget::isa')) ||
+ ! TkComm.bool(Tk.tk_call('info','command','::widget::validate'))
+ fail e
+ end
+ end
+ Tk.tk_call('::widget::validate', compare_as, *args)
+ end
+ def self.validate(compare_as, *args)
+ begin
+ return Tk.tk_call('::widget::validate', compare_as, *args)
+ rescue => e
+ if TkComm.bool(Tk.tk_call('info','command','::widget::validate')) ||
+ ! TkComm.bool(Tk.tk_call('info','command','::widget::isa'))
+ fail e
+ end
+ end
+ Tk.tk_call('::widget::isa', compare_as, *args)
+ end
end
end
module Tk::Tcllib::Widget
+ TkComm::TkExtlibAutoloadModule.unshift(self)
+
+ autoload :Calendar, 'tkextlib/tcllib/calendar'
+
+ autoload :Canvas_Sqmap, 'tkextlib/tcllib/canvas_sqmap'
+ autoload :Canvas_Zoom, 'tkextlib/tcllib/canvas_zoom'
+
autoload :Dialog, 'tkextlib/tcllib/dialog'
autoload :Panelframe, 'tkextlib/tcllib/panelframe'
@@ -45,4 +76,7 @@ module Tk::Tcllib::Widget
autoload :Superframe, 'tkextlib/tcllib/superframe'
autoload :SuperFrame, 'tkextlib/tcllib/superframe'
+
+ autoload :Toolbar, 'tkextlib/tcllib/toolbar'
+ autoload :ToolbarItem, 'tkextlib/tcllib/toolbar'
end
diff --git a/ext/tk/lib/tkextlib/tile.rb b/ext/tk/lib/tkextlib/tile.rb
index 09cf49faa6..6c11e212ae 100644
--- a/ext/tk/lib/tkextlib/tile.rb
+++ b/ext/tk/lib/tkextlib/tile.rb
@@ -18,10 +18,37 @@ require 'tkextlib/tile/setup.rb'
# TkPackage.require('tile', '0.7')
if Tk::TK_MAJOR_VERSION > 8 ||
(Tk::TK_MAJOR_VERSION == 8 && Tk::TK_MINOR_VERSION >= 5)
- TkPackage.require('tile') # for compatibility (version check of 'tile')
- verstr = TkPackage.require('Ttk')
+ begin
+ TkPackage.require('tile') # for compatibility (version check of 'tile')
+ rescue RuntimeError
+ # ignore, even if cannot find package 'tile'
+ end
+ pkgname = 'Ttk'
else
- verstr = TkPackage.require('tile')
+ pkgname = 'tile'
+end
+
+begin
+ verstr = TkPackage.require(pkgname)
+rescue RuntimeError
+ # define dummy methods
+ module Tk
+ module Tile
+ CANNOT_FIND_PACKAGE = true
+ def self.const_missing(sym)
+ TkPackage.require(PACKAGE_NAME)
+ end
+ def self.method_missing(*args)
+ TkPackage.require(PACKAGE_NAME)
+ end
+ end
+ end
+ Tk.__cannot_find_tk_package_for_widget_set__(:Ttk, pkgname)
+ if pkgname == 'Ttk'
+ verstr = Tk::TK_PATCHLEVEL # dummy
+ else
+ verstr = '0.7' # dummy
+ end
end
ver = verstr.split('.')
@@ -404,6 +431,9 @@ module Tk
autoload :TSeparator, 'tkextlib/tile/tseparator'
autoload :Separator, 'tkextlib/tile/tseparator'
+ autoload :TSpinbox, 'tkextlib/tile/tspinbox'
+ autoload :Spinbox, 'tkextlib/tile/tspinbox'
+
autoload :TSquare, 'tkextlib/tile/tsquare'
autoload :Square, 'tkextlib/tile/tsquare'
diff --git a/ext/tk/lib/tkextlib/tile/dialog.rb b/ext/tk/lib/tkextlib/tile/dialog.rb
index ef2d1fe577..b112e6152b 100644
--- a/ext/tk/lib/tkextlib/tile/dialog.rb
+++ b/ext/tk/lib/tkextlib/tile/dialog.rb
@@ -12,6 +12,12 @@ module Tk
end
end
+begin
+ TkPackage.require('ttk::dialog') # this may be required.
+rescue RuntimeError
+ # ignore
+end
+
class Tk::Tile::Dialog
TkCommandNames = ['::ttk::dialog'.freeze].freeze
diff --git a/ext/tk/lib/tkextlib/tile/sizegrip.rb b/ext/tk/lib/tkextlib/tile/sizegrip.rb
index c5068919a4..d7da0a4075 100644
--- a/ext/tk/lib/tkextlib/tile/sizegrip.rb
+++ b/ext/tk/lib/tkextlib/tile/sizegrip.rb
@@ -13,17 +13,20 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Sizegrip, :TkSizegrip, :TkSizeGrip)
-
-
class Tk::Tile::SizeGrip < TkWindow
include Tk::Tile::TileWidget
TkCommandNames = ['::ttk::sizegrip'.freeze].freeze
WidgetClassName = 'TSizegrip'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Sizegrip,
+# :TkSizegrip, :TkSizeGrip)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/sizegrip.rb',
+ :Ttk, Tk::Tile::Sizegrip,
+ :TkSizegrip, :TkSizeGrip)
diff --git a/ext/tk/lib/tkextlib/tile/style.rb b/ext/tk/lib/tkextlib/tile/style.rb
index 26d79d378b..f38deda503 100644
--- a/ext/tk/lib/tkextlib/tile/style.rb
+++ b/ext/tk/lib/tkextlib/tile/style.rb
@@ -233,6 +233,8 @@ class << Tk::Tile::Style
def element_create(name, type, *args)
if type == 'image' || type == :image
element_create_image(name, *args)
+ elsif type == 'vsapi' || type == :vsapi
+ element_create_vsapi(name, *args)
else
tk_call(TkCommandNames[0], 'element', 'create', name, type, *args)
end
@@ -279,6 +281,24 @@ class << Tk::Tile::Style
end
end
+ def element_create_vsapi(name, class_name, part_id, *args)
+ # supported on Tcl/Tk 8.6 or later
+
+ # argument check
+ if (state_map = args.shift || None)
+ if state_map.kind_of?(Hash)
+ opts = _symbolkey2str(state_map)
+ state_map = None
+ end
+ end
+ opts = args.shift || None
+ fail ArgumentError, "too many arguments" unless args.empty?
+
+ # define a Microsoft Visual Styles element
+ tk_call(TkCommandNames[0], 'element', 'create', name, 'vsapi',
+ class_name, part_id, state_map, opts)
+ end
+
def element_names()
list(tk_call(TkCommandNames[0], 'element', 'names'))
end
diff --git a/ext/tk/lib/tkextlib/tile/tbutton.rb b/ext/tk/lib/tkextlib/tile/tbutton.rb
index 5d7db10fe9..c852024842 100644
--- a/ext/tk/lib/tkextlib/tile/tbutton.rb
+++ b/ext/tk/lib/tkextlib/tile/tbutton.rb
@@ -13,9 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Button, :TkButton)
-
-
class Tk::Tile::TButton < Tk::Button
include Tk::Tile::TileWidget
@@ -25,9 +22,13 @@ class Tk::Tile::TButton < Tk::Button
TkCommandNames = ['::tbutton'.freeze].freeze
end
WidgetClassName = 'TButton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Button, :TkButton)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tbutton.rb',
+ :Ttk, Tk::Tile::Button, :TkButton)
diff --git a/ext/tk/lib/tkextlib/tile/tcheckbutton.rb b/ext/tk/lib/tkextlib/tile/tcheckbutton.rb
index ca79d89e58..01751ede0f 100644
--- a/ext/tk/lib/tkextlib/tile/tcheckbutton.rb
+++ b/ext/tk/lib/tkextlib/tile/tcheckbutton.rb
@@ -15,10 +15,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Checkbutton,
- :TkCheckbutton, :TkCheckButton)
-
-
class Tk::Tile::TCheckButton < Tk::CheckButton
include Tk::Tile::TileWidget
@@ -28,9 +24,15 @@ class Tk::Tile::TCheckButton < Tk::CheckButton
TkCommandNames = ['::tcheckbutton'.freeze].freeze
end
WidgetClassName = 'TCheckbutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Checkbutton,
+# :TkCheckbutton, :TkCheckButton)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tcheckbutton.rb',
+ :Ttk, Tk::Tile::Checkbutton,
+ :TkCheckbutton, :TkCheckButton)
diff --git a/ext/tk/lib/tkextlib/tile/tcombobox.rb b/ext/tk/lib/tkextlib/tile/tcombobox.rb
index b64372f1c9..b5ab827e2d 100644
--- a/ext/tk/lib/tkextlib/tile/tcombobox.rb
+++ b/ext/tk/lib/tkextlib/tile/tcombobox.rb
@@ -13,9 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Combobox, :TkCombobox)
-
-
class Tk::Tile::TCombobox < Tk::Tile::TEntry
include Tk::Tile::TileWidget
@@ -25,7 +22,7 @@ class Tk::Tile::TCombobox < Tk::Tile::TEntry
TkCommandNames = ['::tcombobox'.freeze].freeze
end
WidgetClassName = 'TCombobox'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __boolval_optkeys
super() << 'exportselection'
@@ -52,3 +49,7 @@ class Tk::Tile::TCombobox < Tk::Tile::TEntry
tk_send('set', val)
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Combobox, :TkCombobox)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tcombobox.rb',
+ :Ttk, Tk::Tile::Combobox, :TkCombobox)
diff --git a/ext/tk/lib/tkextlib/tile/tentry.rb b/ext/tk/lib/tkextlib/tile/tentry.rb
index 0bea98dcd9..8d2633a774 100644
--- a/ext/tk/lib/tkextlib/tile/tentry.rb
+++ b/ext/tk/lib/tkextlib/tile/tentry.rb
@@ -13,9 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Entry, :TkEntry)
-
-
class Tk::Tile::TEntry < Tk::Entry
include Tk::Tile::TileWidget
@@ -25,7 +22,7 @@ class Tk::Tile::TEntry < Tk::Entry
TkCommandNames = ['::tentry'.freeze].freeze
end
WidgetClassName = 'TEntry'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __optkey_aliases
{:vcmd=>:validatecommand, :invcmd=>:invalidcommand}
@@ -46,3 +43,7 @@ class Tk::Tile::TEntry < Tk::Entry
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Entry, :TkEntry)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tentry.rb',
+ :Ttk, Tk::Tile::Entry, :TkEntry)
diff --git a/ext/tk/lib/tkextlib/tile/tframe.rb b/ext/tk/lib/tkextlib/tile/tframe.rb
index 3b5f98bb6e..d6d4312628 100644
--- a/ext/tk/lib/tkextlib/tile/tframe.rb
+++ b/ext/tk/lib/tkextlib/tile/tframe.rb
@@ -13,9 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Frame, :TkFrame)
-
-
class Tk::Tile::TFrame < Tk::Frame
include Tk::Tile::TileWidget
@@ -25,9 +22,13 @@ class Tk::Tile::TFrame < Tk::Frame
TkCommandNames = ['::tframe'.freeze].freeze
end
WidgetClassName = 'TFrame'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Frame, :TkFrame)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tframe.rb',
+ :Ttk, Tk::Tile::Frame, :TkFrame)
diff --git a/ext/tk/lib/tkextlib/tile/tlabel.rb b/ext/tk/lib/tkextlib/tile/tlabel.rb
index 7d074d3842..55b98acc68 100644
--- a/ext/tk/lib/tkextlib/tile/tlabel.rb
+++ b/ext/tk/lib/tkextlib/tile/tlabel.rb
@@ -13,9 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Label, :TkLabel)
-
-
class Tk::Tile::TLabel < Tk::Label
include Tk::Tile::TileWidget
@@ -25,9 +22,13 @@ class Tk::Tile::TLabel < Tk::Label
TkCommandNames = ['::tlabel'.freeze].freeze
end
WidgetClassName = 'TLabel'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Label, :TkLabel)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tlabel.rb',
+ :Ttk, Tk::Tile::Label, :TkLabel)
diff --git a/ext/tk/lib/tkextlib/tile/tlabelframe.rb b/ext/tk/lib/tkextlib/tile/tlabelframe.rb
index 9f4a11990c..a34c98583f 100644
--- a/ext/tk/lib/tkextlib/tile/tlabelframe.rb
+++ b/ext/tk/lib/tkextlib/tile/tlabelframe.rb
@@ -15,10 +15,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Labelframe,
- :TkLabelframe, :TkLabelFrame)
-
-
class Tk::Tile::TLabelframe < Tk::Tile::TFrame
include Tk::Tile::TileWidget
@@ -28,9 +24,15 @@ class Tk::Tile::TLabelframe < Tk::Tile::TFrame
TkCommandNames = ['::tlabelframe'.freeze].freeze
end
WidgetClassName = 'TLabelframe'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Labelframe,
+# :TkLabelframe, :TkLabelFrame)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tlabelframe.rb',
+ :Ttk, Tk::Tile::Labelframe,
+ :TkLabelframe, :TkLabelFrame)
diff --git a/ext/tk/lib/tkextlib/tile/tmenubutton.rb b/ext/tk/lib/tkextlib/tile/tmenubutton.rb
index 5612fb47eb..1cf553ec8c 100644
--- a/ext/tk/lib/tkextlib/tile/tmenubutton.rb
+++ b/ext/tk/lib/tkextlib/tile/tmenubutton.rb
@@ -15,10 +15,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Menubutton,
- :TkMenubutton, :TkMenuButton)
-
-
class Tk::Tile::TMenubutton < Tk::Menubutton
include Tk::Tile::TileWidget
@@ -28,9 +24,15 @@ class Tk::Tile::TMenubutton < Tk::Menubutton
TkCommandNames = ['::tmenubutton'.freeze].freeze
end
WidgetClassName = 'TMenubutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Menubutton,
+# :TkMenubutton, :TkMenuButton)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tmenubutton.rb',
+ :Ttk, Tk::Tile::Menubutton,
+ :TkMenubutton, :TkMenuButton)
diff --git a/ext/tk/lib/tkextlib/tile/tnotebook.rb b/ext/tk/lib/tkextlib/tile/tnotebook.rb
index d02e05b211..9e27e2c1fd 100644
--- a/ext/tk/lib/tkextlib/tile/tnotebook.rb
+++ b/ext/tk/lib/tkextlib/tile/tnotebook.rb
@@ -13,9 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Notebook, :TkNotebook)
-
-
class Tk::Tile::TNotebook < TkWindow
################################
include TkItemConfigMethod
@@ -46,8 +43,11 @@ class Tk::Tile::TNotebook < TkWindow
alias tabconfiginfo itemconfiginfo
alias current_tabconfiginfo current_itemconfiginfo
+ def tabcget_tkstring(tagOrId, option)
+ tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{option}")), false, true)[-1]
+ end
def tabcget_strict(tagOrId, option)
- tabconfigure(tagOrId, option)[-1]
+ tabconfiginfo(tagOrId, option)[-1]
end
def tabcget(tagOrId, option)
unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
@@ -80,7 +80,7 @@ class Tk::Tile::TNotebook < TkWindow
TkCommandNames = ['::tnotebook'.freeze].freeze
end
WidgetClassName = 'TNotebook'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
@@ -111,6 +111,10 @@ class Tk::Tile::TNotebook < TkWindow
self
end
+ def hide(idx)
+ tk_send('hide', idx)
+ end
+
def index(idx)
number(tk_send('index', idx))
end
@@ -137,3 +141,7 @@ class Tk::Tile::TNotebook < TkWindow
list(tk_send('tabs'))
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Notebook, :TkNotebook)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tnotebook.rb',
+ :Ttk, Tk::Tile::Notebook, :TkNotebook)
diff --git a/ext/tk/lib/tkextlib/tile/tpaned.rb b/ext/tk/lib/tkextlib/tile/tpaned.rb
index aff6cac4bb..d6ad234559 100644
--- a/ext/tk/lib/tkextlib/tile/tpaned.rb
+++ b/ext/tk/lib/tkextlib/tile/tpaned.rb
@@ -13,10 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Panedwindow,
- :TkPanedwindow, :TkPanedWindow)
-
-
class Tk::Tile::TPaned < TkWindow
include Tk::Tile::TileWidget
@@ -30,7 +26,7 @@ class Tk::Tile::TPaned < TkWindow
TkCommandNames = ['::tpaned'.freeze].freeze
end
WidgetClassName = 'TPaned'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
@@ -66,6 +62,12 @@ class Tk::Tile::TPaned < TkWindow
self
end
+ def panecget_tkstring(pane, slot)
+ pane = _epath(pane)
+ tk_send_without_enc('pane', pane, "-#{slot}")
+ end
+ alias pane_cget_tkstring panecget_tkstring
+
def panecget_strict(pane, slot)
pane = _epath(pane)
tk_tcl2ruby(tk_send_without_enc('pane', pane, "-#{slot}"))
@@ -221,11 +223,23 @@ class Tk::Tile::TPaned < TkWindow
end
alias current_pane_configinfo current_paneconfiginfo
+ def panes
+ tk_split_simplelist(tk_send_without_enc('panes')).map{|w|
+ (obj = window(w))? obj: w
+ }
+ end
+
def identify(x, y)
- list(tk_send_without_enc('identify', x, y))
+ num_or_nil(tk_send_without_enc('identify', x, y))
end
def sashpos(idx, newpos=None)
num_or_str(tk_send_without_enc('sashpos', idx, newpos))
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Panedwindow,
+# :TkPanedwindow, :TkPanedWindow)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tpaned.rb',
+ :Ttk, Tk::Tile::Panedwindow,
+ :TkPanedwindow, :TkPanedWindow)
diff --git a/ext/tk/lib/tkextlib/tile/tprogressbar.rb b/ext/tk/lib/tkextlib/tile/tprogressbar.rb
index f786d370dd..0c9d15e1b9 100644
--- a/ext/tk/lib/tkextlib/tile/tprogressbar.rb
+++ b/ext/tk/lib/tkextlib/tile/tprogressbar.rb
@@ -13,9 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Progressbar, :TkProgressbar)
-
-
class Tk::Tile::TProgressbar
include Tk::Tile::TileWidget
@@ -25,7 +22,7 @@ class Tk::Tile::TProgressbar
TkCommandNames = ['::tprogressbar'.freeze].freeze
end
WidgetClassName = 'TProgressbar'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
@@ -54,3 +51,7 @@ class Tk::Tile::TProgressbar
end
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Progressbar, :TkProgressbar)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tprogressbar.rb',
+ :Ttk, Tk::Tile::Progressbar, :TkProgressbar)
diff --git a/ext/tk/lib/tkextlib/tile/tradiobutton.rb b/ext/tk/lib/tkextlib/tile/tradiobutton.rb
index 72e72170cb..5dbf260666 100644
--- a/ext/tk/lib/tkextlib/tile/tradiobutton.rb
+++ b/ext/tk/lib/tkextlib/tile/tradiobutton.rb
@@ -15,10 +15,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Radiobutton,
- :TkRadiobutton, :TkRadioButton)
-
-
class Tk::Tile::TRadioButton < Tk::RadioButton
include Tk::Tile::TileWidget
@@ -28,9 +24,15 @@ class Tk::Tile::TRadioButton < Tk::RadioButton
TkCommandNames = ['::tradiobutton'.freeze].freeze
end
WidgetClassName = 'TRadiobutton'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Radiobutton,
+# :TkRadiobutton, :TkRadioButton)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tradiobutton.rb',
+ :Ttk, Tk::Tile::Radiobutton,
+ :TkRadiobutton, :TkRadioButton)
diff --git a/ext/tk/lib/tkextlib/tile/treeview.rb b/ext/tk/lib/tkextlib/tile/treeview.rb
index 2046be8a69..70db3d6d78 100644
--- a/ext/tk/lib/tkextlib/tile/treeview.rb
+++ b/ext/tk/lib/tkextlib/tile/treeview.rb
@@ -12,9 +12,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Treeview, :TkTreeview)
-
-
module Tk::Tile::TreeviewConfig
include TkItemConfigMethod
@@ -519,16 +516,20 @@ module Tk::Tile::TreeviewConfig
end
end
+ alias __itemcget_tkstring itemcget_tkstring
alias __itemcget itemcget
alias __itemcget_strict itemcget_strict
alias __itemconfigure itemconfigure
alias __itemconfiginfo itemconfiginfo
alias __current_itemconfiginfo current_itemconfiginfo
- private :__itemcget, :__itemcget_strict
+ private :__itemcget_tkstring, :__itemcget, :__itemcget_strict
private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo
# Treeview Item
+ def itemcget_tkstring(tagOrId, option)
+ __itemcget_tkstring([:item, tagOrId], option)
+ end
def itemcget(tagOrId, option)
__itemcget([:item, tagOrId], option)
end
@@ -546,6 +547,9 @@ module Tk::Tile::TreeviewConfig
end
# Treeview Column
+ def columncget_tkstring(tagOrId, option)
+ __itemcget_tkstring([:column, tagOrId], option)
+ end
def columncget(tagOrId, option)
__itemcget([:column, tagOrId], option)
end
@@ -561,6 +565,7 @@ module Tk::Tile::TreeviewConfig
def current_columnconfiginfo(tagOrId, slot=nil)
__current_itemconfiginfo([:column, tagOrId], slot)
end
+ alias column_cget_tkstring columncget_tkstring
alias column_cget columncget
alias column_cget_strict columncget_strict
alias column_configure columnconfigure
@@ -568,6 +573,19 @@ module Tk::Tile::TreeviewConfig
alias current_column_configinfo current_columnconfiginfo
# Treeview Heading
+ def headingcget_tkstring(tagOrId, option)
+ if __tile_specific_item_optkeys([:heading, tagOrId]).index(option.to_s)
+ begin
+ # On tile-0.7.{2-8}, 'state' options has no '-' at its head.
+ tk_call(*(__item_cget_cmd([:heading, tagOrId]) << option.to_s))
+ rescue
+ # Maybe, 'state' option has '-' in future.
+ tk_call(*(__item_cget_cmd([:heading, tagOrId]) << "-#{option}"))
+ end
+ else
+ __itemcget_tkstring([:heading, tagOrId], option)
+ end
+ end
def headingcget_strict(tagOrId, option)
if __tile_specific_item_optkeys([:heading, tagOrId]).index(option.to_s)
begin
@@ -630,6 +648,7 @@ module Tk::Tile::TreeviewConfig
def current_headingconfiginfo(tagOrId, slot=nil)
__current_itemconfiginfo([:heading, tagOrId], slot)
end
+ alias heading_cget_tkstring headingcget_tkstring
alias heading_cget headingcget
alias heading_cget_strict headingcget_strict
alias heading_configure headingconfigure
@@ -637,6 +656,9 @@ module Tk::Tile::TreeviewConfig
alias current_heading_configinfo current_headingconfiginfo
# Treeview Tag
+ def tagcget_tkstring(tagOrId, option)
+ __itemcget_tkstring([:tag, :configure, tagOrId], option)
+ end
def tagcget(tagOrId, option)
__itemcget([:tag, :configure, tagOrId], option)
end
@@ -652,6 +674,7 @@ module Tk::Tile::TreeviewConfig
def current_tagconfiginfo(tagOrId, slot=nil)
__current_itemconfiginfo([:tag, :configure, tagOrId], slot)
end
+ alias tag_cget_tkstring tagcget_tkstring
alias tag_cget tagcget
alias tag_cget_strict tagcget_strict
alias tag_configure tagconfigure
@@ -737,6 +760,9 @@ class Tk::Tile::Treeview::Item < TkObject
@id
end
+ def cget_tkstring(option)
+ @t.itemcget_tkstring(@id, option)
+ end
def cget(option)
@t.itemcget(@id, option)
end
@@ -769,6 +795,11 @@ class Tk::Tile::Treeview::Item < TkObject
self
end
+ def tag_has?(tag)
+ @t.tag_has?(tag, @id)
+ end
+ alias has_tag? tag_has?
+
def bbox(column=None)
@t.bbox(@id, column)
end
@@ -907,7 +938,7 @@ class Tk::Tile::Treeview::Tag < TkObject
TagID_TBL = TkCore::INTERP.create_table
- (Tag_ID = ['tile_treeview_tag'.freeze, '00000'.taint]).instance_eval{
+ (Tag_ID = ['tile_treeview_tag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -950,6 +981,11 @@ class Tk::Tile::Treeview::Tag < TkObject
@id
end
+ def tag_has?(item)
+ @t.tag_has?(@id, item)
+ end
+ alias added? tag_has?
+
def bind(seq, *args)
if TkComm._callback_entry?(args[0]) || !block_given?
cmd = args.shift
@@ -979,6 +1015,9 @@ class Tk::Tile::Treeview::Tag < TkObject
@t.tag_bindinfo(@id, seq)
end
+ def cget_tkstring(option)
+ @t.tagcget_tkstring(@id, option)
+ end
def cget(option)
@t.tagcget(@id, option)
end
@@ -1014,7 +1053,7 @@ class Tk::Tile::Treeview < TkWindow
TkCommandNames = ['::treeview'.freeze].freeze
end
WidgetClassName = 'Treeview'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __destroy_hook__
Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{
@@ -1098,14 +1137,29 @@ class Tk::Tile::Treeview < TkWindow
end
end
+ def identify_region(x, y)
+ tk_send('identify', 'region', x, y)
+ end
+
+ def identify_item(x, y)
+ id = tk_send('identify', 'item', x, y)
+ (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)
+ end
+
+ def identify_element(x, y)
+ tk_send('identify', 'element', x, y)
+ end
+
def row_identify(x, y)
id = tk_send('identify', 'row', x, y)
(id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)
end
+ alias identify_row row_identify
def column_identify(x, y)
tk_send('identify', 'column', x, y)
end
+ alias identify_column column_identify
def index(item)
number(tk_send('index', item))
@@ -1204,6 +1258,15 @@ class Tk::Tile::Treeview < TkWindow
self
end
+ def tag_has?(tag, item)
+ bool(tk_send('tag', 'has', tagid(tag), tagid(item)))
+ end
+ def tag_has(tag)
+ tk_split_simplelist(tk_send('tag', 'has', tagid(tag))).collect{|id|
+ Tk::Tile::Treeview::Item.id2obj(self, id)
+ }
+ end
+
def tag_bind(tag, seq, *args)
if TkComm._callback_entry?(args[0]) || !block_given?
cmd = args.shift
@@ -1237,3 +1300,7 @@ class Tk::Tile::Treeview < TkWindow
end
alias tagbindinfo tag_bindinfo
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Treeview, :TkTreeview)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/treeview.rb',
+ :Ttk, Tk::Tile::Treeview, :TkTreeview)
diff --git a/ext/tk/lib/tkextlib/tile/tscale.rb b/ext/tk/lib/tkextlib/tile/tscale.rb
index 2c46fd9bd4..7eefcef731 100644
--- a/ext/tk/lib/tkextlib/tile/tscale.rb
+++ b/ext/tk/lib/tkextlib/tile/tscale.rb
@@ -17,9 +17,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Scale, :TkScale)
-
-
class Tk::Tile::TScale < Tk::Scale
include Tk::Tile::TileWidget
@@ -29,11 +26,13 @@ class Tk::Tile::TScale < Tk::Scale
TkCommandNames = ['::tscale'.freeze].freeze
end
WidgetClassName = 'TScale'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
+
+ alias identify ttk_identify
end
class Tk::Tile::TProgress < Tk::Tile::TScale
@@ -45,9 +44,13 @@ class Tk::Tile::TProgress < Tk::Tile::TScale
TkCommandNames = ['::tprogress'.freeze].freeze
end
WidgetClassName = 'TProgress'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Scale, :TkScale)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tscale.rb',
+ :Ttk, Tk::Tile::Scale, :TkScale)
diff --git a/ext/tk/lib/tkextlib/tile/tscrollbar.rb b/ext/tk/lib/tkextlib/tile/tscrollbar.rb
index 163b8f4713..c6bba5810b 100644
--- a/ext/tk/lib/tkextlib/tile/tscrollbar.rb
+++ b/ext/tk/lib/tkextlib/tile/tscrollbar.rb
@@ -13,9 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Scrollbar, :TkScrollbar)
-
-
class Tk::Tile::TScrollbar < Tk::Scrollbar
include Tk::Tile::TileWidget
@@ -25,13 +22,21 @@ class Tk::Tile::TScrollbar < Tk::Scrollbar
TkCommandNames = ['::tscrollbar'.freeze].freeze
end
WidgetClassName = 'TScrollbar'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
+
+ alias identify ttk_identify
end
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Scrollbar, :TkScrollbar)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tscrollbar.rb',
+ :Ttk, Tk::Tile::Scrollbar, :TkScrollbar)
+
+#######################################################################
+
class Tk::Tile::XScrollbar < Tk::Tile::TScrollbar
def create_self(keys)
keys = {} unless keys
@@ -50,5 +55,9 @@ class Tk::Tile::YScrollbar < Tk::Tile::TScrollbar
private :create_self
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::XScrollbar, :TkXScrollbar)
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::YScrollbar, :TkYScrollbar)
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::XScrollbar, :TkXScrollbar)
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::YScrollbar, :TkYScrollbar)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tscrollbar.rb',
+ :Ttk, Tk::Tile::XScrollbar, :TkXScrollbar)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tscrollbar.rb',
+ :Ttk, Tk::Tile::YScrollbar, :TkYScrollbar)
diff --git a/ext/tk/lib/tkextlib/tile/tseparator.rb b/ext/tk/lib/tkextlib/tile/tseparator.rb
index 30fae2c525..ffd2f6f89f 100644
--- a/ext/tk/lib/tkextlib/tile/tseparator.rb
+++ b/ext/tk/lib/tkextlib/tile/tseparator.rb
@@ -13,9 +13,6 @@ module Tk
end
end
-Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Separator, :TkSeparator)
-
-
class Tk::Tile::TSeparator < TkWindow
include Tk::Tile::TileWidget
@@ -25,9 +22,13 @@ class Tk::Tile::TSeparator < TkWindow
TkCommandNames = ['::tseparator'.freeze].freeze
end
WidgetClassName = 'TSeparator'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
end
end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Separator, :TkSeparator)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tseparator.rb',
+ :Ttk, Tk::Tile::Separator, :TkSeparator)
diff --git a/ext/tk/lib/tkextlib/tile/tspinbox.rb b/ext/tk/lib/tkextlib/tile/tspinbox.rb
new file mode 100644
index 0000000000..2f2d73c5ab
--- /dev/null
+++ b/ext/tk/lib/tkextlib/tile/tspinbox.rb
@@ -0,0 +1,107 @@
+#
+# ttk::spinbox widget (Tcl/Tk 8.6b1 or later)
+# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
+#
+require 'tk'
+require 'tkextlib/tile.rb'
+
+module Tk
+ module Tile
+ class TSpinbox < Tk::Tile::TEntry
+ end
+ Spinbox = TSpinbox
+ end
+end
+
+class Tk::Tile::TSpinbox < Tk::Tile::TEntry
+ include Tk::Tile::TileWidget
+
+ if Tk::Tile::USE_TTK_NAMESPACE
+ TkCommandNames = ['::ttk::spinbox'.freeze].freeze
+ else
+ TkCommandNames = ['::tspinbox'.freeze].freeze
+ end
+ WidgetClassName = 'TSpinbox'.freeze
+ WidgetClassNames[WidgetClassName] ||= self
+
+ class SpinCommand < TkValidateCommand
+ class ValidateArgs < TkUtil::CallbackSubst
+ KEY_TBL = [
+ [ ?d, ?s, :direction ],
+ [ ?s, ?e, :current ],
+ [ ?W, ?w, :widget ],
+ nil
+ ]
+
+ PROC_TBL = [
+ [ ?s, TkComm.method(:string) ],
+ [ ?w, TkComm.method(:window) ],
+
+ [ ?e, proc{|val|
+ #enc = Tk.encoding
+ enc = ((Tk.encoding)? Tk.encoding : Tk.encoding_system)
+ if enc
+ Tk.fromUTF8(TkComm::string(val), enc)
+ else
+ TkComm::string(val)
+ end
+ }
+ ],
+
+ nil
+ ]
+
+ _setup_subst_table(KEY_TBL, PROC_TBL);
+
+ def self.ret_val(val)
+ (val)? '1': '0'
+ end
+ end
+
+ def self._config_keys
+ ['command']
+ end
+ end
+
+ def __validation_class_list
+ super() << SpinCommand
+ end
+
+ Tk::ValidateConfigure.__def_validcmd(binding, SpinCommand)
+
+ def __boolval_optkeys
+ super() << 'wrap'
+ end
+ private :__boolval_optkeys
+
+ def __strval_optkeys
+ super() << 'buttonbackground' << 'format'
+ end
+ private :__strval_optkeys
+
+ def __listval_optkeys
+ super() << 'values'
+ end
+ private :__listval_optkeys
+
+ def self.style(*args)
+ [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
+ end
+
+ def current
+ number(tk_send_without_enc('current'))
+ end
+ def current=(idx)
+ tk_send('current', idx)
+ end
+
+ def set(val)
+ tk_send('set', val)
+ end
+
+ alias identify ttk_identify
+end
+
+#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Spinbox, :TkSpinbox)
+Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/tspinbox.rb',
+ :Ttk, Tk::Tile::Spinbox, :TkSpinbox)
diff --git a/ext/tk/lib/tkextlib/tile/tsquare.rb b/ext/tk/lib/tkextlib/tile/tsquare.rb
index 600b55e4e7..a81cd7b98a 100644
--- a/ext/tk/lib/tkextlib/tile/tsquare.rb
+++ b/ext/tk/lib/tkextlib/tile/tsquare.rb
@@ -22,7 +22,7 @@ class Tk::Tile::TSquare < TkWindow
TkCommandNames = ['::tsquare'.freeze].freeze
end
WidgetClassName = 'TSquare'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def self.style(*args)
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
diff --git a/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb b/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb
index 522ebfb92c..b9ee90aace 100644
--- a/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb
+++ b/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb
@@ -36,7 +36,7 @@ end
class Tk::HTML_Widget::ClippingWindow
WidgetClassName = 'HtmlClip'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
HtmlClip_TBL = TkCore::INTERP.create_table
@@ -101,7 +101,7 @@ class Tk::HTML_Widget
TkCommandNames = ['html'.freeze].freeze
WidgetClassName = 'Html'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def create_self(keys)
if keys and keys != None
diff --git a/ext/tk/lib/tkextlib/tktable/tktable.rb b/ext/tk/lib/tkextlib/tktable/tktable.rb
index 12a2dd75bf..bc7a6c9a2e 100644
--- a/ext/tk/lib/tkextlib/tktable/tktable.rb
+++ b/ext/tk/lib/tkextlib/tktable/tktable.rb
@@ -74,6 +74,9 @@ module Tk::TkTable::ConfigMethod
end
private :__item_val2ruby_optkeys
+ def tag_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['tag', tagid(tagOrId)], option)
+ end
def tag_cget(tagOrId, option)
itemcget(['tag', tagid(tagOrId)], option)
end
@@ -90,6 +93,9 @@ module Tk::TkTable::ConfigMethod
current_itemconfiginfo(['tag', tagid(tagOrId)], slot)
end
+ def window_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['window', tagid(tagOrId)], option)
+ end
def window_cget(tagOrId, option)
itemcget(['window', tagid(tagOrId)], option)
end
@@ -114,7 +120,7 @@ module Tk::TkTable::ConfigMethod
current_itemconfiginfo(['window', tagid(tagOrId)], slot)
end
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
@@ -125,7 +131,7 @@ class Tk::TkTable::CellTag
CellTagID_TBL = TkCore::INTERP.create_table
- (CellTag_ID = ['tktbl:celltag'.freeze, '00000'.taint]).instance_eval{
+ (CellTag_ID = ['tktbl:celltag'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -197,6 +203,9 @@ class Tk::TkTable::CellTag
@t.tag_lower(@id, target)
end
+ def cget_tkstring(key)
+ @t.tag_cget_tkstring(@id, key)
+ end
def cget(key)
@t.tag_cget(@id, key)
end
@@ -253,7 +262,7 @@ end
class Tk::TkTable
TkCommandNames = ['table'.freeze].freeze
WidgetClassName = 'Table'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
include Scrollable
include Tk::TkTable::ConfigMethod
diff --git a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb
index 0c3de94baa..1879a531ae 100644
--- a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb
+++ b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb
@@ -322,7 +322,7 @@ module Tk::TreeCtrl::ConfigMethod
def __item_boolval_optkeys(id)
if id == 'debug'
- ['data', 'display', 'enable']
+ ['data', 'display', 'enable', 'span', 'textlayout']
elsif id == 'dragimage'
['visible']
elsif id == 'marquee'
@@ -330,7 +330,7 @@ module Tk::TreeCtrl::ConfigMethod
elsif id.kind_of?(Array)
case id[0]
when 'item'
- ['button', 'visible']
+ ['visible', 'wrap', 'open', 'returnid', 'visible']
when 'column'
if id[1] == 'drag'
['enable']
@@ -339,11 +339,11 @@ module Tk::TreeCtrl::ConfigMethod
'visible', 'widthhack']
end
when 'element'
- ['draw', 'filled', 'showfocus', 'destroy']
+ ['draw', 'filled', 'showfocus', 'clip', 'destroy']
when 'notify'
['active']
when 'style'
- ['detach']
+ ['detach', 'indent', 'visible']
else
if id[0].kind_of?(Array) && id[0][1] == 'element'
['filled', 'showfocus']
@@ -401,6 +401,20 @@ module Tk::TreeCtrl::ConfigMethod
end
private :__item_listval_optkeys
+ def __item_val2ruby_optkeys(id)
+ if id.kind_of?(Array)
+ case id[0]
+ when 'item'
+ { 'button' => proc{|id,val| (val == 'auto')? val: TkComm.bool(val)} }
+ else
+ []
+ end
+ else
+ []
+ end
+ end
+ private :__item_val2ruby_optkeys
+
def __item_keyonly_optkeys(id) # { def_key=>(undef_key|nil), ... }
{
'notreally'=>nil,
@@ -414,6 +428,9 @@ module Tk::TreeCtrl::ConfigMethod
end
private :__item_keyonly_optkeys
+ def column_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['column', tagOrId], option)
+ end
def column_cget(tagOrId, option)
itemcget(['column', tagOrId], option)
end
@@ -430,6 +447,9 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo(['column', tagOrId], slot)
end
+ def column_dragcget_tkstring(option)
+ itemcget_tkstring(['column', 'drag'], option)
+ end
def column_dragcget(option)
itemcget(['column', 'drag'], option)
end
@@ -446,6 +466,9 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo(['column', 'drag'], slot)
end
+ def debug_cget_tkstring(option)
+ itemcget_tkstring('debug', option)
+ end
def debug_cget(option)
itemcget('debug', option)
end
@@ -462,6 +485,9 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo('debug', slot)
end
+ def dragimage_cget_tkstring(option)
+ itemcget_tkstring('dragimage', option)
+ end
def dragimage_cget(option)
itemcget('dragimage', option)
end
@@ -478,6 +504,9 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo('dragimage', slot)
end
+ def element_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['element', tagOrId], option)
+ end
def element_cget(tagOrId, option)
itemcget(['element', tagOrId], option)
end
@@ -494,6 +523,9 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo(['element', tagOrId], slot)
end
+ def item_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['item', tagOrId], option)
+ end
def item_cget(tagOrId, option)
itemcget(['item', tagOrId], option)
end
@@ -510,6 +542,9 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo(['item', tagOrId], slot)
end
+ def item_element_cget_tkstring(item, column, elem, option)
+ itemcget_tkstring([['item', 'element'], [item, column, elem]], option)
+ end
def item_element_cget(item, column, elem, option)
itemcget([['item', 'element'], [item, column, elem]], option)
end
@@ -526,6 +561,9 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo([['item', 'element'], [item, column, elem]], slot)
end
+ def marquee_cget_tkstring(option)
+ itemcget_tkstring('marquee', option)
+ end
def marquee_cget(option)
itemcget('marquee', option)
end
@@ -542,6 +580,11 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo('marquee', slot)
end
+ def notify_cget_tkstring(win, pattern, option)
+ pattern = "<#{pattern}>"
+ # "notify" doesn't have cget subcommand.
+ tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(['notify', [win, pattern]])) << "-#{option}")), false, true)[-1]
+ end
def notify_cget(win, pattern, option)
pattern = "<#{pattern}>"
# "notify" doesn't have cget subcommand.
@@ -571,6 +614,9 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo(['notify', [win, pattern]], slot)
end
+ def style_cget_tkstring(tagOrId, option)
+ itemcget_tkstring(['style', tagOrId], option)
+ end
def style_cget(tagOrId, option)
itemcget(['style', tagOrId], option)
end
@@ -587,7 +633,7 @@ module Tk::TreeCtrl::ConfigMethod
current_itemconfiginfo(['style', tagOrId], slot)
end
- private :itemcget, :itemcget_strict
+ private :itemcget_tkstring, :itemcget, :itemcget_strict
private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
end
@@ -599,7 +645,7 @@ class Tk::TreeCtrl
TkCommandNames = ['treectrl'.freeze].freeze
WidgetClassName = 'TreeCtrl'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
#########################
@@ -631,7 +677,7 @@ class Tk::TreeCtrl
[
'itemwidthequal', 'usetheme',
'showbuttons', 'showheader', 'showlines', 'showroot',
- 'showrootbutton', 'showrootlines',
+ 'showrootbutton', 'showrootlines', 'showrootchildbuttons'
]
end
private :__boolval_optkeys
@@ -1547,8 +1593,8 @@ class Tk::TreeCtrl
self
end
- def see(item)
- tk_send('see', item)
+ def see(item, column=None, keys={})
+ tk_send('see', item, column, *hash_kv(keys))
self
end
@@ -1686,7 +1732,7 @@ end
class Tk::TreeCtrl::Column < TkObject
TreeCtrlColumnID_TBL = TkCore::INTERP.create_table
- (TreeCtrlColumnID = ['treectrl_column'.freeze, '00000'.taint]).instance_eval{
+ (TreeCtrlColumnID = ['treectrl_column'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -1741,6 +1787,9 @@ class Tk::TreeCtrl::Column < TkObject
@id.to_s.dup
end
+ def cget_tkstring(opt)
+ @tree.column_cget_tkstring(@tree.column_index(@id), opt)
+ end
def cget(opt)
@tree.column_cget(@tree.column_index(@id), opt)
end
@@ -1789,7 +1838,7 @@ end
class Tk::TreeCtrl::Element < TkObject
TreeCtrlElementID_TBL = TkCore::INTERP.create_table
- (TreeCtrlElementID = ['treectrl_element'.freeze, '00000'.taint]).instance_eval{
+ (TreeCtrlElementID = ['treectrl_element'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -1844,6 +1893,9 @@ class Tk::TreeCtrl::Element < TkObject
@id.dup
end
+ def cget_tkstring(opt)
+ @tree.element_cget_tkstring(@id, opt)
+ end
def cget(opt)
@tree.element_cget(@id, opt)
end
@@ -1978,6 +2030,9 @@ class Tk::TreeCtrl::Item < TkObject
self
end
+ def cget_tkstring(opt)
+ @tree.item_cget_tkstring(@id, opt)
+ end
def cget(opt)
@tree.item_cget(@id, opt)
end
@@ -2014,7 +2069,10 @@ class Tk::TreeCtrl::Item < TkObject
@tree.item_element_actual(@id, column, elem, key)
end
- def element_cget(opt)
+ def element_cget_tkstring(opt)
+ @tree.item_element_cget(@id, opt)
+ end
+ def element_cget_tkstring(opt)
@tree.item_element_cget(@id, opt)
end
def element_cget_strict(opt)
@@ -2218,7 +2276,7 @@ end
class Tk::TreeCtrl::Style < TkObject
TreeCtrlStyleID_TBL = TkCore::INTERP.create_table
- (TreeCtrlStyleID = ['treectrl_style'.freeze, '00000'.taint]).instance_eval{
+ (TreeCtrlStyleID = ['treectrl_style'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -2268,6 +2326,9 @@ class Tk::TreeCtrl::Style < TkObject
@id.dup
end
+ def cget_tkstring(opt)
+ @tree.style_cget_tkstring(@id, opt)
+ end
def cget(opt)
@tree.style_cget(@id, opt)
end
diff --git a/ext/tk/lib/tkextlib/version.rb b/ext/tk/lib/tkextlib/version.rb
index 82ed7ef542..3bc3ec5ae2 100644
--- a/ext/tk/lib/tkextlib/version.rb
+++ b/ext/tk/lib/tkextlib/version.rb
@@ -2,5 +2,5 @@
# release date of tkextlib
#
module Tk
- Tkextlib_RELEASE_DATE = '2008-11-25'.freeze
+ Tkextlib_RELEASE_DATE = '2009-07-12'.freeze
end
diff --git a/ext/tk/lib/tkextlib/vu/bargraph.rb b/ext/tk/lib/tkextlib/vu/bargraph.rb
index 1bcafc2887..b9fcf925f3 100644
--- a/ext/tk/lib/tkextlib/vu/bargraph.rb
+++ b/ext/tk/lib/tkextlib/vu/bargraph.rb
@@ -19,7 +19,7 @@ require 'tkextlib/vu.rb'
class Tk::Vu::Bargraph < TkWindow
TkCommandNames = ['::vu::bargraph'.freeze].freeze
WidgetClassName = 'Bargraph'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
###############################
diff --git a/ext/tk/lib/tkextlib/vu/dial.rb b/ext/tk/lib/tkextlib/vu/dial.rb
index e27a38ae42..eca0bbb67c 100644
--- a/ext/tk/lib/tkextlib/vu/dial.rb
+++ b/ext/tk/lib/tkextlib/vu/dial.rb
@@ -19,7 +19,7 @@ require 'tkextlib/vu.rb'
class Tk::Vu::Dial < TkWindow
TkCommandNames = ['::vu::dial'.freeze].freeze
WidgetClassName = 'Dial'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
###############################
diff --git a/ext/tk/lib/tkextlib/vu/pie.rb b/ext/tk/lib/tkextlib/vu/pie.rb
index c1fb6857bf..6b0c485d8a 100644
--- a/ext/tk/lib/tkextlib/vu/pie.rb
+++ b/ext/tk/lib/tkextlib/vu/pie.rb
@@ -37,7 +37,7 @@ end
class Tk::Vu::Pie < TkWindow
TkCommandNames = ['::vu::pie'.freeze].freeze
WidgetClassName = 'Pie'.freeze
- WidgetClassNames[WidgetClassName] = self
+ WidgetClassNames[WidgetClassName] ||= self
def __destroy_hook__
Tk::Vu::PieSlice::SliceID_TBL.delete(@path)
@@ -117,7 +117,7 @@ end
class Tk::Vu::PieSlice
SliceID_TBL = TkCore::INTERP.create_table
- (Pie_Slice_ID = ['vu:pie'.freeze, '00000'.taint]).instance_eval{
+ (Pie_Slice_ID = ['vu:pie'.freeze, TkUtil.untrust('00000')]).instance_eval{
@mutex = Mutex.new
def mutex; @mutex; end
freeze
@@ -173,6 +173,10 @@ class Tk::Vu::PieSlice
val
end
+ def cget_tkstring(slot)
+ @pie.itemcget_tkstring(@id, slot)
+ end
+
def cget(slot)
@pie.itemcget(@id, slot)
end
diff --git a/ext/tk/old-extconf.rb b/ext/tk/old-extconf.rb
new file mode 100644
index 0000000000..ebc83a0c0b
--- /dev/null
+++ b/ext/tk/old-extconf.rb
@@ -0,0 +1,440 @@
+# extconf.rb for tcltklib
+
+require 'mkmf'
+
+is_win32 = (/mswin|mingw|cygwin|bccwin/ =~ RUBY_PLATFORM)
+#is_macosx = (/darwin/ =~ RUBY_PLATFORM)
+
+have_func("ruby_native_thread_p", "ruby.h")
+have_func("rb_errinfo", "ruby.h")
+have_func("rb_safe_level", "ruby.h")
+have_struct_member("struct RArray", "ptr", "ruby.h")
+have_struct_member("struct RArray", "len", "ruby.h")
+
+def find_framework(tcl_hdr, tk_hdr)
+ if framework_dir = with_config("tcltk-framework")
+ paths = [framework_dir]
+ else
+ unless tcl_hdr || tk_hdr ||
+ enable_config("tcltk-framework", false) ||
+ enable_config("mac-tcltk-framework", false)
+ return false
+ end
+ paths = ["/Library/Frameworks", "/System/Library/Frameworks"]
+ end
+
+ checking_for('Tcl/Tk Framework') {
+ paths.find{|dir|
+ dir.strip!
+ dir.chomp!('/')
+ (tcl_hdr || FileTest.directory?(dir + "/Tcl.framework/") ) &&
+ (tk_hdr || FileTest.directory?(dir + "/Tk.framework/") )
+ }
+ }
+end
+
+tcl_framework_header = with_config("tcl-framework-header")
+tk_framework_header = with_config("tk-framework-header")
+
+tcltk_framework = find_framework(tcl_framework_header, tk_framework_header)
+
+unless is_win32
+ have_library("nsl", "t_open")
+ have_library("socket", "socket")
+ have_library("dl", "dlopen")
+ have_library("m", "log")
+end
+
+tk_idir, tk_ldir = dir_config("tk")
+tcl_idir, tcl_ldir = dir_config("tcl")
+x11_idir, x11_ldir = dir_config("X11")
+
+tk_ldir2 = with_config("tk-lib")
+tcl_ldir2 = with_config("tcl-lib")
+x11_ldir2 = with_config("X11-lib")
+
+tk_ldir_list = [tk_ldir2, tk_ldir]
+tcl_ldir_list = [tcl_ldir2, tcl_ldir]
+
+tklib = with_config("tklib")
+tcllib = with_config("tcllib")
+stubs = enable_config("tcltk_stubs") || with_config("tcltk_stubs")
+
+tcltk_version = with_config("tcltkversion")
+
+use_X = with_config("X11", (! is_win32))
+
+def parse_tclConfig(file)
+ # check tclConfig.sh/tkConfig.sh
+ tbl = {}
+ IO.foreach(file){|line|
+ line.strip!
+ next if line !~ /^([^\#=][^=]*)=(['"]|)(.*)\2$/
+ key, val = $1, $3
+ tbl[key] = val.gsub(/\$\{([^}]+)\}/){|s| tbl[$1]} rescue nil
+ }
+ tbl
+end
+
+def check_tcltk_version(version)
+ return [nil, nil] unless version
+
+ version = version.strip
+
+ tclver = version.dup
+ tkver = version.dup
+
+ major = dot = minor = dot = plvl = ext = nil
+
+ if version =~ /^(\d)(\.?)(\d)(\.?)(\d*)(.*)$/
+ major = $1; minor_dot = $2; minor = $3; plvl_dot = $4; plvl = $5; ext = $6
+ dot = ! minor_dot.empty?
+ if plvl_dot.empty? && ! plvl.empty?
+ minor << plvl
+ end
+ elsif version =~ /^(\d)(\.?)(\d?)(.*)$/
+ major = $1; minor_dot = $2; minor = $3; ext = $4
+ dot = ! minor_dot.empty?
+ else # unknown -> believe user
+ return [tclver, tkver]
+ end
+
+ # check Tcl7.6 / Tk4.2 ?
+ if major == "7" # Tcl7.6 ( not support Tclversion < 7.6 )
+ # Tk4.2
+ tkver = "4" + ((dot)? ".": "") + ((minor.empty)? "": "2") + ext
+ elsif major == "4" # Tk4.2 ( not support Tkversion < 4.2 )
+ # Tcl7.6
+ tclver = "7" + ((dot)? ".": "") + ((minor.empty)? "": "6") + ext
+ end
+
+ [tclver, tkver]
+end
+
+def find_tcl(tcllib, stubs, version, *opt_paths)
+ default_paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"]
+ default_paths << "/Tcl/lib" # default for ActiveTcl
+
+ if (paths = opt_paths.compact).empty?
+ paths = default_paths
+ end
+
+ if stubs
+ func = "Tcl_InitStubs"
+ lib = "tclstub"
+ else
+ func = "Tcl_FindExecutable"
+ lib = "tcl"
+ end
+
+ if version && ! version.empty?
+ versions = [version]
+ else
+ versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6]
+ end
+
+ if tcllib
+ st = find_library(tcllib, func, *paths)
+ else
+ st = versions.find { |ver|
+ find_library("#{lib}#{ver}", func, *paths) or
+ find_library("#{lib}#{ver.delete('.')}", func, *paths) or
+ find_library("#{lib}#{ver}g", func, *paths) or
+ find_library("#{lib}#{ver.delete('.')}g", func, *paths) or
+ find_library("tcl#{ver}", func, *paths) or
+ find_library("tcl#{ver.delete('.')}", func, *paths) or
+ find_library("tcl#{ver}g", func, *paths) or
+ find_library("tcl#{ver.delete('.')}g", func, *paths)
+ } || (!version && find_library(lib, func, *paths))
+ end
+
+ unless st
+ puts("Warning:: cannot find Tcl library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options.")
+ end
+ st
+end
+
+def find_tk(tklib, stubs, version, *opt_paths)
+ default_paths = ["/usr/local/lib", "/usr/pkg/lib", "/usr/lib"]
+ default_paths << "/Tcl/lib" # default for ActiveTcl
+
+ if (paths = opt_paths.compact).empty?
+ paths = default_paths
+ end
+
+ if stubs
+ func = "Tk_InitStubs"
+ lib = "tkstub"
+ else
+ func = "Tk_Init"
+ lib = "tk"
+ end
+
+ if version && ! version.empty?
+ versions = [version]
+ else
+ versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2]
+ end
+
+ if tklib
+ st = find_library(tklib, func, *paths)
+ else
+ st = versions.find { |ver|
+ find_library("#{lib}#{ver}", func, *paths) or
+ find_library("#{lib}#{ver.delete('.')}", func, *paths) or
+ find_library("#{lib}#{ver}g", func, *paths) or
+ find_library("#{lib}#{ver.delete('.')}g", func, *paths) or
+ find_library("tk#{ver}", func, *paths) or
+ find_library("tk#{ver.delete('.')}", func, *paths) or
+ find_library("tk#{ver}g", func, *paths) or
+ find_library("tk#{ver.delete('.')}g", func, *paths)
+ } || (!version && find_library(lib, func, *paths))
+ end
+
+ unless st
+ puts("Warning:: cannot find Tk library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options.")
+ end
+ st
+end
+
+def find_tcltk_header(tclver, tkver)
+ base_dir = ['/usr/local/include', '/usr/pkg/include', '/usr/include']
+ base_dir << '/Tcl/include' # default for ActiveTcl
+
+ unless have_tcl_h = have_header('tcl.h')
+ if tclver && ! tclver.empty?
+ versions = [tclver]
+ else
+ versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 7.6]
+ end
+ paths = base_dir.dup
+ versions.each{|ver| paths.concat(base_dir.map{|dir| dir + '/tcl' + ver})}
+ have_tcl_h = find_header('tcl.h', *paths)
+ end
+
+ unless have_tk_h = have_header("tk.h")
+ if tkver && ! tkver.empty?
+ versions = [tkver]
+ else
+ versions = %w[8.7 8.6 8.5 8.4 8.3 8.2 8.1 8.0 4.2]
+ end
+ paths = base_dir.dup
+ versions.each{|ver| paths.concat(base_dir.map{|dir| dir + '/tk' + ver})}
+ have_tk_h = find_header('tk.h', *paths)
+ end
+
+ have_tcl_h && have_tk_h
+end
+
+def find_X11(*opt_paths)
+ default_paths =
+ [ "/usr/X11/lib", "/usr/lib/X11", "/usr/X11R6/lib", "/usr/openwin/lib" ]
+ paths = opt_paths.compact.concat(default_paths)
+ st = find_library("X11", "XOpenDisplay", *paths)
+ unless st
+ puts("Warning:: cannot find X11 library. tcltklib will not be compiled (tcltklib is disabled on your Ruby == Ruby/Tk will not work). Please check configure options. If your Tcl/Tk don't require X11, please try --without-X11.")
+ end
+ st
+end
+
+def pthread_check()
+ tcl_major_ver = nil
+ tcl_minor_ver = nil
+
+ # Is tcl-thread given by user ?
+ case enable_config("tcl-thread")
+ when true
+ tcl_enable_thread = true
+ when false
+ tcl_enable_thread = false
+ else
+ tcl_enable_thread = nil
+ end
+
+ if (tclConfig = with_config("tclConfig-file"))
+ if tcl_enable_thread == true
+ puts("Warning: --with-tclConfig-file option is ignored, because --enable-tcl-thread option is given.")
+ elsif tcl_enable_thread == false
+ puts("Warning: --with-tclConfig-file option is ignored, because --disable-tcl-thread option is given.")
+ else
+ # tcl-thread is unknown and tclConfig.sh is given
+ begin
+ tbl = parse_tclConfig(tclConfig)
+ if tbl['TCL_THREADS']
+ tcl_enable_thread = (tbl['TCL_THREADS'] == "1")
+ else
+ tcl_major_ver = tbl['TCL_MAJOR_VERSION'].to_i
+ tcl_minor_ver = tbl['TCL_MINOR_VERSION'].to_i
+ if tcl_major_ver < 8 || (tcl_major_ver == 8 && tcl_minor_ver == 0)
+ tcl_enable_thread = false
+ end
+ end
+
+ if tcl_enable_thread == nil
+ # cannot find definition
+ if tcl_major_ver
+ puts("Warning: '#{tclConfig}' doesn't include TCL_THREADS definition.")
+ else
+ puts("Warning: '#{tclConfig}' may not be a tclConfig file.")
+ end
+ tclConfig = false
+ end
+ rescue Exception
+ puts("Warning: fail to read '#{tclConfig}'!! --> ignore the file")
+ tclConfig = false
+ end
+ end
+ end
+
+ if tcl_enable_thread == nil && !tclConfig
+ # tcl-thread is unknown and tclConfig is unavailable
+ begin
+ try_run_available = try_run("int main() { exit(0); }")
+ rescue Exception
+ # cannot try_run. Is CROSS-COMPILE environment?
+ puts(%Q'\
+*****************************************************************************
+**
+** PTHREAD SUPPORT CHECK WARNING:
+**
+** We cannot check the consistency of pthread support between Ruby
+** and the Tcl/Tk library in your environment (are you perhaps
+** cross-compiling?). If pthread support for these 2 packages is
+** inconsistent you may find you get errors when running Ruby/Tk
+** (e.g. hangs or segmentation faults). We strongly recommend
+** you to check the consistency manually.
+**
+*****************************************************************************
+')
+ return true
+ end
+ end
+
+ if tcl_enable_thread == nil
+ # tcl-thread is unknown
+ if try_run(<<EOF)
+#include <tcl.h>
+int main() {
+ Tcl_Interp *ip;
+ ip = Tcl_CreateInterp();
+ exit((Tcl_Eval(ip, "set tcl_platform(threaded)") == TCL_OK)? 0: 1);
+}
+EOF
+ tcl_enable_thread = true
+ elsif try_run(<<EOF)
+#include <tcl.h>
+static Tcl_ThreadDataKey dataKey;
+int main() { exit((Tcl_GetThreadData(&dataKey, 1) == dataKey)? 1: 0); }
+EOF
+ tcl_enable_thread = true
+ else
+ tcl_enable_thread = false
+ end
+ end
+
+ # check pthread mode
+ if (macro_defined?('HAVE_NATIVETHREAD', '#include "ruby.h"'))
+ # ruby -> enable
+ unless tcl_enable_thread
+ # ruby -> enable && tcl -> disable
+ puts(%Q'\
+*****************************************************************************
+**
+** PTHREAD SUPPORT MODE WARNING:
+**
+** Ruby is compiled with --enable-pthread, but your Tcl/Tk library
+** seems to be compiled without pthread support. Although you can
+** create the tcltklib library, this combination may cause errors
+** (e.g. hangs or segmentation faults). If you have no reason to
+** keep the current pthread support status, we recommend you reconfigure
+** and recompile the libraries so that both or neither support pthreads.
+**
+** If you want change the status of pthread support, please recompile
+** Ruby without "--enable-pthread" configure option or recompile Tcl/Tk
+** with "--enable-threads" configure option (if your Tcl/Tk is later
+** than or equal to Tcl/Tk 8.1).
+**
+*****************************************************************************
+')
+ end
+
+ # ruby -> enable && tcl -> enable/disable
+ if tcl_enable_thread
+ $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=1'
+ else
+ $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=0'
+ end
+
+ return true
+
+ else
+ # ruby -> disable
+ if tcl_enable_thread
+ # ruby -> disable && tcl -> enable
+ puts(%Q'\
+*****************************************************************************
+**
+** PTHREAD SUPPORT MODE ERROR:
+**
+** Ruby is not compiled with --enable-pthread, but your Tcl/Tk
+** library seems to be compiled with pthread support. This
+** combination may cause frequent hang or segmentation fault
+** errors when Ruby/Tk is working. We recommend that you NEVER
+** create the library with such a combination of pthread support.
+**
+** Please recompile Ruby with the "--enable-pthread" configure option
+** or recompile Tcl/Tk with the "--disable-threads" configure option.
+**
+*****************************************************************************
+')
+ $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=1'
+ return false
+ else
+ # ruby -> disable && tcl -> disable
+ $CPPFLAGS += ' -DWITH_TCL_ENABLE_THREAD=0'
+ return true
+ end
+ end
+end
+
+tclver, tkver = check_tcltk_version(tcltk_version)
+
+if ( tcltk_framework ||
+ ( find_tcltk_header(tclver, tkver) &&
+ ( !use_X || find_X11(x11_ldir2, x11_ldir) ) &&
+ find_tcl(tcllib, stubs, tclver, *tcl_ldir_list) &&
+ find_tk(tklib, stubs, tkver, *tk_ldir_list) ) )
+ $CPPFLAGS += ' -DUSE_TCL_STUBS -DUSE_TK_STUBS' if stubs
+ $CPPFLAGS += ' -D_WIN32' if /cygwin/ =~ RUBY_PLATFORM
+
+ if tcltk_framework
+ if tcl_framework_header
+ $CPPFLAGS += " -I#{tcl_framework_header}"
+ else
+ $CPPFLAGS += " -I#{tcltk_framework}/Tcl.framework/Headers"
+ end
+
+ if tk_framework_header
+ $CPPFLAGS += " -I#{tk_framework_header}"
+ else
+ $CPPFLAGS += " -I#{tcltk_framework}/Tk.framework/Headers"
+ end
+
+ $LDFLAGS += ' -framework Tk -framework Tcl'
+ end
+
+ if stubs or pthread_check
+ # create Makefile
+
+ # for SUPPORT_STATUS
+ $INSTALLFILES ||= []
+ $INSTALLFILES << ["lib/tkextlib/SUPPORT_STATUS", "$(RUBYLIBDIR)", "lib"]
+
+ have_func("rb_hash_lookup", "ruby.h")
+
+ # create
+ $defs << %[-DRUBY_VERSION=\\"#{RUBY_VERSION}\\"]
+ $defs << %[-DRUBY_RELEASE_DATE=\\"#{RUBY_RELEASE_DATE}\\"]
+ create_makefile("tcltklib")
+ end
+end
diff --git a/ext/tk/sample/demos-en/widget b/ext/tk/sample/demos-en/widget
index 9a0605d8b9..250c589116 100644
--- a/ext/tk/sample/demos-en/widget
+++ b/ext/tk/sample/demos-en/widget
@@ -170,9 +170,12 @@ else
}
scr.command(proc{|*args| txt.yview(*args)})
# txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both', 'padx'=>1)
- txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both')
+# txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both')
# textFrame.pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>2)
textFrame.pack('expand'=>'yes', 'fill'=>'both')
+ # $root.withdraw.deiconify
+ Tk.update_idletasks
+ txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both')
statusBar = TkFrame.new($root) {|f|
if $tk_version =~ /^4.*/
@@ -1035,7 +1038,7 @@ end
#
def aboutBox
Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo',
- 'message'=>"Ruby/Tk widget demonstration Ver.1.7.0-en\n\n" +
+ 'message'=>"Ruby/Tk widget demonstration Ver.1.7.1-en\n\n" +
"based on demos of Tk8.1 -- 8.5 " +
"( Copyright of Tcl/Tk demos:: " +
"(c) 1996-1997 Sun Microsystems, Inc. / " +
diff --git a/ext/tk/sample/demos-jp/widget b/ext/tk/sample/demos-jp/widget
index 132953f32d..dfaa9c004e 100644
--- a/ext/tk/sample/demos-jp/widget
+++ b/ext/tk/sample/demos-jp/widget
@@ -190,10 +190,14 @@ else
yscrollcommand proc{|first,last| scr.set first,last}
}
scr.command(proc{|*args| txt.yview(*args)})
+
# txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both', 'padx'=>1)
- txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both')
+# txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both')
# textFrame.pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>2)
textFrame.pack('expand'=>'yes', 'fill'=>'both')
+ # $root.withdraw.deiconify
+ Tk.update_idletasks
+ txt.pack('in'=>textFrame, 'expand'=>'yes', 'fill'=>'both')
statusBar = TkFrame.new($root) {|f|
if $tk_version =~ /^4.*/
@@ -1070,7 +1074,7 @@ end
#
def aboutBox
Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo',
- 'message'=>"Ruby/Tk ¥¦¥£¥¸¥§¥Ã¥È¥Ç¥â Ver.1.7.0-jp\n\n" +
+ 'message'=>"Ruby/Tk ¥¦¥£¥¸¥§¥Ã¥È¥Ç¥â Ver.1.7.1-jp\n\n" +
"based on demos of Tk8.1 -- 8.5 " +
"( Copyright of Tcl/Tk demos:: " +
"(c) 1996-1997 Sun Microsystems, Inc. / " +
diff --git a/ext/tk/sample/editable_listbox.rb b/ext/tk/sample/editable_listbox.rb
index 553d400e24..7a9ad4450b 100644
--- a/ext/tk/sample/editable_listbox.rb
+++ b/ext/tk/sample/editable_listbox.rb
@@ -1,5 +1,5 @@
#
-# Editable_TkListbox class
+# Tk::RbWidget::Editable_Listbox class
#
# When "DoubleClick-1" on a listbox item, the entry box is opend on the
# item. And when hit "Return" key on the entry box after modifying the
@@ -10,19 +10,106 @@
#
require 'tk'
-class Editable_TkListbox < TkListbox
- def _ebox_placer(coord_y)
- idx = self.nearest(coord_y)
- x, y, w, h = self.bbox(idx)
+module Tk
+ module RbWidget
+ class Editable_Listbox < TkListbox
+ end
+ end
+end
+
+
+class Tk::RbWidget::Editable_Listbox < TkListbox
+ #------------------------------------
+ BindTag = TkBindTag.new_by_name(self.to_s.gsub(/::/, '#'))
+
+ BindTag.bind('FocusIn', :widget){|w|
+ w.instance_eval{
+ if idx = @ebox.pos
+ see(idx) if bbox(idx).empty?
+ @ebox.focus(true)
+ end
+ }
+ }
+
+ BindTag.bind('Double-1', :widget, :y){|w, y|
+ w.instance_eval{ _ebox_placer(nearest(y)) }
+ }
+
+ BindTag.bind('Return', :widget){|w|
+ w.instance_eval{
+ if idx = index(:active)
+ _ebox_placer(idx)
+ end
+ }
+ }
+ #------------------------------------
+
+ def configure(*args)
+ ret = super
+
+ case cget(:state)
+ when 'normal'
+ # do nothing
+ when 'disabled'
+ _ebox_erase
+ else # unknown
+ # do nothing
+
+ end
+
+ ret
+ end
+
+ def _ebox_move(idx)
+ return nil if cget(:state) == 'disabled'
+ x, y, w, h = bbox(idx)
+ return nil unless y && h
@ebox.place(:x => 0, :relwidth => 1.0,
- :y => y - self.selectborderwidth,
- :height => h + 2 * self.selectborderwidth)
+ :y => y - selectborderwidth,
+ :height => h + 2 * selectborderwidth)
@ebox.pos = idx
- @ebox.value = self.listvariable.list[idx]
@ebox.focus
end
- private :_ebox_placer
+ def _ebox_placer(idx)
+ return nil unless _ebox_move(idx)
+ @ebox.value = listvariable.list[idx]
+ @ebox.xview_moveto(self.xview[0])
+ end
+
+ def _ebox_erase
+ @ebox.place_forget
+ @ebox.pos = nil
+ end
+ private :_ebox_move, :_ebox_placer, :_ebox_erase
+
+ def _setup_ebox_bindings
+ # bindings for entry
+ @ebox.bind('Return'){
+ list = listvariable.list
+ list[@ebox.pos] = @ebox.value if @ebox.pos
+ listvariable.value = list
+ _ebox_erase
+ focus
+ }
+
+ @ebox.bind('Escape'){ _ebox_erase }
+ end
+ def _setup_listbox_bindings
+ # bindings for listbox
+ tags = bindtags
+ bindtags(tags.insert(tags.index(self) + 1, self.class::BindTag))
+ end
+ private :_setup_ebox_bindings, :_setup_listbox_bindings
+
+ def yview(*args)
+ if !@ebox.pos || bbox(@ebox.pos).empty?
+ @ebox.place_forget
+ else
+ _ebox_move(@ebox.pos)
+ end
+ super
+ end
def create_self(keys)
super(keys)
@@ -32,38 +119,30 @@ class Editable_TkListbox < TkListbox
end
@ebox = TkEntry.new(self){
- @pos = -1
+ @pos = nil
def self.pos; @pos; end
def self.pos=(idx); @pos = idx; end
}
- @ebox.bind('Return'){
- list = self.listvariable.list
- list[@ebox.pos] = @ebox.value
- self.listvariable.value = list
- @ebox.place_forget
- @ebox.pos = -1
- }
-
- @ebox.bind('Escape'){
- @ebox.place_forget
- @ebox.pos = -1
- }
-
- self.bind('Double-1', '%y'){|y| _ebox_placer(y) }
+ _setup_ebox_bindings
+ _setup_listbox_bindings
end
end
if $0 == __FILE__
+ #lbox0 = TkListbox.new.pack(:side=>:left)
+ #lbox0.insert(:end, 0,1,2,3,4,5,6,7,8,9,0,1,2,3)
+
scr = TkScrollbar.new.pack(:side=>:right, :fill=>:y)
- lbox1 = Editable_TkListbox.new.pack(:side=>:left)
- lbox2 = Editable_TkListbox.new.pack(:side=>:left)
+ lbox1 = Tk::RbWidget::Editable_Listbox.new.pack(:side=>:left)
+ lbox2 = Tk::RbWidget::Editable_Listbox.new.pack(:side=>:left)
scr.assign(lbox1, lbox2)
lbox1.insert(:end, *%w(a b c d e f g h i j k l m n))
lbox2.insert(:end, 0,1,2,3,4,5,6,7,8,9,0,1,2,3)
+
Tk.mainloop
end
diff --git a/ext/tk/sample/menubar3.rb b/ext/tk/sample/menubar3.rb
new file mode 100644
index 0000000000..129cfd779b
--- /dev/null
+++ b/ext/tk/sample/menubar3.rb
@@ -0,0 +1,72 @@
+#
+# menubar sample 3 : vertical layout menubar; use frame and menubuttons
+#
+
+require 'tk'
+
+radio_var = TkVariable.new('y')
+
+menu_spec = [
+ [['&File', true], # when underline option is ture, '&' index is the position
+ {:label=>'Open', :command=>proc{puts('Open clicked')}, :underline=>0},
+ '---',
+ ['Check_A', TkVariable.new(true), 6],
+ {:type=>'checkbutton', :label=>'Check_B',
+ :variable=>TkVariable.new, :underline=>6},
+ '---',
+ ['Radio_X', [radio_var, 'x'], /[XYZ]/, '', {:foreground=>'black'}],
+ ['Radio_Y', [radio_var, 'y'], /[XYZ]/],
+ ['Radio_Z', [radio_var, 'z'], /[XYZ]/], # use Regexp for underline position
+ '---',
+ ['cascade', [
+ ['sss', proc{p 'sss'}, 0],
+ ['ttt', proc{p 'ttt'}, 0],
+ ['uuu', proc{p 'uuu'}, 0],
+ ['vvv', proc{p 'vvv'}, 0],
+ ],
+ 0, '',
+ {:font=>'Courier 16 italic',
+ :menu_config=>{:font=>'Times -18 bold', :foreground=>'black'}}],
+ '---',
+ ['Quit', proc{exit}, 0]],
+
+ [['Edit', 0],
+ ['Cut', proc{puts('Cut clicked')}, 2],
+ ['Copy', proc{puts('Copy clicked')}, 0],
+ ['Paste', proc{puts('Paste clicked')}, 0]],
+
+ [['Help', 0, {:menu_name=>'help'}],
+ ['About This', proc{puts('Ruby/Tk menubar sample 3')}, "This"]]
+ # use string index for underline position
+]
+
+layout_proc = 'vertical'
+# The following procedure is same to 'layout_proc'=>'vertical'
+=begin
+layout_proc = proc{|parent, mbtn|
+ mbtn.direction :right
+ mbtn.pack(:side=>:top, :fill=>:x)
+
+ menu = mbtn.menu
+ cmd = proc{|m, dir|
+ Tk::Menu::TkInternalFunction.next_menu(m, dir) rescue nil
+ # ignore error when the internal function doesn't exist
+ }
+ menu.bind('Tab', cmd, :widget, 'forward')
+ menu.bind('Alt-Tab', cmd, :widget, 'backward')
+}
+=end
+
+menubar = TkMenubar.new(nil, menu_spec,
+ 'layout_proc'=>layout_proc,
+ 'tearoff'=>false,
+ 'foreground'=>'grey40',
+ 'activeforeground'=>'red',
+ 'font'=>'Helvetia 12 bold')
+menubar.pack('side'=>'left', 'fill'=>'y')
+
+TkText.new(:wrap=>'word').pack.insert('1.0', 'This sample script generates "Menu Sidebar".
+If "::tk::MenuNextMenuon" function is available your Tcl/Tk library, you will be able to move to the next menu by Tab key on the posted menu, or the previous menu by Alt + Tab key.
+Please read the sample source, and check how to override default configure options of menu entries on a menu_spec. Maybe, on windows, this menubar does not work properly about keyboard shortcuts. Then, please use "menu" option of root/toplevel widget (see sample/menubar3.rb).')
+
+Tk.mainloop
diff --git a/ext/tk/sample/multi-ip_sample.rb b/ext/tk/sample/multi-ip_sample.rb
index 8150e69c73..eccf0201f8 100644
--- a/ext/tk/sample/multi-ip_sample.rb
+++ b/ext/tk/sample/multi-ip_sample.rb
@@ -19,7 +19,6 @@ cmd = Proc.new{|txt|
else
root = TkRoot.new(:title=>'timer sample')
end
-
label = TkLabel.new(:parent=>root, :relief=>:raised, :width=>10) \
.pack(:side=>:bottom, :fill=>:both)
@@ -48,6 +47,7 @@ cmd = Proc.new{|txt|
b_start = TkButton.new(:text=>'Start', :state=>:disabled) {
pack(:side=>:left, :fill=>:both, :expand=>true)
}
+
b_stop = TkButton.new(:text=>'Stop', :state=>:normal) {
pack('side'=>'left', 'fill'=>'both', 'expand'=>'yes')
}
@@ -80,6 +80,7 @@ safe_slave2.eval_proc(cmd, 'safe2') # label -> .w00020
cmd.call('master') # label -> .w00024
#second_master = MultiTkIp.new(&cmd)
+#second_master = MultiTkIp.new(:safe=>2){p [:second_master, $SAFE]}
TkTimer.new(2000, -1, proc{p ['safe1', safe_slave1.deleted?]}).start
TkTimer.new(2000, -1, proc{p ['safe2', safe_slave2.deleted?]}).start
diff --git a/ext/tk/sample/safe-tk.rb b/ext/tk/sample/safe-tk.rb
index e2408480d1..148548efb2 100644
--- a/ext/tk/sample/safe-tk.rb
+++ b/ext/tk/sample/safe-tk.rb
@@ -11,13 +11,16 @@ TkFrame.new(:borderwidth=>2, :height=>3,
:relief=>:sunken).pack(:fill=>:x, :expand=>true,
:padx=>10, :pady=>7)
+safe0_p = proc{|*args| p args}
+
###############################
puts "---- create a safe slave IP with Ruby's safe-level == 1 ----------"
-ip = MultiTkIp.new_safe_slave(1)
+ip = MultiTkIp.new_safe_slave(1){|*args| safe0_p["safe_slave safe_level == #{$SAFE}", args]}
puts "\n---- create procs ----------"
puts 'x = proc{p [\'proc x\', "$SAFE==#{$SAFE}"]; exit}'
+#x = proc{p ['proc x', "$SAFE==#{$SAFE}"]; exit}
x = proc{p ['proc x', "$SAFE==#{$SAFE}"]; exit}
TkLabel.new(:text=>'x = proc{p [\'proc x\', "$SAFE==#{$SAFE}"]; exit}',
:anchor=>:w).pack(:fill=>:x)
@@ -46,7 +49,9 @@ p lbl = ip.eval_proc{
:command=>proc{l.text($SAFE)}).pack(:fill=>:x, :padx=>5)
TkButton.new(:text=>':command=>x', :command=>x).pack(:fill=>:x, :padx=>5)
TkButton.new(:text=>':command=>proc{exit}',
- :command=>proc{exit}).pack(:fill=>:x, :padx=>5)
+ :command=>proc{
+ safe0_p["'exit' is called at $SAFE=#{$SAFE}"];exit}
+ ).pack(:fill=>:x, :padx=>5)
TkFrame.new(:borderwidth=>2, :height=>3,
:relief=>:sunken).pack(:fill=>:x, :expand=>true,
:padx=>10, :pady=>7)
@@ -68,10 +73,24 @@ p ip.eval_proc(proc{
TkButton.new(:text=>':command=>proc{y.call(l)}',
:command=>proc{y.call(l)}).pack(:fill=>:x,
:padx=>5)
+ TkButton.new(:text=>':command=>proc{Proc.new(&y).call(l)}',
+ :command=>proc{
+ Proc.new(&y).call(l)
+ }).pack(:fill=>:x, :padx=>5)
+ TkButton.new(:text=>':command=>proc{MultiTkIp._proc_on_current_safelevel(y).call(l)}',
+ :command=>proc{
+ MultiTkIp._proc_on_current_safelevel(y).call(l)
+ }).pack(:fill=>:x, :padx=>5)
+if Object.const_defined?(:RubyVM) && ::RubyVM.class == Class
TkButton.new(:text=>':command=>proc{Thread.new(l, &y).value}',
:command=>proc{
Thread.new(l, &y).value
}).pack(:fill=>:x, :padx=>5)
+else
+ # KNOWN BUG::
+ # Current multi-tk.rb cannot support long term threads on callbacks.
+ # Such a thread freezes the Ruby/Tk process.
+end
TkButton.new(:text=>':command=>proc{z.call}',
:command=>proc{z.call}).pack(:fill=>:x, :padx=>5)
TkFrame.new(:borderwidth=>2, :height=>3,
diff --git a/ext/tk/sample/scrollframe.rb b/ext/tk/sample/scrollframe.rb
index ab7a9ce24b..6a9381d465 100644
--- a/ext/tk/sample/scrollframe.rb
+++ b/ext/tk/sample/scrollframe.rb
@@ -1,11 +1,11 @@
#
-# Tk::ScrollFrame class
+# Tk::RbWidget::ScrollFrame class
#
# This widget class is a frame widget with scrollbars.
# The ScrollFrame doesn't propagate the size of embedded widgets.
# When it is configured, scrollregion of the container is changed.
#
-# Scrollbars can be toggled by Tk::ScrollFrame#vscroll & hscroll.
+# Scrollbars can be toggled by Tk::RbWidget::ScrollFrame#vscroll & hscroll.
# If horizontal or virtical scrollbar is turned off, the horizontal
# or virtical size of embedded widgets is propagated.
#
@@ -13,7 +13,7 @@
#
require 'tk'
-class Tk::ScrollFrame < TkFrame
+class Tk::RbWidget::ScrollFrame < TkFrame
include TkComposite
DEFAULT_WIDTH = 200
@@ -209,7 +209,8 @@ end
# test
if __FILE__ == $0
- f = Tk::ScrollFrame.new(:scrollbarwidth=>10, :width=>300, :height=>200)
+ f = Tk::RbWidget::ScrollFrame.new(:scrollbarwidth=>10,
+ :width=>300, :height=>200)
f.pack(:expand=>true, :fill=>:both)
TkButton.new(f, :text=>'foo button', :command=>proc{puts 'foo'}).pack
@@ -220,17 +221,26 @@ if __FILE__ == $0
# f.hscroll(false)
+ # add a text widget
Tk.after(3000){
t = TkText.new(f).pack(:expand=>true, :fill=>:both)
- t.insert(:end, 'Here is a text widget')
+ t.insert(:end, "An example of Tk::RbWidget::ScrollFrame widget.\n\n")
+ t.insert(:end, "Here is a text widget.\n")
+ t.insert(:end, "Please resize the application window, ")
+ t.insert(:end, "and try the scrollbars ")
+ t.insert(:end, "to move the view of packed widgets.\n")
}
+ # remove a vertical scrollbar, and then the scrollframe is not scrollable.
Tk.after(6000){ f.vscroll(false) }
+ # add a vertical scrollbar, and make the scrollframe scrollable.
Tk.after(9000){ f.vscroll(true) }
+ # remove a horizontal scrollbar, and then the scrollframe is not scrollable.
Tk.after(12000){ f.hscroll(false) }
+ # add a horizontal scrollbar, and make the scrollframe scrollable.
Tk.after(15000){ f.hscroll(true) }
Tk.mainloop
diff --git a/ext/tk/sample/tkalignbox.rb b/ext/tk/sample/tkalignbox.rb
index dd82b50360..fb1b58f458 100644
--- a/ext/tk/sample/tkalignbox.rb
+++ b/ext/tk/sample/tkalignbox.rb
@@ -10,10 +10,17 @@
require 'tk'
-class TkAlignBox < TkFrame
+module Tk
+ module RbWidget
+ class AlignBox < TkFrame
+ end
+ end
+end
+
+class Tk::RbWidget::AlignBox < TkFrame
def initialize(*args)
- if self.class == TkAlignBox
- fail RuntimeError, "TkAlignBox is an abstract class"
+ if self.class == Tk::RbWidget::AlignBox
+ fail RuntimeError, "Tk::AlignBox is an abstract class"
end
@padx = 0
@pady = 0
@@ -31,12 +38,12 @@ class TkAlignBox < TkFrame
end
def _set_framesize
- fail RuntimeError, "TkAlignBox is an abstract class"
+ fail RuntimeError, "Tk::AlignBox is an abstract class"
end
private :_set_framesize
def _place_config(widget, idx, cnt)
- fail RuntimeError, "TkAlignBox is an abstract class"
+ fail RuntimeError, "Tk::AlignBox is an abstract class"
end
private :_place_config
@@ -117,7 +124,7 @@ class TkAlignBox < TkFrame
attr_accessor :propagate
end
-class TkHBox < TkAlignBox
+class Tk::RbWidget::HBox < Tk::RbWidget::AlignBox
def _set_framesize
bd = self.borderwidth
self.width((@max_width + 2*@padx) * @widgets.size + 2*bd)
@@ -134,9 +141,9 @@ class TkHBox < TkAlignBox
end
private :_place_config
end
-TkHLBox = TkHBox
+Tk::RbWidget::HLBox = Tk::RbWidget::HBox
-class TkHRBox < TkHBox
+class Tk::RbWidget::HRBox < Tk::RbWidget::HBox
def _place_config(widget, idx, cnt)
widget.place_in(self,
'relx'=>(cnt - idx - 1)/cnt, 'x'=>@padx,
@@ -147,7 +154,7 @@ class TkHRBox < TkHBox
private :_place_config
end
-class TkVBox < TkAlignBox
+class Tk::RbWidget::VBox < Tk::RbWidget::AlignBox
def _set_framesize
bd = self.borderwidth
self.width(@max_width + 2*@padx + 2*bd)
@@ -164,9 +171,9 @@ class TkVBox < TkAlignBox
end
private :_place_config
end
-TkVTBox = TkVBox
+Tk::RbWidget::VTBox = Tk::RbWidget::VBox
-class TkVBBox < TkVBox
+class Tk::RbWidget::VBBox < Tk::RbWidget::VBox
def _place_config(widget, idx, cnt)
widget.place_in(self,
'relx'=>0, 'x'=>@padx,
@@ -181,31 +188,34 @@ end
# test
################################################
if __FILE__ == $0
- f = TkHBox.new(:borderwidth=>3, :relief=>'ridge').pack
+ f = Tk::RbWidget::HBox.new(:borderwidth=>3, :relief=>'ridge').pack
f.add(TkButton.new(f, :text=>'a'),
TkButton.new(f, :text=>'aa', :font=>'Helvetica 16'),
TkButton.new(f, :text=>'aaa'),
TkButton.new(f, :text=>'aaaa'))
- f = TkHBox.new(:borderwidth=>3, :relief=>'ridge',
- :padx=>7, :pady=>3, :background=>'yellow').pack
+ f = Tk::RbWidget::HBox.new(:borderwidth=>3, :relief=>'ridge',
+ :padx=>7, :pady=>3, :background=>'yellow').pack
f.add(TkButton.new(f, :text=>'a'),
TkButton.new(f, :text=>'aa', :font=>'Helvetica 16'),
TkButton.new(f, :text=>'aaa'),
TkButton.new(f, :text=>'aaaa'))
- f = TkVBox.new(:borderwidth=>5, :relief=>'groove').pack
+ f = Tk::RbWidget::VBox.new(:borderwidth=>5,
+ :relief=>'groove').pack(:fill=>:y, :expand=>true)
f.add(TkButton.new(f, :text=>'a'),
TkButton.new(f, :text=>'aa', :font=>'Helvetica 30'),
TkButton.new(f, :text=>'aaa'),
TkButton.new(f, :text=>'aaaa'))
- f = TkHRBox.new(:borderwidth=>3, :relief=>'raised').pack(:fill=>:x)
+ f = Tk::RbWidget::HRBox.new(:borderwidth=>3,
+ :relief=>'raised').pack(:fill=>:x)
f.add(TkButton.new(f, :text=>'a'),
TkButton.new(f, :text=>'aa'),
TkButton.new(f, :text=>'aaa'))
- f = TkVBBox.new(:borderwidth=>3, :relief=>'ridge').pack(:fill=>:x)
+ f = Tk::RbWidget::VBBox.new(:borderwidth=>3,
+ :relief=>'ridge').pack(:fill=>:x)
f.propagate = false
f.height 100
f.add(TkFrame.new(f){|ff|
diff --git a/ext/tk/sample/tkballoonhelp.rb b/ext/tk/sample/tkballoonhelp.rb
index fc99753b81..a9bd371db6 100644
--- a/ext/tk/sample/tkballoonhelp.rb
+++ b/ext/tk/sample/tkballoonhelp.rb
@@ -7,11 +7,21 @@
# please try to use the Tix extension of Tcl/Tk under Ruby/Tk.
#
# The interval time to display a balloon help is defined 'interval' option
-# (default is 1000ms).
+# (default is 750ms).
#
require 'tk'
-class TkBalloonHelp<TkLabel
+module Tk
+ module RbWidget
+ class BalloonHelp<TkLabel
+ end
+ end
+end
+class Tk::RbWidget::BalloonHelp<TkLabel
+ DEFAULT_FOREGROUND = 'black'
+ DEFAULT_BACKGROUND = 'white'
+ DEFAULT_INTERVAL = 750
+
def _balloon_binding(interval)
@timer = TkAfter.new(interval, 1, proc{show})
def @timer.interval(val)
@@ -50,10 +60,13 @@ class TkBalloonHelp<TkLabel
@command = keys.delete('command')
- @interval = keys.delete('interval'){1000}
+ @interval = keys.delete('interval'){DEFAULT_INTERVAL}
_balloon_binding(@interval)
- @label = TkLabel.new(@frame, 'background'=>'bisque').pack
+ # @label = TkLabel.new(@frame, 'background'=>'bisque').pack
+ @label = TkLabel.new(@frame,
+ 'foreground'=>DEFAULT_FOREGROUND,
+ 'background'=>DEFAULT_BACKGROUND).pack
@label.configure(_symbolkey2str(keys)) unless keys.empty?
@path = @label
end
@@ -118,41 +131,42 @@ end
if __FILE__ == $0
TkButton.new('text'=>'This button has a balloon help') {|b|
pack('fill'=>'x')
- TkBalloonHelp.new(b, 'text'=>' Message ')
+ Tk::RbWidget::BalloonHelp.new(b, 'text'=>' Message ')
}
TkButton.new('text'=>'This button has another balloon help') {|b|
pack('fill'=>'x')
- TkBalloonHelp.new(b, 'text'=>'configured message',
- 'interval'=>200, 'font'=>'courier',
- 'background'=>'gray', 'foreground'=>'red')
+ Tk::RbWidget::BalloonHelp.new(b,
+ 'text'=>"CONFIGURED MESSAGE\nchange colors, and so on",
+ 'interval'=>200, 'font'=>'courier',
+ 'background'=>'gray', 'foreground'=>'red')
}
sb = TkScrollbox.new.pack(:fill=>:x)
sb.insert(:end, *%w(aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm))
=begin
# CASE1 : command takes no arguemnt
- bh = TkBalloonHelp.new(sb, :interval=>500,
- :relief=>:ridge, :background=>'white',
- :command=>proc{
- y = TkWinfo.pointery(sb) - TkWinfo.rooty(sb)
- bh.text "current index == #{sb.nearest(y)}"
- })
+ bh = Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
+ :relief=>:ridge, :background=>'white',
+ :command=>proc{
+ y = TkWinfo.pointery(sb) - TkWinfo.rooty(sb)
+ bh.text "current index == #{sb.nearest(y)}"
+ })
=end
=begin
# CASE2 : command takes 2 arguemnts
- bh = TkBalloonHelp.new(sb, :interval=>500,
- :relief=>:ridge, :background=>'white',
- :command=>proc{|x, y|
- bh.text "current index == #{sb.nearest(y)}"
- })
+ bh = Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
+ :relief=>:ridge, :background=>'white',
+ :command=>proc{|x, y|
+ bh.text "current index == #{sb.nearest(y)}"
+ })
=end
=begin
# CASE3 : command takes 3 arguemnts
- TkBalloonHelp.new(sb, :interval=>500,
- :relief=>:ridge, :background=>'white',
- :command=>proc{|x, y, bhelp|
- bhelp.text "current index == #{sb.nearest(y)}"
- })
+ Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
+ :relief=>:ridge, :background=>'white',
+ :command=>proc{|x, y, bhelp|
+ bhelp.text "current index == #{sb.nearest(y)}"
+ })
=end
=begin
# CASE4a : command is a Proc object and takes 4 arguemnts
@@ -160,16 +174,16 @@ if __FILE__ == $0
bhelp.text "current index == #{parent.nearest(y)}"
}
- TkBalloonHelp.new(sb, :interval=>500,
- :relief=>:ridge, :background=>'white',
- :command=>cmd)
+ Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
+ :relief=>:ridge, :background=>'white',
+ :command=>cmd)
sb2 = TkScrollbox.new.pack(:fill=>:x)
sb2.insert(:end, *%w(AAA BBB CCC DDD EEE FFF GGG HHH III JJJ KKK LLL MMM))
- TkBalloonHelp.new(sb2, :interval=>500,
- :padx=>5, :relief=>:raised,
- :background=>'gray25', :foreground=>'white',
- :command=>cmd)
+ Tk::RbWidget::BalloonHelp.new(sb2, :interval=>500,
+ :padx=>5, :relief=>:raised,
+ :background=>'gray25', :foreground=>'white',
+ :command=>cmd)
=end
#=begin
# CASE4b : command is a Method object and takes 4 arguemnts
@@ -178,16 +192,16 @@ if __FILE__ == $0
end
cmd = self.method(:set_msg)
- TkBalloonHelp.new(sb, :interval=>500,
- :relief=>:ridge, :background=>'white',
- :command=>cmd)
+ Tk::RbWidget::BalloonHelp.new(sb, :interval=>500,
+ :relief=>:ridge, :background=>'white',
+ :command=>cmd)
sb2 = TkScrollbox.new.pack(:fill=>:x)
sb2.insert(:end, *%w(AAA BBB CCC DDD EEE FFF GGG HHH III JJJ KKK LLL MMM))
- TkBalloonHelp.new(sb2, :interval=>500,
- :padx=>5, :relief=>:raised,
- :background=>'gray25', :foreground=>'white',
- :command=>cmd)
+ Tk::RbWidget::BalloonHelp.new(sb2, :interval=>500,
+ :padx=>5, :relief=>:raised,
+ :background=>'gray25', :foreground=>'white',
+ :command=>cmd)
#=end
Tk.mainloop
diff --git a/ext/tk/sample/tkcombobox.rb b/ext/tk/sample/tkcombobox.rb
index 941f7cc4cb..59db565f06 100644
--- a/ext/tk/sample/tkcombobox.rb
+++ b/ext/tk/sample/tkcombobox.rb
@@ -1,11 +1,20 @@
#
-# tkcombobox.rb : TkAutoScrollbox & TkCombobox
+# tkcombobox.rb : auto scrollbox & combobox
#
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
#
require 'tk'
-class TkAutoScrollbox < TkListbox
+module Tk
+ module RbWidget
+ class AutoScrollListbox < TkListbox
+ end
+ class Combobox < TkEntry
+ end
+ end
+end
+
+class Tk::RbWidget::AutoScrollListbox
include TkComposite
@@up_bmp = TkBitmapImage.new(:data=><<EOD)
@@ -221,17 +230,7 @@ end
################################################
-# don't use Ttk widget
-Object.instance_eval{remove_const :TkCombobox} if Object.autoload? :TkCombobox
-
-# if you want to use the 'default_widget_set' selector,
-#class TkCombobox < TkEntry; end
-#Tk.__set_toplevel_aliases__(:Tk, TkCombobox, :TkCombobox)
-
-
-################################################
-
-class TkCombobox < TkEntry
+class Tk::RbWidget::Combobox < TkEntry
include TkComposite
@@down_btn_bmp = TkBitmapImage.new(:data=><<EOD)
@@ -251,6 +250,7 @@ static unsigned char up_arrow_bits[] = {
EOD
def _button_proc(dir = true)
+ return if @ent.state == 'disabled'
@btn.relief(:sunken)
x = @frame.winfo_rootx
y = @frame.winfo_rooty
@@ -275,9 +275,10 @@ EOD
@top.grab
begin
- @var.tkwait
- if (idx = @var.to_i) >= 0
- @ent.value = @lst.get(idx)
+ @wait_var.tkwait
+ if (idx = @wait_var.to_i) >= 0
+ # @ent.value = @lst.get(idx)
+ _set_entry_value(@lst.get(idx))
end
@top.withdraw
@btn.relief(:raised)
@@ -297,18 +298,65 @@ EOD
@btn.bind('1', proc{_button_proc(true)})
@btn.bind('3', proc{_button_proc(false)})
- @lst.bind('1', proc{|y| @var.value = @lst.nearest(y)}, '%y')
- @lst.bind('Return', proc{@var.value = @lst.curselection[0]})
+ @lst.bind('1', proc{|y| @wait_var.value = @lst.nearest(y)}, '%y')
+ @lst.bind('Return', proc{@wait_var.value = @lst.curselection[0]})
cancel = TkVirtualEvent.new('2', '3', 'Escape')
- @lst.bind(cancel, proc{@var.value = -1})
+ @lst.bind(cancel, proc{@wait_var.value = -1})
end
private :_init_bindings
+ def _set_entry_value(val)
+ @ent.textvariable.value = val
+ end
+ private :_set_entry_value
+
+ #----------------------------------------------------
+
+ def _state_control(value = None)
+ if value == None
+ # get
+ @ent.state
+ else
+ # set
+ @ent.state(value.to_s)
+ case value = @ent.state # regulate 'state' string
+ when 'normal', 'readonly'
+ @btn.state 'normal'
+ when 'disabled'
+ @btn.state 'disabled'
+ else
+ # unknown : do nothing
+ end
+ end
+ end
+ private :_state_control
+
+ def __methodcall_optkeys # { key=>method, ... }
+ {'state' => :_state_control}
+ end
+ private :__methodcall_optkeys
+
+ #----------------------------------------------------
+
+ def _textvariable_control(var = None)
+ if var == None
+ # get
+ ((var = @ent.textvariable) === @default_var)? nil: var
+ else
+ # set
+ @var = var
+ tk_send('configure', '-textvariable', (@var)? var: @default_var)
+ end
+ end
+ private :_textvariable_control
+
+ #----------------------------------------------------
+
def initialize_composite(keys={})
keys = _symbolkey2str(keys)
- @btn = TkLabel.new(@frame, :relief=>:raised, :borderwidth=>3,
+ @btn = TkLabel.new(@frame, :relief=>:raised, :borderwidth=>2,
:image=>@@down_btn_bmp).pack(:side=>:right,
:ipadx=>2, :fill=>:y)
@ent = TkEntry.new(@frame).pack(:side=>:left)
@@ -322,16 +370,21 @@ EOD
startwait = keys.delete('startwait'){300}
interval = keys.delete('interval'){150}
- @lst = TkAutoScrollbox.new(@top,
- :startwait=>startwait,
- :interval=>interval).pack(:fill=>:both,
- :expand=>true)
+ @lst = Tk::RbWidget::AutoScrollListbox.new(@top, :scrollbar=>true,
+ :startwait=>startwait,
+ :interval=>interval)
+ @lst.pack(:fill=>:both, :expand=>true)
@ent_list = []
- @var = TkVariable.new
+ @wait_var = TkVariable.new
+ @var = @default_var = TkVariable.new
+
+ @ent.textvariable @default_var
_init_bindings
+ option_methods('textvariable' => :_textvariable_control)
+
delegate('DEFAULT', @ent)
delegate('height', @lst)
delegate('relief', @frame)
@@ -340,6 +393,8 @@ EOD
delegate('arrowrelief', @lst)
delegate('arrowborderwidth', @lst)
+ delegate('state', false)
+
if mode = keys.delete('scrollbar')
scrollbar(mode)
end
@@ -405,10 +460,14 @@ end
# test
################################################
if __FILE__ == $0
+# e0 = Tk::RbWidget::Combobox.new.pack
+# e0.values(%w(aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp qq rr ss tt uu))
+
v = TkVariable.new
- e = TkCombobox.new(:height=>7, :scrollbar=>true, :textvariable=>v,
- :arrowrelief=>:flat, :arrowborderwidth=>0,
- :startwait=>400, :interval=>200).pack
+ e = Tk::RbWidget::Combobox.new(:height=>7, :scrollbar=>true,
+ :textvariable=>v,
+ :arrowrelief=>:flat, :arrowborderwidth=>0,
+ :startwait=>400, :interval=>200).pack
e.values(%w(aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp qq rr ss tt uu))
#e.see(e.list_index('end') - 2)
e.value = 'cc'
@@ -421,8 +480,10 @@ if __FILE__ == $0
TkFrame.new(:relief=>:raised, :borderwidth=>2,
:height=>3).pack(:fill=>:x, :expand=>true, :padx=>5, :pady=>3)
- l = TkAutoScrollbox.new(nil, :relief=>:groove, :borderwidth=>4,
- :width=>20).pack(:fill=>:both, :expand=>true)
+ l = Tk::RbWidget::AutoScrollListbox.new(nil, :relief=>:groove,
+ :borderwidth=>4,:height=>7,
+ :width=>20).pack(:fill=>:both,
+ :expand=>true)
(0..20).each{|i| l.insert('end', "line #{i}")}
TkFrame.new(:relief=>:ridge, :borderwidth=>3){
diff --git a/ext/tk/sample/tktextframe.rb b/ext/tk/sample/tktextframe.rb
index d50f2e5d88..b2b40c9138 100644
--- a/ext/tk/sample/tktextframe.rb
+++ b/ext/tk/sample/tktextframe.rb
@@ -5,9 +5,53 @@
#
require 'tk'
-class TkTextFrame < TkText
+module Tk::ScrollbarComposite
include TkComposite
+ def component_construct_keys
+ # If a component requires options for construction,
+ # return an Array of option-keys.
+ []
+ end
+ private :component_construct_keys
+
+ def create_component(keys={})
+ # This method must return the created component widget.
+ end
+ private :create_component
+
+ def component_delegates
+ # if want to override defalut option-methods or delegates,
+ # please define here.
+ end
+ private :component_delegates
+
+ def define_delegates
+ # option methods for scrollbars
+ option_methods([:scrollbarwidth, :get_scrollbarwidth])
+
+ # set receiver widgets for configure methods (with alias)
+ delegate_alias('scrollbarrelief', 'relief', @h_scroll, @v_scroll)
+ delegate_alias('framebackground', 'background',
+ @frame, @h_scroll, @v_scroll)
+ delegate_alias('activeframebackground', 'activebackground',
+ @h_scroll, @v_scroll)
+
+ # set receiver widgets for configure methods
+ delegate('DEFAULT', @component)
+ delegate('troughcolor', @h_scroll, @v_scroll)
+ delegate('repeatdelay', @h_scroll, @v_scroll)
+ delegate('repeatinterval', @h_scroll, @v_scroll)
+ delegate('borderwidth', @frame)
+ delegate('relief', @frame)
+
+ component_delegates
+ end
+ private :define_delegates
+
+ DEFAULT_VSCROLL = true
+ DEFAULT_HSCROLL = true
+
def initialize_composite(keys={})
keys = _symbolkey2str(keys)
@@ -15,55 +59,123 @@ class TkTextFrame < TkText
@v_scroll = TkScrollbar.new(@frame, 'orient'=>'vertical')
@h_scroll = TkScrollbar.new(@frame, 'orient'=>'horizontal')
- # create a text widget
- @text = TkText.new(@frame, 'wrap'=>'none')
+ # create a component
+ construct_keys = {}
+ ((component_construct_keys.map{|k| k.to_s}) & keys.keys).each{|k|
+ construct_keys[k] = keys.delete(k)
+ }
+
+ # create a component (the component must be scrollable)
+ @component = create_component(construct_keys)
# set default receiver of method calls
- @path = @text.path
+ @path = @component.path
# assign scrollbars
- @text.xscrollbar(@h_scroll)
- @text.yscrollbar(@v_scroll)
+ @component.xscrollbar(@h_scroll)
+ @component.yscrollbar(@v_scroll)
# allignment
TkGrid.rowconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)
TkGrid.columnconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0)
- @text.grid('row'=>0, 'column'=>0, 'sticky'=>'news')
+ @component.grid('row'=>0, 'column'=>0, 'sticky'=>'news')
# scrollbars ON
- vscroll(keys.delete('vscroll'){true})
- hscroll(keys.delete('hscroll'){true})
-
- # set background of the text widget
-=begin
- color = keys.delete('textbackground')
- textbackground(color) if color
-=end
- # please check the differences of the following definitions
+ vscroll(keys.delete('vscroll'){self.class::DEFAULT_VSCROLL})
+ hscroll(keys.delete('hscroll'){self.class::DEFAULT_HSCROLL})
+
+ # do configure
+ define_delegates
+
+ # do configure
+ configure keys unless keys.empty?
+ end
+ private :initialize_composite
+
+ # get/set width of scrollbar
+ def get_scrollbarwidth
+ @v_scroll.width
+ end
+ def set_scrollbarwidth(width)
+ @v_scroll.width(width)
+ @h_scroll.width(width)
+ end
+ alias :scrollbarwidth :set_scrollbarwidth
+
+ def hook_vscroll_on(*args); end
+ def hook_vscroll_off(*args); end
+ def hook_hscroll_on(*args); end
+ def hook_hscroll_off(*args); end
+ private :hook_vscroll_on,:hook_vscroll_off,:hook_hscroll_on,:hook_hscroll_off
+
+ # vertical scrollbar : ON/OFF
+ def vscroll(mode, *args)
+ st = TkGrid.info(@v_scroll)
+ if mode && st.size == 0 then
+ @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns')
+ hook_vscroll_on(*args)
+ elsif !mode && st.size != 0 then
+ @v_scroll.ungrid
+ hook_vscroll_off(*args)
+ end
+ self
+ end
+
+ # horizontal scrollbar : ON/OFF
+ def hscroll(mode, *args)
+ st = TkGrid.info(@h_scroll)
+ if mode && st.size == 0 then
+ @h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew')
+ hook_hscroll_on(*args)
+ elsif !mode && st.size != 0 then
+ @h_scroll.ungrid
+ hook_hscroll_off(*args)
+ end
+ self
+ end
+end
+
+################################################
+
+class TkTextFrame < TkText
+ include Tk::ScrollbarComposite
+
+ # def component_construct_keys; []; end
+ # private :component_construct_keys
+
+ def create_component(keys={})
+ # keys has options which are listed by component_construct_keys method.
+ @text = TkText.new(@frame, 'wrap'=>'none')
+ @text.configure(keys) unless keys.empty?
+
+ # option methods for component
option_methods(
- [:scrollbarwidth, :get_scrollbarwidth],
[:textbackground, nil, :textbg_info],
:textborderwidth,
:textrelief
)
- # set receiver widgets for configure methods (with alias)
- delegate_alias('scrollbarrelief', 'relief', @h_scroll, @v_scroll)
+ # return the created componet
+ @text
+ end
+ private :create_component
- # set receiver widgets for configure methods
- delegate('DEFAULT', @text)
- delegate('background', @frame, @h_scroll, @v_scroll)
- delegate('activebackground', @h_scroll, @v_scroll)
- delegate('troughcolor', @h_scroll, @v_scroll)
- delegate('repeatdelay', @h_scroll, @v_scroll)
- delegate('repeatinterval', @h_scroll, @v_scroll)
- delegate('borderwidth', @frame)
- delegate('relief', @frame)
+ # def component_delegates; end
+ # private :component_delegates
- # do configure
- configure keys unless keys.empty?
+ def hook_hscroll_on(wrap_mode=nil)
+ if wrap_mode
+ wrap wrap_mode
+ else
+ wrap 'none' # => self.wrap('none')
+ end
+ end
+ def hook_hscroll_off(wrap_mode)
+ wrap wrap_mode # => self.wrap(wrap_mode)
+ end
+ def hscroll(mode, wrap_mode="char")
+ super
end
- private :initialize_composite
# set background color of text widget
def textbackground(color = nil)
@@ -103,47 +215,13 @@ class TkTextFrame < TkText
def textrelief(type)
@text.relief(type)
end
-
- # get/set width of scrollbar
- def get_scrollbarwidth
- @v_scroll.width
- end
- def set_scrollbarwidth(width)
- @v_scroll.width(width)
- @h_scroll.width(width)
- end
- alias :scrollbarwidth :set_scrollbarwidth
-
- # vertical scrollbar : ON/OFF
- def vscroll(mode)
- st = TkGrid.info(@v_scroll)
- if mode && st.size == 0 then
- @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns')
- elsif !mode && st.size != 0 then
- @v_scroll.ungrid
- end
- self
- end
-
- # horizontal scrollbar : ON/OFF
- def hscroll(mode, wrap_mode="char")
- st = TkGrid.info(@h_scroll)
- if mode && st.size == 0 then
- @h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew')
- wrap 'none' # => self.wrap('none')
- elsif !mode && st.size != 0 then
- @h_scroll.ungrid
- wrap wrap_mode # => self.wrap(wrap_mode)
- end
- self
- end
end
-
################################################
# test
################################################
if __FILE__ == $0
+ TkLabel.new(:text=>'TkTextFrame is an example of Tk::ScrollbarComposite module.').pack
f = TkFrame.new.pack('fill'=>'x')
#t = TkTextFrame.new.pack
t = TkTextFrame.new(:textborderwidth=>3,
@@ -158,5 +236,46 @@ if __FILE__ == $0
'command'=>proc{t.hscroll(true)}).pack('side'=>'left')
TkButton.new(f, 'text'=>'hscr OFF',
'command'=>proc{t.hscroll(false)}).pack('side'=>'left')
+
+ ############################################
+
+ # Tk.default_widget_set = :Ttk
+
+ TkFrame.new.pack(:pady=>10)
+ TkLabel.new(:text=>'The following is another example of Tk::ScrollbarComposite module.').pack
+
+ #----------------------------------
+ class ScrListbox < TkListbox
+ include Tk::ScrollbarComposite
+
+ DEFAULT_HSCROLL = false
+
+ def create_component(keys={})
+ TkListbox.new(@frame, keys)
+ end
+ private :create_component
+ end
+ #----------------------------------
+
+ f = TkFrame.new.pack(:pady=>5)
+ lbox = ScrListbox.new(f).pack(:side=>:left)
+ lbox.value = %w(aa bb cc dd eeeeeeeeeeeeeeeeeeeeeeeeee ffffffffff gg hh ii jj kk ll mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm nn oo pp qq)
+ fb = TkFrame.new(f).pack(:expand=>true, :fill=>:y, :padx=>5)
+ TkButton.new(fb, 'text'=>'lbox hscr OFF',
+ 'command'=>proc{lbox.hscroll(false)}).pack(:side=>:bottom,
+ :fill=>:x)
+ TkButton.new(fb, 'text'=>'lbox hscr ON',
+ 'command'=>proc{lbox.hscroll(true)}).pack(:side=>:bottom,
+ :fill=>:x)
+ TkFrame.new(fb).pack(:pady=>5, :side=>:bottom)
+ TkButton.new(fb, 'text'=>'lbox vscr OFF',
+ 'command'=>proc{lbox.vscroll(false)}).pack(:side=>:bottom,
+ :fill=>:x)
+ TkButton.new(fb, 'text'=>'lbox vscr ON',
+ 'command'=>proc{lbox.vscroll(true)}).pack(:side=>:bottom,
+ :fill=>:x)
+
+ ############################################
+
Tk.mainloop
end
diff --git a/ext/tk/stubs.c b/ext/tk/stubs.c
index e7ef79dda8..4388fb294d 100644
--- a/ext/tk/stubs.c
+++ b/ext/tk/stubs.c
@@ -11,6 +11,25 @@
/*------------------------------*/
+#ifdef __MACOS__
+# include <tkMac.h>
+# include <Quickdraw.h>
+
+static int call_macinit = 0;
+
+static void
+_macinit()
+{
+ if (!call_macinit) {
+ tcl_macQdPtr = &qd; /* setup QuickDraw globals */
+ Tcl_MacSetEventProc(TkMacConvertEvent); /* setup event handler */
+ call_macinit = 1;
+ }
+}
+#endif
+
+/*------------------------------*/
+
static int nativethread_checked = 0;
static void
@@ -301,6 +320,10 @@ ruby_tk_stubs_init(tcl_ip)
if (!Tk_InitStubs(tcl_ip, (char *)"8.1", 0))
return FAIL_Tk_InitStubs;
+
+#ifdef __MACOS__
+ _macinit();
+#endif
}
return TCLTK_STUBS_OK;
@@ -336,6 +359,10 @@ ruby_tk_stubs_safeinit(tcl_ip)
if (!Tk_InitStubs(tcl_ip, (char *)"8.1", 0))
return FAIL_Tk_InitStubs;
+
+#ifdef __MACOS__
+ _macinit();
+#endif
}
return TCLTK_STUBS_OK;
@@ -490,6 +517,9 @@ ruby_tk_stubs_init(tcl_ip)
return FAIL_Tk_Init;
if (!call_tk_stubs_init) {
+#ifdef __MACOS__
+ _macinit();
+#endif
call_tk_stubs_init = 1;
}
@@ -509,6 +539,9 @@ ruby_tk_stubs_safeinit(tcl_ip)
return FAIL_Tk_Init;
if (!call_tk_stubs_init) {
+#ifdef __MACOS__
+ _macinit();
+#endif
call_tk_stubs_init = 1;
}
diff --git a/ext/tk/tcltklib.c b/ext/tk/tcltklib.c
index 39c85da72d..cc3c0e9b8d 100644
--- a/ext/tk/tcltklib.c
+++ b/ext/tk/tcltklib.c
@@ -4,7 +4,7 @@
* Oct. 24, 1997 Y. Matsumoto
*/
-#define TCLTKLIB_RELEASE_DATE "2008-12-22"
+#define TCLTKLIB_RELEASE_DATE "2009-07-12"
#include "ruby.h"
@@ -15,6 +15,25 @@
#include "version.h"
#endif
+#ifdef RUBY_VM
+static VALUE rb_thread_critical; /* dummy */
+int rb_thread_check_trap_pending();
+#else
+/* use rb_thread_critical on Ruby 1.8.x */
+#include "rubysig.h"
+#endif
+
+#ifdef OBJ_UNTRUST
+#define RbTk_OBJ_UNTRUST(x) do {OBJ_TAINT(x); OBJ_UNTRUST(x);} while (0)
+#else
+#define RbTk_OBJ_UNTRUST(x) OBJ_TAINT(x)
+#endif
+
+#if defined(HAVE_RB_PROC_NEW) && !defined(RUBY_VM)
+/* Ruby 1.8 :: rb_proc_new() was hidden from intern.h at 2008/04/22 */
+extern VALUE rb_proc_new _((VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE));
+#endif
+
#undef EXTERN /* avoid conflict with tcl.h of tcl8.2 or before */
#include <stdio.h>
#ifdef HAVE_STDARG_PROTOTYPES
@@ -34,6 +53,7 @@
#else
#define RUBY_USE_NATIVE_THREAD 1
#endif
+
#ifndef HAVE_RB_ERRINFO
#define rb_errinfo() (ruby_errinfo+0) /* cannot be l-value */
#endif
@@ -49,9 +69,6 @@
#define TCL_FINAL_RELEASE 2 /* "final" */
#endif
-static VALUE rb_thread_critical; /* dummy */
-int rb_thread_check_trap_pending();
-
static struct {
int major;
int minor;
@@ -91,6 +108,14 @@ set_tcltk_version()
# endif
#endif
+#ifndef CONST86
+# if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION <= 5 /* Tcl8.0.x -- 8.5.x */
+# define CONST86
+# else
+# define CONST86 CONST84
+# endif
+#endif
+
/* copied from eval.c */
#define TAG_RETURN 0x1
#define TAG_BREAK 0x2
@@ -191,10 +216,10 @@ static VALUE callq_safelevel_handler _((VALUE, VALUE));
/* Tcl's object type */
#if TCL_MAJOR_VERSION >= 8
static const char Tcl_ObjTypeName_ByteArray[] = "bytearray";
-static Tcl_ObjType *Tcl_ObjType_ByteArray;
+static CONST86 Tcl_ObjType *Tcl_ObjType_ByteArray;
static const char Tcl_ObjTypeName_String[] = "string";
-static Tcl_ObjType *Tcl_ObjType_String;
+static CONST86 Tcl_ObjType *Tcl_ObjType_String;
#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 1)
#define IS_TCL_BYTEARRAY(obj) ((obj)->typePtr == Tcl_ObjType_ByteArray)
@@ -407,6 +432,7 @@ call_queue_mark(struct call_queue *q)
static VALUE eventloop_thread;
+static Tcl_Interp *eventloop_interp;
#ifdef RUBY_USE_NATIVE_THREAD
Tcl_ThreadId tk_eventloop_thread_id; /* native thread ID of Tcl interpreter */
#endif
@@ -460,6 +486,8 @@ static int have_rb_thread_waiting_for_value = 0;
#define NO_THREAD_INTERRUPT_TIME 100/*milliseconds ( 1 -- 999 ) */
#endif
+#define EVENT_HANDLER_TIMEOUT 100/*milliseconds*/
+
static int event_loop_max = DEFAULT_EVENT_LOOP_MAX;
static int no_event_tick = DEFAULT_NO_EVENT_TICK;
static int no_event_wait = DEFAULT_NO_EVENT_WAIT;
@@ -1630,6 +1658,7 @@ trap_check(int *check_var)
{
DUMP1("trap check");
+#ifdef RUBY_VM
if (rb_thread_check_trap_pending()) {
if (check_var != (int*)NULL) {
/* wait command */
@@ -1639,11 +1668,35 @@ trap_check(int *check_var)
rb_thread_check_ints();
}
}
+#else
+ if (rb_trap_pending) {
+ run_timer_flag = 0;
+ if (rb_prohibit_interrupt || check_var != (int*)NULL) {
+ /* pending or on wait command */
+ return 0;
+ } else {
+ rb_trap_exec();
+ }
+ }
+#endif
return 1;
}
static int
+check_eventloop_interp()
+{
+ DUMP1("check eventloop_interp");
+ if (eventloop_interp != (Tcl_Interp*)NULL
+ && Tcl_InterpDeleted(eventloop_interp)) {
+ DUMP2("eventloop_interp(%p) was deleted", eventloop_interp);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
lib_eventloop_core(check_root, update_flag, check_var, interp)
int check_root;
int update_flag;
@@ -1684,6 +1737,8 @@ lib_eventloop_core(check_root, update_flag, check_var, interp)
#endif
for(;;) {
+ if (check_eventloop_interp()) return 0;
+
#if USE_EVLOOP_THREAD_ALONE_CHECK_FLAG
if (thread_alone_check_flag && rb_thread_alone()) {
#else
@@ -1776,6 +1831,7 @@ lib_eventloop_core(check_root, update_flag, check_var, interp)
}
TRAP_CHECK();
+ if (check_eventloop_interp()) return 0;
DUMP1("check Root Widget");
if (check_root && tk_stubs_init_p() && Tk_GetNumMainWindows() == 0) {
@@ -1962,6 +2018,7 @@ lib_eventloop_core(check_root, update_flag, check_var, interp)
}
TRAP_CHECK();
+ if (check_eventloop_interp()) return 0;
DUMP1("check Root Widget");
if (check_root && tk_stubs_init_p() && Tk_GetNumMainWindows() == 0) {
@@ -2205,6 +2262,7 @@ ip_mainloop(argc, argv, self)
VALUE *argv;
VALUE self;
{
+ volatile VALUE ret;
struct tcltkip *ptr = get_ip(self);
/* ip is deleted? */
@@ -2216,7 +2274,11 @@ ip_mainloop(argc, argv, self)
/* slave IP */
return Qnil;
}
- return lib_mainloop(argc, argv, self);
+
+ eventloop_interp = ptr->ip;
+ ret = lib_mainloop(argc, argv, self);
+ eventloop_interp = (Tcl_Interp*)NULL;
+ return ret;
}
@@ -2306,7 +2368,7 @@ lib_mainloop_watchdog(argc, argv, self)
{
VALUE check_rootwidget;
-#ifdef RUBY_USE_NATIVE_THREAD
+#ifdef RUBY_VM
rb_raise(rb_eNotImpError,
"eventloop_watchdog is not implemented on Ruby VM.");
#endif
@@ -2812,7 +2874,17 @@ tcl_protect(interp, proc, data)
#endif
#endif
+#ifdef RUBY_VM
code = tcl_protect_core(interp, proc, data);
+#else
+ do {
+ int old_trapflag = rb_trap_immediate;
+ rb_trap_immediate = 0;
+ code = tcl_protect_core(interp, proc, data);
+ rb_trap_immediate = old_trapflag;
+ } while (0);
+#endif
+
return code;
}
@@ -2906,6 +2978,7 @@ ip_ruby_cmd_core(arg)
thr_crit_bup = rb_thread_critical;
rb_thread_critical = Qfalse;
ret = rb_apply(arg->receiver, arg->method, arg->args);
+ DUMP2("rb_apply return:%lx", ret);
rb_thread_critical = thr_crit_bup;
DUMP1("finish ip_ruby_cmd_core");
@@ -3374,7 +3447,11 @@ ip_rbUpdateCommand(clientData, interp, objc, objv)
}
/* trap check */
+#ifdef RUBY_VM
if (rb_thread_check_trap_pending()) {
+#else
+ if (rb_trap_pending) {
+#endif
Tcl_Release(interp);
return TCL_RETURN;
@@ -3442,6 +3519,7 @@ ip_rb_threadUpdateCommand(clientData, interp, objc, objv)
static CONST char *updateOptions[] = {"idletasks", (char *) NULL};
enum updateOptions {REGEXP_IDLETASKS};
volatile VALUE current_thread = rb_thread_current();
+ struct timeval t;
DUMP1("Ruby's 'thread_update' is called");
if (interp == (Tcl_Interp*)NULL) {
@@ -3529,10 +3607,17 @@ ip_rb_threadUpdateCommand(clientData, interp, objc, objv)
DUMP1("set idle proc");
Tcl_DoWhenIdle(rb_threadUpdateProc, (ClientData) param);
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (long)((EVENT_HANDLER_TIMEOUT)*1000.0);
+
while(!param->done) {
- DUMP1("wait for complete idle proc");
- /* rb_thread_stop(); */
- rb_thread_sleep_forever();
+ DUMP1("wait for complete idle proc");
+ /* rb_thread_stop(); */
+ /* rb_thread_sleep_forever(); */
+ rb_thread_wait_for(t);
+ if (NIL_P(eventloop_thread)) {
+ break;
+ }
}
#if 0 /* use Tcl_EventuallyFree */
@@ -3740,7 +3825,11 @@ ip_rbVwaitCommand(clientData, interp, objc, objv)
}
/* trap check */
+#ifdef RUBY_VM
if (rb_thread_check_trap_pending()) {
+#else
+ if (rb_trap_pending) {
+#endif
#if TCL_MAJOR_VERSION >= 8
Tcl_DecrRefCount(objv[1]);
#endif
@@ -4029,7 +4118,11 @@ ip_rbTkWaitCommand(clientData, interp, objc, objv)
}
/* trap check */
- if (rb_thread_check_trap_pending()) {
+#ifdef RUBY_VM
+ if (rb_thread_check_trap_pending()) {
+#else
+ if (rb_trap_pending) {
+#endif
Tcl_Release(interp);
return TCL_RETURN;
@@ -4089,7 +4182,11 @@ ip_rbTkWaitCommand(clientData, interp, objc, objv)
}
/* trap check */
- if (rb_thread_check_trap_pending()) {
+#ifdef RUBY_VM
+ if (rb_thread_check_trap_pending()) {
+#else
+ if (rb_trap_pending) {
+#endif
#if TCL_MAJOR_VERSION >= 8
Tcl_DecrRefCount(objv[2]);
#endif
@@ -4184,7 +4281,11 @@ ip_rbTkWaitCommand(clientData, interp, objc, objv)
}
/* trap check */
- if (rb_thread_check_trap_pending()) {
+#ifdef RUBY_VM
+ if (rb_thread_check_trap_pending()) {
+#else
+ if (rb_trap_pending) {
+#endif
Tcl_Release(interp);
return TCL_RETURN;
@@ -4304,6 +4405,7 @@ ip_rb_threadVwaitCommand(clientData, interp, objc, objv)
int ret, dummy;
int thr_crit_bup;
volatile VALUE current_thread = rb_thread_current();
+ struct timeval t;
DUMP1("Ruby's 'thread_vwait' is called");
if (interp == (Tcl_Interp*)NULL) {
@@ -4398,9 +4500,16 @@ ip_rb_threadVwaitCommand(clientData, interp, objc, objv)
return TCL_ERROR;
}
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (long)((EVENT_HANDLER_TIMEOUT)*1000.0);
+
while(!param->done) {
- /* rb_thread_stop(); */
- rb_thread_sleep_forever();
+ /* rb_thread_stop(); */
+ /* rb_thread_sleep_forever(); */
+ rb_thread_wait_for(t);
+ if (NIL_P(eventloop_thread)) {
+ break;
+ }
}
thr_crit_bup = rb_thread_critical;
@@ -4459,6 +4568,7 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv)
int ret, dummy;
int thr_crit_bup;
volatile VALUE current_thread = rb_thread_current();
+ struct timeval t;
DUMP1("Ruby's 'thread_tkwait' is called");
if (interp == (Tcl_Interp*)NULL) {
@@ -4612,9 +4722,16 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv)
return TCL_ERROR;
}
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (long)((EVENT_HANDLER_TIMEOUT)*1000.0);
+
while(!param->done) {
- /* rb_thread_stop(); */
- rb_thread_sleep_forever();
+ /* rb_thread_stop(); */
+ /* rb_thread_sleep_forever(); */
+ rb_thread_wait_for(t);
+ if (NIL_P(eventloop_thread)) {
+ break;
+ }
}
thr_crit_bup = rb_thread_critical;
@@ -4691,10 +4808,17 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv)
rb_thread_critical = thr_crit_bup;
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (long)((EVENT_HANDLER_TIMEOUT)*1000.0);
+
while(param->done != TKWAIT_MODE_VISIBILITY) {
- if (param->done == TKWAIT_MODE_DESTROY) break;
- /* rb_thread_stop(); */
- rb_thread_sleep_forever();
+ if (param->done == TKWAIT_MODE_DESTROY) break;
+ /* rb_thread_stop(); */
+ /* rb_thread_sleep_forever(); */
+ rb_thread_wait_for(t);
+ if (NIL_P(eventloop_thread)) {
+ break;
+ }
}
thr_crit_bup = rb_thread_critical;
@@ -4806,9 +4930,16 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv)
rb_thread_critical = thr_crit_bup;
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (long)((EVENT_HANDLER_TIMEOUT)*1000.0);
+
while(param->done != TKWAIT_MODE_DESTROY) {
- /* rb_thread_stop(); */
- rb_thread_sleep_forever();
+ /* rb_thread_stop(); */
+ /* rb_thread_sleep_forever(); */
+ rb_thread_wait_for(t);
+ if (NIL_P(eventloop_thread)) {
+ break;
+ }
}
Tcl_Release(window);
@@ -5073,7 +5204,9 @@ ip_finalize(ip)
}
/* delete root widget */
-#if 0 /* cause SEGV on Ruby 1.9 */
+#ifdef RUBY_VM
+ /* cause SEGV on Ruby 1.9 */
+#else
DUMP1("check `destroy'");
if (Tcl_GetCommandInfo(ip, "destroy", &info)) {
DUMP1("call `destroy .'");
@@ -5292,7 +5425,7 @@ ip_rbNamespaceObjCmd(clientData, interp, objc, objv)
}
rbtk_eventloop_depth++;
- DUMP2("namespace wrapper enter depth == %d", rbtk_eventloop_depth);
+ /* DUMP2("namespace wrapper enter depth == %d", rbtk_eventloop_depth); */
if (info.isNativeObjectProc) {
ret = (*(info.objProc))(info.objClientData, interp, objc, objv);
@@ -5328,7 +5461,7 @@ ip_rbNamespaceObjCmd(clientData, interp, objc, objv)
#endif
}
- DUMP2("namespace wrapper exit depth == %d", rbtk_eventloop_depth);
+ /* DUMP2("namespace wrapper exit depth == %d", rbtk_eventloop_depth); */
rbtk_eventloop_depth--;
return ret;
@@ -5490,6 +5623,7 @@ ip_init(argc, argv, self)
;
}
+ st = ruby_tcl_stubs_init();
/* from Tcl_AppInit() */
if (with_tk) {
DUMP1("Tk_Init");
@@ -6154,7 +6288,7 @@ ip_get_result_string_obj(interp)
retObj = Tcl_GetObjResult(interp);
Tcl_IncrRefCount(retObj);
strval = get_str_from_obj(retObj);
- OBJ_TAINT(strval);
+ RbTk_OBJ_UNTRUST(strval);
Tcl_ResetResult(interp);
Tcl_DecrRefCount(retObj);
return strval;
@@ -6297,6 +6431,7 @@ tk_funcall(func, argc, argv, obj)
volatile VALUE ip_obj = obj;
volatile VALUE result;
volatile VALUE ret;
+ struct timeval t;
if (!NIL_P(ip_obj) && rb_obj_is_kind_of(ip_obj, tcltkip_class)) {
ptr = get_ip(ip_obj);
@@ -6406,12 +6541,21 @@ tk_funcall(func, argc, argv, obj)
rb_thread_critical = thr_crit_bup;
/* wait for the handler to be processed */
- DUMP2("wait for handler (current thread:%lx)", current);
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (long)((EVENT_HANDLER_TIMEOUT)*1000.0);
+
+ DUMP2("callq wait for handler (current thread:%lx)", current);
while(*alloc_done >= 0) {
- DUMP2("*** wait for handler (current thread:%lx)", current);
+ DUMP2("*** callq wait for handler (current thread:%lx)", current);
/* rb_thread_stop(); */
- rb_thread_sleep_forever();
- DUMP2("*** wakeup (current thread:%lx)", current);
+ /* rb_thread_sleep_forever(); */
+ rb_thread_wait_for(t);
+ DUMP2("*** callq wakeup (current thread:%lx)", current);
+ DUMP2("*** (eventloop thread:%lx)", eventloop_thread);
+ if (NIL_P(eventloop_thread)) {
+ DUMP1("*** callq lost eventloop thread");
+ break;
+ }
}
DUMP2("back from handler (current thread:%lx)", current);
@@ -6784,6 +6928,7 @@ ip_eval(self, str)
volatile VALUE result;
volatile VALUE ret;
Tcl_QueuePosition position;
+ struct timeval t;
thr_crit_bup = rb_thread_critical;
rb_thread_critical = Qtrue;
@@ -6792,7 +6937,12 @@ ip_eval(self, str)
#ifdef RUBY_USE_NATIVE_THREAD
ptr = get_ip(ip_obj);
+ DUMP2("eval status: ptr->tk_thread_id %p", ptr->tk_thread_id);
+ DUMP2("eval status: Tcl_GetCurrentThread %p", Tcl_GetCurrentThread());
+#else
+ DUMP2("status: Tcl_GetCurrentThread %p", Tcl_GetCurrentThread());
#endif
+ DUMP2("status: eventloopt_thread %lx", eventloop_thread);
if (
#ifdef RUBY_USE_NATIVE_THREAD
@@ -6880,12 +7030,21 @@ ip_eval(self, str)
rb_thread_critical = thr_crit_bup;
/* wait for the handler to be processed */
- DUMP2("wait for handler (current thread:%lx)", current);
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (long)((EVENT_HANDLER_TIMEOUT)*1000.0);
+
+ DUMP2("evq wait for handler (current thread:%lx)", current);
while(*alloc_done >= 0) {
- DUMP2("*** wait for handler (current thread:%lx)", current);
+ DUMP2("*** evq wait for handler (current thread:%lx)", current);
/* rb_thread_stop(); */
- rb_thread_sleep_forever();
- DUMP2("*** wakeup (current thread:%lx)", current);
+ /* rb_thread_sleep_forever(); */
+ rb_thread_wait_for(t);
+ DUMP2("*** evq wakeup (current thread:%lx)", current);
+ DUMP2("*** (eventloop thread:%lx)", eventloop_thread);
+ if (NIL_P(eventloop_thread)) {
+ DUMP1("*** evq lost eventloop thread");
+ break;
+ }
}
DUMP2("back from handler (current thread:%lx)", current);
@@ -6931,6 +7090,71 @@ ip_eval(self, str)
}
+static int
+ip_cancel_eval_core(interp, msg, flag)
+ Tcl_Interp *interp;
+ VALUE msg;
+ int flag;
+{
+#if TCL_MAJOR_VERSION < 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION < 6)
+ rb_raise(rb_eNotImpError,
+ "cancel_eval is supported Tcl/Tk8.6 or later.");
+#else
+ Tcl_Obj *msg_obj;
+
+ if (NIL_P(msg)) {
+ msg_obj = NULL;
+ } else {
+ msg_obj = Tcl_NewStringObj(RSTRING_PTR(msg), RSTRING_LEN(msg));
+ Tcl_IncrRefCount(msg_obj);
+ }
+
+ return Tcl_CancelEval(interp, msg_obj, 0, flag);
+#endif
+}
+
+static VALUE
+ip_cancel_eval(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
+{
+ VALUE retval;
+
+ if (rb_scan_args(argc, argv, "01", &retval) == 0) {
+ retval = Qnil;
+ }
+ if (ip_cancel_eval_core(get_ip(self)->ip, retval, 0) == TCL_OK) {
+ return Qtrue;
+ } else {
+ return Qfalse;
+ }
+}
+
+#ifndef TCL_CANCEL_UNWIND
+#define TCL_CANCEL_UNWIND 0x100000
+#endif
+static VALUE
+ip_cancel_eval_unwind(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
+{
+ int flag = 0;
+ VALUE retval;
+
+ if (rb_scan_args(argc, argv, "01", &retval) == 0) {
+ retval = Qnil;
+ }
+
+ flag |= TCL_CANCEL_UNWIND;
+ if (ip_cancel_eval_core(get_ip(self)->ip, retval, flag) == TCL_OK) {
+ return Qtrue;
+ } else {
+ return Qfalse;
+ }
+}
+
/* restart Tk */
static VALUE
lib_restart_core(interp, argc, argv)
@@ -7170,8 +7394,8 @@ lib_toUTF8_core(ip_obj, src, encodename)
#ifdef HAVE_RUBY_ENCODING_H
rb_enc_associate_index(str, ENCODING_INDEX_UTF8);
#endif
+ if (taint_flag) RbTk_OBJ_UNTRUST(str);
rb_ivar_set(str, ID_at_enc, ENCODING_NAME_UTF8);
- if (taint_flag) OBJ_TAINT(str);
/*
if (encoding != (Tcl_Encoding)NULL) {
@@ -7371,9 +7595,9 @@ lib_fromUTF8_core(ip_obj, src, encodename)
rb_enc_associate_index(str, rb_enc_find_index(RSTRING_PTR(encodename)));
}
#endif
- rb_ivar_set(str, ID_at_enc, encodename);
- if (taint_flag) OBJ_TAINT(str);
+ if (taint_flag) RbTk_OBJ_UNTRUST(str);
+ rb_ivar_set(str, ID_at_enc, encodename);
/*
if (encoding != (Tcl_Encoding)NULL) {
@@ -7466,7 +7690,7 @@ lib_UTF_backslash_core(self, str, all_bs)
}
str = rb_str_new(dst_buf, dst_len);
- if (taint_flag) OBJ_TAINT(str);
+ if (taint_flag) RbTk_OBJ_UNTRUST(str);
#ifdef HAVE_RUBY_ENCODING_H
rb_enc_associate_index(str, ENCODING_INDEX_UTF8);
#endif
@@ -8185,6 +8409,7 @@ ip_invoke_with_position(argc, argv, obj, position)
volatile VALUE ip_obj = obj;
volatile VALUE result;
volatile VALUE ret;
+ struct timeval t;
#if TCL_MAJOR_VERSION >= 8
Tcl_Obj **av = (Tcl_Obj **)NULL;
@@ -8198,10 +8423,10 @@ ip_invoke_with_position(argc, argv, obj, position)
#ifdef RUBY_USE_NATIVE_THREAD
ptr = get_ip(ip_obj);
- DUMP2("status: ptr->tk_thread_id %p", ptr->tk_thread_id);
- DUMP2("status: Tcl_GetCurrentThread %p", Tcl_GetCurrentThread());
+ DUMP2("invoke status: ptr->tk_thread_id %p", ptr->tk_thread_id);
+ DUMP2("invoke status: Tcl_GetCurrentThread %p", Tcl_GetCurrentThread());
#else
- DUMP2("status: Tcl_GetCurrentThread %lx", Tcl_GetCurrentThread());
+ DUMP2("status: Tcl_GetCurrentThread %p", Tcl_GetCurrentThread());
#endif
DUMP2("status: eventloopt_thread %lx", eventloop_thread);
@@ -8285,10 +8510,20 @@ ip_invoke_with_position(argc, argv, obj, position)
rb_thread_critical = thr_crit_bup;
/* wait for the handler to be processed */
- DUMP2("wait for handler (current thread:%lx)", current);
+ t.tv_sec = (time_t)0;
+ t.tv_usec = (long)((EVENT_HANDLER_TIMEOUT)*1000.0);
+
+ DUMP2("ivq wait for handler (current thread:%lx)", current);
while(*alloc_done >= 0) {
- /* rb_thread_stop(); */
- rb_thread_sleep_forever();
+ /* rb_thread_stop(); */
+ /* rb_thread_sleep_forever(); */
+ rb_thread_wait_for(t);
+ DUMP2("*** ivq wakeup (current thread:%lx)", current);
+ DUMP2("*** (eventloop thread:%lx)", eventloop_thread);
+ if (NIL_P(eventloop_thread)) {
+ DUMP1("*** ivq lost eventloop thread");
+ break;
+ }
}
DUMP2("back from handler (current thread:%lx)", current);
@@ -8426,7 +8661,7 @@ ip_get_variable2_core(interp, argc, argv)
Tcl_IncrRefCount(ret);
strval = get_str_from_obj(ret);
- OBJ_TAINT(strval);
+ RbTk_OBJ_UNTRUST(strval);
Tcl_DecrRefCount(ret);
/* Tcl_Release(ptr->ip); */
@@ -8565,7 +8800,7 @@ ip_set_variable2_core(interp, argc, argv)
Tcl_IncrRefCount(ret);
strval = get_str_from_obj(ret);
- OBJ_TAINT(strval);
+ RbTk_OBJ_UNTRUST(strval);
Tcl_DecrRefCount(ret);
/* Tcl_Release(ptr->ip); */
@@ -8842,12 +9077,14 @@ lib_split_tklist_core(ip_obj, list_str)
rb_thread_critical = Qtrue;
ary = rb_ary_new2(objc);
- if (taint_flag) OBJ_TAINT(ary);
+ if (taint_flag) RbTk_OBJ_UNTRUST(ary);
old_gc = rb_gc_disable();
for(idx = 0; idx < objc; idx++) {
elem = get_str_from_obj(objv[idx]);
+ if (taint_flag) RbTk_OBJ_UNTRUST(elem);
+
#ifdef HAVE_RUBY_ENCODING_H
if (rb_enc_get_index(elem) == ENCODING_INDEX_BINARY) {
rb_enc_associate_index(elem, ENCODING_INDEX_BINARY);
@@ -8857,7 +9094,6 @@ lib_split_tklist_core(ip_obj, list_str)
rb_ivar_set(elem, ID_at_enc, list_ivar_enc);
}
#endif
- if (taint_flag) OBJ_TAINT(elem);
/* RARRAY(ary)->ptr[idx] = elem; */
rb_ary_push(ary, elem);
}
@@ -8889,7 +9125,7 @@ lib_split_tklist_core(ip_obj, list_str)
}
ary = rb_ary_new2(argc);
- if (taint_flag) OBJ_TAINT(ary);
+ if (taint_flag) RbTk_OBJ_UNTRUST(ary);
old_gc = rb_gc_disable();
@@ -9009,7 +9245,7 @@ lib_merge_tklist(argc, argv, obj)
/* create object */
str = rb_str_new(result, dst - result - 1);
- if (taint_flag) OBJ_TAINT(str);
+ if (taint_flag) RbTk_OBJ_UNTRUST(str);
#if 0 /* use Tcl_EventuallyFree */
Tcl_EventuallyFree((ClientData)result, TCL_DYNAMIC); /* XXXXXXXX */
#else
@@ -9057,7 +9293,7 @@ lib_conv_listelement(self, src)
#endif
rb_str_resize(dst, len);
- if (taint_flag) OBJ_TAINT(dst);
+ if (taint_flag) RbTk_OBJ_UNTRUST(dst);
rb_thread_critical = thr_crit_bup;
@@ -9400,11 +9636,10 @@ update_encoding_table(table, interp, error_mode)
{
struct tcltkip *ptr;
int retry = 0;
- int i, idx, objc;
+ int i, objc;
Tcl_Obj **objv;
Tcl_Obj *enc_list;
volatile VALUE encname = Qnil;
- volatile VALUE encobj = Qnil;
/* interpreter check */
if (NIL_P(interp)) return 0;
@@ -9446,7 +9681,6 @@ encoding_table_get_name_core(table, enc, error_mode)
VALUE error_mode;
{
volatile VALUE name = Qnil;
- int retry = 0;
enc = rb_funcall(enc, ID_to_s, 0, 0);
name = rb_hash_lookup(table, enc);
@@ -9519,7 +9753,8 @@ encoding_table_get_obj(table, enc)
#ifdef HAVE_RUBY_ENCODING_H
static VALUE
-create_encoding_table(interp)
+create_encoding_table_core(arg, interp)
+ VALUE arg;
VALUE interp;
{
struct tcltkip *ptr = get_ip(interp);
@@ -9530,7 +9765,11 @@ create_encoding_table(interp)
Tcl_Obj **objv;
Tcl_Obj *enc_list;
- rb_secure(4);
+#ifdef HAVE_RB_SET_SAFE_LEVEL_FORCE
+ rb_set_safe_level_force(0);
+#else
+ rb_set_safe_level(0);
+#endif
/* set 'binary' encoding */
encobj = rb_enc_from_encoding(rb_enc_from_index(ENCODING_INDEX_BINARY));
@@ -9610,7 +9849,8 @@ create_encoding_table(interp)
#else /* ! HAVE_RUBY_ENCODING_H */
#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 1)
static VALUE
-create_encoding_table(interp)
+create_encoding_table_core(arg, interp)
+ VALUE arg;
VALUE interp;
{
struct tcltkip *ptr = get_ip(interp);
@@ -9651,7 +9891,8 @@ create_encoding_table(interp)
#else /* Tcl/Tk 7.x or 8.0 */
static VALUE
-create_encoding_table(interp)
+create_encoding_table_core(arg, interp)
+ VALUE arg;
VALUE interp;
{
volatile VALUE table = rb_hash_new();
@@ -9663,6 +9904,14 @@ create_encoding_table(interp)
#endif
static VALUE
+create_encoding_table(interp)
+ VALUE interp;
+{
+ return rb_funcall(rb_proc_new(create_encoding_table_core, interp),
+ ID_call, 0);
+}
+
+static VALUE
ip_get_encoding_table(interp)
VALUE interp;
{
@@ -10041,6 +10290,8 @@ Init_tcltklib()
rb_define_method(ip, "has_mainwindow?", ip_has_mainwindow_p, 0);
rb_define_method(ip, "invalid_namespace?", ip_has_invalid_namespace_p, 0);
rb_define_method(ip, "_eval", ip_eval, 1);
+ rb_define_method(ip, "_cancel_eval", ip_cancel_eval, -1);
+ rb_define_method(ip, "_cancel_eval_unwind", ip_cancel_eval_unwind, -1);
rb_define_method(ip, "_toUTF8", ip_toUTF8, -1);
rb_define_method(ip, "_fromUTF8", ip_fromUTF8, -1);
rb_define_method(ip, "_thread_vwait", ip_thread_vwait, 1);
@@ -10103,12 +10354,13 @@ Init_tcltklib()
/* --------------------------------------------------------------- */
eventloop_thread = Qnil;
+ eventloop_interp = (Tcl_Interp*)NULL;
#ifndef DEFAULT_EVENTLOOP_DEPTH
#define DEFAULT_EVENTLOOP_DEPTH 7
#endif
eventloop_stack = rb_ary_new2(DEFAULT_EVENTLOOP_DEPTH);
- OBJ_TAINT(eventloop_stack);
+ RbTk_OBJ_UNTRUST(eventloop_stack);
watchdog_thread = Qnil;
@@ -10152,4 +10404,3 @@ Init_tcltklib()
}
/* eof */
-
diff --git a/ext/tk/tkutil/extconf.rb b/ext/tk/tkutil/extconf.rb
index 34b91632eb..57de973c0a 100644
--- a/ext/tk/tkutil/extconf.rb
+++ b/ext/tk/tkutil/extconf.rb
@@ -7,8 +7,12 @@ end
if has_tk
require 'mkmf'
+
have_func("rb_obj_instance_exec", "ruby.h")
+ have_func("rb_obj_untrust", "ruby.h")
+ have_func("rb_obj_taint", "ruby.h")
have_func("rb_sym_to_s", "ruby.h")
have_func("strndup", "string.h")
+
create_makefile('tkutil')
end
diff --git a/ext/tk/tkutil/tkutil.c b/ext/tk/tkutil/tkutil.c
index 42c9330766..25011bb473 100644
--- a/ext/tk/tkutil/tkutil.c
+++ b/ext/tk/tkutil/tkutil.c
@@ -7,10 +7,16 @@
************************************************/
-#define TKUTIL_RELEASE_DATE "2008-05-23"
+#define TKUTIL_RELEASE_DATE "2009-07-12"
#include "ruby.h"
+#ifdef RUBY_VM
+static VALUE rb_thread_critical; /* dummy */
+#else
+/* On Ruby 1.8.x, use rb_thread_critical (defined at rubysig.h) */
+#include "rubysig.h"
+#endif
#ifdef HAVE_RUBY_ST_H
#include "ruby/st.h"
#else
@@ -54,6 +60,9 @@ static unsigned long CALLBACK_ID_NUM = 0;
/*************************************/
+#if defined(HAVE_RB_OBJ_INSTANCE_EXEC) && !defined(RUBY_VM)
+extern VALUE rb_obj_instance_exec _((int, VALUE*, VALUE));
+#endif
static VALUE
tk_s_new(argc, argv, klass)
int argc;
@@ -78,12 +87,34 @@ static VALUE
tkNone_to_s(self)
VALUE self;
{
+ return rb_str_new2("");
+}
+
+static VALUE
+tkNone_inspect(self)
+ VALUE self;
+{
return rb_str_new2("None");
}
/*************************************/
static VALUE
+tk_obj_untrust(self, obj)
+ VALUE self;
+ VALUE obj;
+{
+#ifdef HAVE_RB_OBJ_TAINT
+ rb_obj_taint(obj);
+#endif
+#ifdef HAVE_RB_OBJ_UNTRUST
+ rb_obj_untrust(obj);
+#endif
+
+ return obj;
+}
+
+static VALUE
tk_eval_cmd(argc, argv, self)
int argc;
VALUE argv[];
@@ -890,12 +921,15 @@ tk_conv_args(argc, argv, self)
{
int idx, size;
volatile VALUE dst;
+ int thr_crit_bup;
VALUE old_gc;
if (argc < 2) {
rb_raise(rb_eArgError, "too few arguments");
}
+ thr_crit_bup = rb_thread_critical;
+ rb_thread_critical = Qtrue;
old_gc = rb_gc_disable();
for(size = 0, idx = 2; idx < argc; idx++) {
@@ -920,6 +954,7 @@ tk_conv_args(argc, argv, self)
}
if (old_gc == Qfalse) rb_gc_enable();
+ rb_thread_critical = thr_crit_bup;
return rb_ary_plus(argv[0], dst);
}
@@ -1065,6 +1100,18 @@ tcl2rb_num_or_str(self, value)
rb_eArgError, 0);
}
+static VALUE
+tcl2rb_num_or_nil(self, value)
+ VALUE self;
+ VALUE value;
+{
+ rb_check_type(value, T_STRING);
+
+ if (RSTRING_LEN(value) == 0) return Qnil;
+
+ return tkstr_to_number(value);
+}
+
/*************************************/
@@ -1590,8 +1637,12 @@ cbsubst_scan_args(self, arg_key, val_ary)
unsigned char type_chr;
volatile VALUE dst = rb_ary_new2(vallen);
volatile VALUE proc;
+ int thr_crit_bup;
VALUE old_gc;
+ thr_crit_bup = rb_thread_critical;
+ rb_thread_critical = Qtrue;
+
old_gc = rb_gc_disable();
Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
@@ -1619,6 +1670,7 @@ cbsubst_scan_args(self, arg_key, val_ary)
}
if (old_gc == Qfalse) rb_gc_enable();
+ rb_thread_critical = thr_crit_bup;
return dst;
}
@@ -1743,7 +1795,7 @@ Init_tkutil()
TK_None = rb_obj_alloc(rb_cObject);
rb_define_const(mTK, "None", TK_None);
rb_define_singleton_method(TK_None, "to_s", tkNone_to_s, 0);
- rb_define_singleton_method(TK_None, "inspect", tkNone_to_s, 0);
+ rb_define_singleton_method(TK_None, "inspect", tkNone_inspect, 0);
OBJ_FREEZE(TK_None);
/* --------------------- */
@@ -1751,6 +1803,8 @@ Init_tkutil()
CALLBACK_TABLE = rb_hash_new();
/* --------------------- */
+ rb_define_singleton_method(mTK, "untrust", tk_obj_untrust, 1);
+
rb_define_singleton_method(mTK, "eval_cmd", tk_eval_cmd, -1);
rb_define_singleton_method(mTK, "callback", tk_do_callback, -1);
rb_define_singleton_method(mTK, "install_cmd", tk_install_cmd, -1);
@@ -1767,6 +1821,7 @@ Init_tkutil()
rb_define_singleton_method(mTK, "number", tcl2rb_number, 1);
rb_define_singleton_method(mTK, "string", tcl2rb_string, 1);
rb_define_singleton_method(mTK, "num_or_str", tcl2rb_num_or_str, 1);
+ rb_define_singleton_method(mTK, "num_or_nil", tcl2rb_num_or_nil, 1);
rb_define_method(mTK, "_toUTF8", tk_toUTF8, -1);
rb_define_method(mTK, "_fromUTF8", tk_fromUTF8, -1);
@@ -1780,6 +1835,7 @@ Init_tkutil()
rb_define_method(mTK, "number", tcl2rb_number, 1);
rb_define_method(mTK, "string", tcl2rb_string, 1);
rb_define_method(mTK, "num_or_str", tcl2rb_num_or_str, 1);
+ rb_define_method(mTK, "num_or_nil", tcl2rb_num_or_nil, 1);
/* --------------------- */
rb_global_variable(&ENCODING_NAME_UTF8);