mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* 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/branches/ruby_1_8@24064 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
			
			
This commit is contained in:
		
							parent
							
								
									4e94c36f3d
								
							
						
					
					
						commit
						41b74c6e20
					
				
					 535 changed files with 16499 additions and 10067 deletions
				
			
		
							
								
								
									
										26
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								ChangeLog
									
										
									
									
									
								
							|  | @ -1,3 +1,29 @@ | |||
| Mon Jul 13 08:01:00 2009  Hidetoshi NAGAI  <nagai@ai.kyutech.ac.jp> | ||||
| 
 | ||||
| 	* 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 | ||||
| 
 | ||||
| Mon Jul 13 01:18:46 2009  Nobuyoshi Nakada  <nobu@ruby-lang.org> | ||||
| 
 | ||||
| 	* time.c (time_timeval): rounds subsecond toward zero. | ||||
|  |  | |||
|  | @ -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,  | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 変換処理を呼び出す. | ||||
|  |  | |||
|  | @ -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> | ||||
| 
 | ||||
|  |  | |||
|  | @ -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") | ||||
|  |  | |||
							
								
								
									
										35
									
								
								ext/tk/config_list.in
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ext/tk/config_list.in
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
							
								
								
									
										1090
									
								
								ext/tk/extconf.rb
									
										
									
									
									
								
							
							
						
						
									
										1090
									
								
								ext/tk/extconf.rb
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -28,7 +28,13 @@ class << TclTkIp | |||
|     if Thread.current.group != ThreadGroup::Default | ||||
|       raise SecurityError, 'only ThreadGroup::Default can call TclTkIp.new' | ||||
|     end | ||||
|     __new__(*args) | ||||
|     obj = __new__(*args) | ||||
|     obj.instance_eval{ | ||||
|       @force_default_encoding ||= TkUtil.untrust([false]) | ||||
|       @encoding ||= TkUtil.untrust([nil]) | ||||
|       def @encoding.to_s; self.join(nil); end | ||||
|     } | ||||
|     obj | ||||
|   end | ||||
| end | ||||
| 
 | ||||
|  | @ -114,30 +120,31 @@ MultiTkIp_OK.freeze | |||
| class MultiTkIp | ||||
|   BASE_DIR = File.dirname(__FILE__) | ||||
| 
 | ||||
|   WITH_RUBY_VM  = Object.const_defined?(:VM) && ::VM.class == Class | ||||
|   WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.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 = [ | ||||
|  | @ -216,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 | ||||
|  | @ -226,8 +236,8 @@ class MultiTkIp | |||
|     def call(*args) | ||||
|       unless @ip.deleted? | ||||
|         current = Thread.current | ||||
|         backup_ip = current['callback_ip'] | ||||
|         current['callback_ip'] = @ip | ||||
|         backup_ip = current[:callback_ip] | ||||
|         current[:callback_ip] = @ip | ||||
|         begin | ||||
|           ret = @ip.cb_eval(@cmd, *args) | ||||
|           fail ret if ret.kind_of?(Exception) | ||||
|  | @ -260,7 +270,7 @@ class MultiTkIp | |||
|             fail e | ||||
|           end | ||||
|         ensure | ||||
|           current['callback_ip'] = backup_ip | ||||
|           current[:callback_ip] = backup_ip | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|  | @ -729,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" | ||||
|  | @ -748,19 +758,49 @@ class MultiTkIp | |||
|     else ### Ruby 1.9 !!!!!!!!!!! | ||||
|       @interp_thread = Thread.new{ | ||||
|         current = Thread.current | ||||
|         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 | ||||
| 
 | ||||
|         status = [nil] | ||||
|         def status.value | ||||
|           self[0] | ||||
|         end | ||||
|         def status.value=(val) | ||||
|           self[0] = val | ||||
|         end | ||||
|         current[:status] = status | ||||
| 
 | ||||
|         begin | ||||
|           current[:status] = interp.mainloop(true) | ||||
|           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] = e | ||||
|             current[:status].value = e | ||||
|             retry if interp.has_mainwindow? | ||||
|           ensure | ||||
|             mutex.synchronize{ cond_var.broadcast } | ||||
|           end | ||||
|         current[:status] = interp.mainloop(false) | ||||
| 
 | ||||
|           #Thread.current[:status].value = TclTkLib.mainloop(false) | ||||
|           current[:status].value = interp.mainloop(false) | ||||
| 
 | ||||
|         ensure | ||||
|           # 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 | ||||
|       } | ||||
|       until @interp_thread[:interp] | ||||
|         Thread.pass | ||||
|  | @ -778,13 +818,19 @@ class MultiTkIp | |||
|       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 | ||||
| 
 | ||||
|     @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 | ||||
| 
 | ||||
|  | @ -951,8 +997,9 @@ class MultiTkIp | |||
|       begin | ||||
|         class << subclass | ||||
|           self.methods.each{|m| | ||||
|             name = m.to_s | ||||
|             begin | ||||
|               unless m == '__id__' || m == '__send__' || m == 'freeze' | ||||
|               unless name == '__id__' || name == '__send__' || name == 'freeze' | ||||
|                 undef_method(m) | ||||
|               end | ||||
|             rescue Exception | ||||
|  | @ -1157,6 +1204,11 @@ class MultiTkIp | |||
|     # safe interpreter | ||||
|     ip_name = _create_slave_ip_name | ||||
|     slave_ip = @interp.create_slave(ip_name, true) | ||||
|     slave_ip.instance_eval{ | ||||
|       @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 | ||||
|     def slave_ip.safe_base? | ||||
|       true | ||||
|  | @ -1199,6 +1251,11 @@ class MultiTkIp | |||
| 
 | ||||
|     ip_name = _create_slave_ip_name | ||||
|     slave_ip = @interp.create_slave(ip_name, false) | ||||
|     slave_ip.instance_eval{ | ||||
|       @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) | ||||
|     slave_ip._invoke('set', 'argv', _keys2opts(keys)) | ||||
|     @interp._invoke('load', '', 'Tk', ip_name) | ||||
|  | @ -1249,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 = [] | ||||
| 
 | ||||
|  | @ -1268,9 +1325,22 @@ class MultiTkIp | |||
|       # create master-ip | ||||
|       unless WITH_RUBY_VM | ||||
|         @interp = TclTkIp.new(name, _keys2opts(tk_opts)) | ||||
|         @interp.instance_eval{ | ||||
|           @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 ||= TkUtil.untrust([false]) | ||||
|             @encoding ||= TkUtil.untrust([nil]) | ||||
|             def @encoding.to_s; self.join(nil); end | ||||
|           } | ||||
| 
 | ||||
|           #sleep | ||||
|           TclTkLib.mainloop(true) | ||||
|         } | ||||
|  | @ -1279,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? | ||||
|  | @ -1320,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 | ||||
| 
 | ||||
|  | @ -1341,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) | ||||
| 
 | ||||
|  | @ -1390,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 | ||||
|  | @ -1400,8 +1539,11 @@ class MultiTkIp | |||
| 
 | ||||
|   def self.__getip | ||||
|     current = Thread.current | ||||
|     if TclTkLib.mainloop_thread? != false && current['callback_ip'] | ||||
|       return current['callback_ip'] | ||||
|     if current.kind_of?(@@CALLBACK_SUBTHREAD) | ||||
|       return current[:callback_ip] | ||||
|     end | ||||
|     if TclTkLib.mainloop_thread? != false && current[:callback_ip] | ||||
|       return current[:callback_ip] | ||||
|     end | ||||
|     if current.group == ThreadGroup::Default | ||||
|       @@DEFAULT_MASTER | ||||
|  | @ -1422,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) | ||||
|  | @ -1445,14 +1587,16 @@ 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)} | ||||
|       #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) | ||||
|  | @ -1469,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) | ||||
|  | @ -1490,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 | ||||
|  | @ -1624,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 | ||||
| 
 | ||||
|  | @ -1768,7 +1915,6 @@ class MultiTkIp | |||
|   end | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| # for callback operation | ||||
| class MultiTkIp | ||||
|   def self.cb_entry_class | ||||
|  | @ -1792,6 +1938,13 @@ class MultiTkIp | |||
|     ret | ||||
|   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 | ||||
|  | @ -1799,6 +1952,7 @@ class MultiTkIp | |||
|       TkComm._get_eval_string(TkUtil.eval_cmd(cmd, *params)) | ||||
|     } | ||||
|   end | ||||
| =end | ||||
| =begin | ||||
|   def cb_eval(cmd, *args) | ||||
|     @callback_status[0] ||= TkVariable.new | ||||
|  | @ -1893,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 | ||||
|  | @ -1908,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 | ||||
|  | @ -1963,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 | ||||
|  | @ -1986,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 | ||||
|     begin | ||||
|       eval_proc_core(false, cmd, *args) | ||||
|     rescue Exception=>e | ||||
|       e | ||||
|     ensure | ||||
|     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 | ||||
|       backup_ip = current[:callback_ip] | ||||
|       current[:callback_ip] = self | ||||
|       begin | ||||
|         eval_proc_core(false, cmd, *args) | ||||
|       ensure | ||||
|       current['callback_ip'] = backup_ip | ||||
|         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, | ||||
|  | @ -2016,8 +2266,8 @@ class MultiTkIp | |||
|     if TclTkLib.mainloop_thread? == true | ||||
|       # call from eventloop | ||||
|       current = Thread.current | ||||
|       backup_ip = current['callback_ip'] | ||||
|       current['callback_ip'] = self | ||||
|       backup_ip = current[:callback_ip] | ||||
|       current[:callback_ip] = self | ||||
|       begin | ||||
|         eval_proc_core(false, | ||||
| 	               proc{|safe, *params| | ||||
|  | @ -2025,7 +2275,7 @@ class MultiTkIp | |||
|                          cmd.call(*params) | ||||
|                        }, *args) | ||||
|       ensure | ||||
|         current['callback_ip'] = backup_ip | ||||
|         current[:callback_ip] = backup_ip | ||||
|       end | ||||
|     else | ||||
|       eval_proc_core(true, | ||||
|  | @ -2036,6 +2286,7 @@ class MultiTkIp | |||
|                      *args) | ||||
|     end | ||||
|   end | ||||
| =end | ||||
|   alias call eval_proc | ||||
| 
 | ||||
|   def bg_eval_proc(*args) | ||||
|  | @ -2169,6 +2420,11 @@ end | |||
| 
 | ||||
| # event loop | ||||
| # all master/slave IPs are controled by only one event-loop | ||||
| class MultiTkIp | ||||
|   def self.default_master? | ||||
|     __getip == @@DEFAULT_MASTER | ||||
|   end | ||||
| end | ||||
| class << MultiTkIp | ||||
|   def mainloop(check_root = true) | ||||
|     __getip.mainloop(check_root) | ||||
|  | @ -2428,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 !!!!!!!!!!! | ||||
|  | @ -2457,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 | ||||
|  | @ -3289,6 +3546,42 @@ class << MultiTkIp | |||
|   def encoding_table | ||||
|     __getip.encoding_table | ||||
|   end | ||||
| 
 | ||||
|   def force_default_encoding=(mode) | ||||
|     __getip.force_default_encoding=(mode) | ||||
|   end | ||||
| 
 | ||||
|   def force_default_encoding? | ||||
|     __getip.force_default_encoding? | ||||
|   end | ||||
| 
 | ||||
|   def default_encoding=(enc) | ||||
|     __getip.default_encoding=(enc) | ||||
|   end | ||||
| 
 | ||||
|   def encoding=(enc) | ||||
|     __getip.encoding=(enc) | ||||
|   end | ||||
| 
 | ||||
|   def encoding_name | ||||
|     __getip.encoding_name | ||||
|   end | ||||
| 
 | ||||
|   def encoding_obj | ||||
|     __getip.encoding_obj | ||||
|   end | ||||
|   alias encoding encoding_name | ||||
|   alias default_encoding encoding_name | ||||
| 
 | ||||
|   def encoding_convertfrom(str, enc=None) | ||||
|     __getip.encoding_convertfrom(str, enc) | ||||
|   end | ||||
|   alias encoding_convert_from encoding_convertfrom | ||||
| 
 | ||||
|   def encoding_convertto(str, enc=None) | ||||
|     __getip.encoding_convertto(str, enc) | ||||
|   end | ||||
|   alias encoding_convert_to encoding_convertto | ||||
| end | ||||
| class MultiTkIp | ||||
|   def encoding_table | ||||
|  | @ -3339,20 +3632,48 @@ end | |||
| 
 | ||||
| 
 | ||||
| # remove methods for security | ||||
| =begin | ||||
| class MultiTkIp | ||||
|   INTERP_THREAD = @@DEFAULT_MASTER.instance_variable_get('@interp_thread') | ||||
|   INTERP_MUTEX  = INTERP_THREAD[:mutex] | ||||
|   INTERP_ROOT_CHECK = INTERP_THREAD[:root_check] | ||||
| 
 | ||||
|   # undef_method :instance_eval | ||||
|   undef_method :instance_variable_get | ||||
|   undef_method :instance_variable_set | ||||
| end | ||||
| 
 | ||||
| module TkCore | ||||
|   if MultiTkIp::WITH_RUBY_VM && | ||||
|       ! MultiTkIp::RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!! | ||||
|     INTERP_THREAD = MultiTkIp::INTERP_THREAD | ||||
|     INTERP_MUTEX  = MultiTkIp::INTERP_MUTEX | ||||
|     INTERP_ROOT_CHECK = MultiTkIp::INTERP_ROOT_CHECK | ||||
|   end | ||||
| end | ||||
| class MultiTkIp | ||||
|   remove_const(:INTERP_THREAD) | ||||
|   remove_const(:INTERP_MUTEX) | ||||
|   remove_const(:INTERP_ROOT_CHECK) | ||||
| end | ||||
| =end | ||||
| if MultiTkIp::WITH_RUBY_VM && | ||||
|     ! MultiTkIp::RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!! | ||||
|   class MultiTkIp | ||||
|     INTERP_THREAD = @@DEFAULT_MASTER.instance_variable_get('@interp_thread') | ||||
|     INTERP_THREAD_STATUS = INTERP_THREAD[:status] | ||||
|     INTERP_MUTEX  = INTERP_THREAD[:mutex] | ||||
|     INTERP_ROOT_CHECK = INTERP_THREAD[:root_check] | ||||
|   end | ||||
|   module TkCore | ||||
|     INTERP_THREAD = MultiTkIp::INTERP_THREAD | ||||
|     INTERP_THREAD_STATUS = MultiTkIp::INTERP_THREAD_STATUS | ||||
|     INTERP_MUTEX  = MultiTkIp::INTERP_MUTEX | ||||
|     INTERP_ROOT_CHECK = MultiTkIp::INTERP_ROOT_CHECK | ||||
|   end | ||||
|   class MultiTkIp | ||||
|     remove_const(:INTERP_THREAD) | ||||
|     remove_const(:INTERP_THREAD_STATUS) | ||||
|     remove_const(:INTERP_MUTEX) | ||||
|     remove_const(:INTERP_ROOT_CHECK) | ||||
|   end | ||||
|  |  | |||
|  | @ -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,10 +88,14 @@ class RemoteTkIp | |||
|     @slave_ip_tbl = {} | ||||
|     @slave_ip_top = {} | ||||
| 
 | ||||
|     @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? | ||||
|     @force_default_encoding ||= TkUtil.untrust([false]) | ||||
|     @encoding ||= TkUtil.untrust([nil]) | ||||
|     def @encoding.to_s; self.join(nil); end | ||||
| 
 | ||||
|     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 | ||||
| 
 | ||||
|  | @ -115,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 | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										310
									
								
								ext/tk/lib/tk.rb
									
										
									
									
									
								
							
							
						
						
									
										310
									
								
								ext/tk/lib/tk.rb
									
										
									
									
									
								
							|  | @ -15,12 +15,25 @@ 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 | ||||
|     '' | ||||
|   end | ||||
| 
 | ||||
|   alias __initialize__ initialize | ||||
|   private :__initialize__ | ||||
| 
 | ||||
|   def initialize(*args) | ||||
|     __initialize__(*args) | ||||
| 
 | ||||
|     @force_default_encoding ||= TkUtil.untrust([false]) | ||||
|     @encoding ||= TkUtil.untrust([nil]) | ||||
|     def @encoding.to_s; self.join(nil); end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| # define TkComm module (step 1: basic functions) | ||||
|  | @ -28,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 | ||||
|  | @ -39,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 | ||||
|  | @ -59,7 +75,7 @@ module TkComm | |||
|   Tk_WINDOWS.freeze | ||||
| 
 | ||||
|   self.instance_eval{ | ||||
|     @cmdtbl = [].taint | ||||
|     @cmdtbl = TkUtil.untrust([]) | ||||
|   } | ||||
| 
 | ||||
|   unless const_defined?(:GET_CONFIGINFO_AS_ARRAY) | ||||
|  | @ -102,6 +118,12 @@ module TkComm | |||
|       gen_class_name = ruby_class_name | ||||
|       classname_def = '' | ||||
|     else # ruby_class == nil | ||||
|       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 | ||||
|  | @ -111,6 +133,7 @@ module TkComm | |||
|             # ignore load error | ||||
|           end | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       unless ruby_class | ||||
|         std_class = 'Tk' << tk_class | ||||
|  | @ -120,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 | ||||
|  | @ -602,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', | ||||
|  | @ -792,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) | ||||
|  | @ -1099,12 +1154,8 @@ module TkCore | |||
|   extend TkComm | ||||
| 
 | ||||
|   WITH_RUBY_VM  = Object.const_defined?(:RubyVM) && ::RubyVM.class == Class | ||||
|   WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class | ||||
| 
 | ||||
|   unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD | ||||
|     ### Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
|     RUN_EVENTLOOP_ON_MAIN_THREAD = false | ||||
|   end | ||||
|   WITH_ENCODING = defined?(::Encoding.default_external) && true | ||||
|   #WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class | ||||
| 
 | ||||
|   unless self.const_defined? :INTERP | ||||
|     if self.const_defined? :IP_NAME | ||||
|  | @ -1123,8 +1174,48 @@ module TkCore | |||
|       opts = '' | ||||
|     end | ||||
| 
 | ||||
|     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 | ||||
|           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 | ||||
|         ip = nil | ||||
| 
 | ||||
|       else # Ruby 1.8.x | ||||
|         RUN_EVENTLOOP_ON_MAIN_THREAD = false | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     if !WITH_RUBY_VM || RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!! | ||||
|       INTERP = TclTkIp.new(name, opts) | ||||
|       INTERP = TclTkIp.new(name, opts) unless self.const_defined? :INTERP | ||||
|     else | ||||
|       INTERP_MUTEX = Mutex.new | ||||
|       INTERP_ROOT_CHECK = ConditionVariable.new | ||||
|  | @ -1135,17 +1226,42 @@ module TkCore | |||
|           Thread.current[:interp] = e | ||||
|           raise e | ||||
|         end | ||||
|         Thread.current[:status] = nil | ||||
| 
 | ||||
|         status = [nil] | ||||
|         def status.value | ||||
|           self[0] | ||||
|         end | ||||
|         def status.value=(val) | ||||
|           self[0] = val | ||||
|         end | ||||
| 
 | ||||
|         Thread.current[:status] = status | ||||
|         #sleep | ||||
| 
 | ||||
|         begin | ||||
|           Thread.current[:status] = TclTkLib.mainloop(true) | ||||
|           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] = e | ||||
|             Thread.current[:status].value = e | ||||
|             retry if interp.has_mainwindow? | ||||
|           ensure | ||||
|             INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast } | ||||
|           end | ||||
|         Thread.current[:status] = TclTkLib.mainloop(false) | ||||
| 
 | ||||
|           #Thread.current[:status].value = TclTkLib.mainloop(false) | ||||
|           Thread.current[:status].value = interp.mainloop(false) | ||||
| 
 | ||||
|         ensure | ||||
|           # 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 | ||||
|       } | ||||
| 
 | ||||
|       until INTERP_THREAD[:interp] | ||||
|  | @ -1155,17 +1271,22 @@ module TkCore | |||
|       raise INTERP_THREAD[:interp] if INTERP_THREAD[:interp].kind_of? Exception | ||||
| 
 | ||||
|       INTERP = INTERP_THREAD[:interp] | ||||
|       INTERP_THREAD_STATUS = INTERP_THREAD[:status] | ||||
|     end | ||||
| 
 | ||||
|     def INTERP.__getip | ||||
|       self | ||||
|     end | ||||
|     def INTERP.default_master? | ||||
|       true | ||||
|     end | ||||
| 
 | ||||
|     INTERP.instance_eval{ | ||||
|       # @tk_cmd_tbl = {}.taint | ||||
|       @tk_cmd_tbl = Hash.new{|hash, key| | ||||
|       # @tk_cmd_tbl = TkUtil.untrust({}) | ||||
|       @tk_cmd_tbl =  | ||||
|         TkUtil.untrust(Hash.new{|hash, key| | ||||
|                          fail IndexError, "unknown command ID '#{key}'" | ||||
|       }.taint | ||||
|                        }) | ||||
|       def @tk_cmd_tbl.[]=(idx,val) | ||||
|         if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default | ||||
|           fail SecurityError,"cannot change the entried command" | ||||
|  | @ -1173,12 +1294,16 @@ 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 ||= TkUtil.untrust([false]) | ||||
|       @encoding ||= TkUtil.untrust([nil]) | ||||
|       def @encoding.to_s; self.join(nil); end | ||||
| 
 | ||||
|       @cb_entry_class = Class.new(TkCallbackEntry){ | ||||
|         class << self | ||||
|  | @ -1231,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 | ||||
|  | @ -1269,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 | ||||
|  | @ -1279,6 +1405,11 @@ module TkCore | |||
|     end | ||||
|   end | ||||
| 
 | ||||
|   unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD | ||||
|     ### Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
|     RUN_EVENTLOOP_ON_MAIN_THREAD = false | ||||
|   end | ||||
| 
 | ||||
|   WIDGET_DESTROY_HOOK = '<WIDGET_DESTROY_HOOK>' | ||||
|   INTERP._invoke_without_enc('event', 'add', | ||||
|                              "<#{WIDGET_DESTROY_HOOK}>", '<Destroy>') | ||||
|  | @ -1642,17 +1773,36 @@ module TkCore | |||
|   end | ||||
| 
 | ||||
|   def mainloop(check_root = true) | ||||
|     if !TkCore::WITH_RUBY_VM || TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD | ||||
|     if !TkCore::WITH_RUBY_VM | ||||
|       TclTkLib.mainloop(check_root) | ||||
| 
 | ||||
|     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" | ||||
|       #end | ||||
|       if Thread.current != Thread.main | ||||
|         raise RuntimeError, "Tk.mainloop is allowed on the main thread only" | ||||
|       end | ||||
|       TclTkLib.mainloop(check_root) | ||||
| 
 | ||||
|     else ### Ruby 1.9 !!!!! | ||||
|       unless TkCore::INTERP.default_master? | ||||
|         # [MultiTkIp] slave interp ? | ||||
|         return TkCore::INTERP._thread_tkwait('window', '.') if check_root | ||||
|       end | ||||
| 
 | ||||
|       begin | ||||
|         TclTkLib.set_eventloop_window_mode(true) | ||||
|         if check_root | ||||
|           INTERP_MUTEX.synchronize{ | ||||
|             INTERP_ROOT_CHECK.wait(INTERP_MUTEX) | ||||
|             status = INTERP_THREAD[:status] | ||||
|             if status | ||||
|               INTERP_THREAD[:status] = nil | ||||
|             status = INTERP_THREAD_STATUS.value | ||||
|             if status && TkCore::INTERP.default_master? | ||||
|               INTERP_THREAD_STATUS.value = nil if $SAFE < 4 | ||||
|               raise status if status.kind_of?(Exception) | ||||
|             end | ||||
|           } | ||||
|  | @ -1838,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  <<<<< | ||||
|  | @ -1846,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  <<<<< | ||||
|  | @ -2140,7 +2290,7 @@ module Tk | |||
|   end | ||||
| 
 | ||||
|   def Tk.exit | ||||
|     tk_call_without_enc('destroy', '.') | ||||
|     TkCore::INTERP.has_mainwindow? && tk_call_without_enc('destroy', '.') | ||||
|   end | ||||
| 
 | ||||
|   ################################################ | ||||
|  | @ -2355,6 +2505,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) | |||
|         BINARY_NAME  = 'binary'.freeze | ||||
|         UTF8_NAME    = 'utf-8'.freeze | ||||
|         DEFAULT_EXTERNAL_NAME = RubyEncoding.default_external.name.freeze | ||||
|         DEFAULT_INTERNAL_NAME = RubyEncoding.default_internal.name.freeze rescue nil | ||||
| 
 | ||||
|         BINARY  = RubyEncoding.find(BINARY_NAME) | ||||
|         UNKNOWN = RubyEncoding.find('ASCII-8BIT') | ||||
|  | @ -2492,7 +2643,8 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) | |||
|         alias default_encoding encoding_name | ||||
| 
 | ||||
|         def tk_encoding_names | ||||
|           TkComm.simplelist(TkCore::INTERP._invoke_without_enc(Tk::Encoding::ENCNAMES_CMD[0], Tk::Encoding::ENCNAMES_CMD[1])) | ||||
|           #TkComm.simplelist(TkCore::INTERP._invoke_without_enc(Tk::Encoding::ENCNAMES_CMD[0], Tk::Encoding::ENCNAMES_CMD[1])) | ||||
|           TkComm.simplelist(TkCore::INTERP._invoke_without_enc('encoding', 'names')) | ||||
|         end | ||||
|         def encoding_names | ||||
|           self.tk_encoding_names.find_all{|name| | ||||
|  | @ -2626,16 +2778,16 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) | |||
| 
 | ||||
|   class TclTkIp | ||||
|     def force_default_encoding=(mode) | ||||
|       @force_default_encoding = (mode)? true: false | ||||
|       @force_default_encoding[0] = (mode)? true: false | ||||
|     end | ||||
| 
 | ||||
|     def force_default_encoding? | ||||
|       @force_default_encoding ||= false | ||||
|       @force_default_encoding[0] ||= false | ||||
|     end | ||||
| 
 | ||||
|     def default_encoding=(name) | ||||
|       name = name.name if name.kind_of?(::Encoding) if Tk::WITH_ENCODING | ||||
|       @encoding = name | ||||
|       name = name.name if Tk::WITH_ENCODING && name.kind_of?(::Encoding) | ||||
|       @encoding[0] = name.to_s.dup | ||||
|     end | ||||
| 
 | ||||
|     # from tkencoding.rb by ttate@jaist.ac.jp | ||||
|  | @ -2646,16 +2798,16 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) | |||
|     end | ||||
| 
 | ||||
|     def encoding_name | ||||
|       (@encoding)? @encoding.dup: nil | ||||
|       (@encoding[0])? @encoding[0].dup: nil | ||||
|     end | ||||
|     alias encoding encoding_name | ||||
|     alias default_encoding encoding_name | ||||
| 
 | ||||
|     def encoding_obj | ||||
|       if Tk::WITH_ENCODING | ||||
|         Tk::Encoding.tcl2rb_encoding(@encoding) | ||||
|         Tk::Encoding.tcl2rb_encoding(@encoding[0]) | ||||
|       else | ||||
|         (@encoding)? @encoding.dup: nil | ||||
|         (@encoding[0])? @encoding[0].dup: nil | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|  | @ -2686,7 +2838,12 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) | |||
|         enc_name ||= | ||||
|           Tk::Encoding::ENCODING_TABLE.get_name(str.encoding) rescue nil | ||||
| 
 | ||||
|         unless enc_name | ||||
|         if enc_name | ||||
|           # str has its encoding information | ||||
|           encstr = __toUTF8(str, enc_name) | ||||
|           encstr.force_encoding(Tk::Encoding::UTF8_NAME) | ||||
|           return encstr | ||||
|         else | ||||
|           # str.encoding isn't supported by Tk -> try to convert on Ruby | ||||
|           begin | ||||
|             return str.encode(Tk::Encoding::UTF8_NAME) # new string | ||||
|  | @ -2939,14 +3096,16 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) | |||
|     end | ||||
| 
 | ||||
|   else ### Ruby 1.9 !!!!!!!!!!!! | ||||
|     loc_enc_obj = ::Encoding.find(::Encoding.locale_charmap) | ||||
|     # loc_enc_obj = (::Encoding.find(::Encoding.locale_charmap) rescue Tk::Encoding::UNKNOWN) | ||||
|     loc_enc_obj = ::Encoding.find("locale") | ||||
|     ext_enc_obj = ::Encoding.default_external | ||||
|     int_enc_obj = ::Encoding.default_internal || ext_enc_obj | ||||
|     tksys_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(Tk.encoding_system) | ||||
|     # p [Tk.encoding, Tk.encoding_system, loc_enc_obj, ext_enc_obj] | ||||
| 
 | ||||
| =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 | ||||
|  | @ -3017,7 +3176,8 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) | |||
|     end | ||||
| 
 | ||||
|     unless enc_name | ||||
|       if ext_enc_obj == Tk::Encoding::UNKNOWN | ||||
|       #if ext_enc_obj == Tk::Encoding::UNKNOWN | ||||
|       if int_enc_obj == Tk::Encoding::UNKNOWN | ||||
|         if loc_enc_obj == Tk::Encoding::UNKNOWN | ||||
|           # use Tk.encoding_system | ||||
|           enc_name = tksys_enc_name | ||||
|  | @ -3025,7 +3185,7 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) | |||
|           # use locale_charmap | ||||
|           begin | ||||
|             loc_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(loc_enc_obj) | ||||
|             if loc_enc_name && loc_enc_name != tksys_enc_name | ||||
|             if loc_enc_name | ||||
|               # use locale_charmap | ||||
|               enc_name = loc_enc_name | ||||
|             else | ||||
|  | @ -3039,10 +3199,12 @@ if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) | |||
|         end | ||||
|       else | ||||
|         begin | ||||
|           ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj) | ||||
|           if ext_enc_name && ext_enc_name != tksys_enc_name | ||||
|             # use default_external | ||||
|             enc_name = ext_enc_name | ||||
|           #ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj) | ||||
|           #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_internal | ||||
|             enc_name = int_enc_name | ||||
|           else | ||||
|             # use Tk.encoding_system | ||||
|             enc_name = tksys_enc_name | ||||
|  | @ -3194,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) | ||||
|       } | ||||
|  | @ -3322,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 | ||||
|  | @ -3382,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 | ||||
|  | @ -3616,6 +3778,12 @@ 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 | ||||
|  | @ -4021,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] | ||||
|  | @ -4211,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 | ||||
|  | @ -4250,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 | ||||
|  | @ -4597,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 | ||||
|  | @ -4636,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 | ||||
|  | @ -4779,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_? | ||||
|  | @ -5466,7 +5636,7 @@ TkWidget = TkWindow | |||
| #Tk.freeze | ||||
| 
 | ||||
| module Tk | ||||
|   RELEASE_DATE = '2008-12-04'.freeze | ||||
|   RELEASE_DATE = '2009-07-12'.freeze | ||||
| 
 | ||||
|   autoload :AUTO_PATH,        'tk/variable' | ||||
|   autoload :TCL_PACKAGE_PATH, 'tk/variable' | ||||
|  |  | |||
|  | @ -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) | ||||
|       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) | ||||
|         end | ||||
|       } | ||||
|     end | ||||
| 
 | ||||
|     # 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) | ||||
|       else | ||||
|         # file => loaded class object | ||||
|         Object.const_set(sym, file) | ||||
|       end | ||||
|       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 | ||||
| 
 | ||||
|   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 | ||||
| 
 | ||||
|   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) | ||||
|     } | ||||
| 
 | ||||
|     # update current alias | ||||
|     # 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 | ||||
|         # New definition | ||||
|         @TOPLEVEL_ALIAS_OWNER[sym] = target | ||||
|         replace_topalias(sym, obj) | ||||
|         replace_topobj(sym, obj) | ||||
|       end | ||||
|     } | ||||
| 
 | ||||
|     # 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 | ||||
|  | @ -394,7 +740,7 @@ Tk.default_widget_set = :Tk | |||
| 
 | ||||
| ############################################ | ||||
| #  depend on the version of Tcl/Tk | ||||
| # major, minor, type, type_name, patchlevel = TclTkLib.get_version | ||||
| # major, minor, type, patchlevel = TclTkLib.get_version | ||||
| 
 | ||||
| ############################################ | ||||
| # Ttk (Tile) support | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										118
									
								
								ext/tk/lib/tk/busy.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								ext/tk/lib/tk/busy.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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,  | ||||
| #Tk.__set_toplevel_aliases__(:Tk, Tk::CheckButton, | ||||
| #                            :TkCheckButton, :TkCheckbutton) | ||||
| Tk.__set_loaded_toplevel_aliases__('tk/checkbutton.rb', :Tk, Tk::CheckButton, | ||||
|                                    :TkCheckButton, :TkCheckbutton) | ||||
|  |  | |||
|  | @ -145,17 +145,35 @@ module TkComposite | |||
|     str.chop << ' @epath=' << @epath.inspect << '>' | ||||
|   end | ||||
| 
 | ||||
|   def option_methods(*opts) | ||||
|     opts.each{|m_set, m_cget, m_info| | ||||
|   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) | ||||
|     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) | ||||
|     if wins.length == 0 | ||||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										166
									
								
								ext/tk/lib/tk/fontchooser.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								ext/tk/lib/tk/fontchooser.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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,9 +387,33 @@ 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 | ||||
|   def initialize(parent, type=None) | ||||
|  | @ -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,  | ||||
| #Tk.__set_toplevel_aliases__(:Tk, Tk::OptionMenubutton, | ||||
| #                            :TkOptionMenubutton, :TkOptionMenuButton) | ||||
| Tk.__set_loaded_toplevel_aliases__('tk/menu.rb', :Tk, Tk::OptionMenubutton, | ||||
|                                    :TkOptionMenubutton, :TkOptionMenuButton) | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|     tearoff = keys.delete('tearoff') if keys.key?('tearoff') | ||||
|       _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 | ||||
|       } | ||||
| 
 | ||||
|     if _use_menubar?(parent) | ||||
|       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) && ! 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| | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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} { | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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,  | ||||
| #Tk.__set_toplevel_aliases__(:Tk, Tk::PanedWindow, | ||||
| #                            :TkPanedWindow, :TkPanedwindow) | ||||
| Tk.__set_loaded_toplevel_aliases__('tk/panedwindow.rb', :Tk, Tk::PanedWindow, | ||||
|                                    :TkPanedWindow, :TkPanedwindow) | ||||
|  |  | |||
|  | @ -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,  | ||||
| #Tk.__set_toplevel_aliases__(:Tk, Tk::RadioButton, | ||||
| #                            :TkRadioButton, :TkRadiobutton) | ||||
| Tk.__set_loaded_toplevel_aliases__('tk/radiobutton.rb', :Tk, Tk::RadioButton, | ||||
|                                    :TkRadioButton, :TkRadiobutton) | ||||
|  |  | |||
|  | @ -52,7 +52,7 @@ class Tk::Root<TkWindow | |||
|   end | ||||
| 
 | ||||
|   WidgetClassName = 'Tk'.freeze | ||||
|   WidgetClassNames[WidgetClassName] = self | ||||
|   WidgetClassNames[WidgetClassName] ||= self | ||||
| 
 | ||||
|   def self.to_eval | ||||
|     # self::WidgetClassName | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
|     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) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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} { | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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 | ||||
|  | @ -26,7 +26,7 @@ class TkVariable | |||
|     TkVar_ID_TBL.mutex.synchronize{ TkVar_ID_TBL.clear } | ||||
|   } | ||||
| 
 | ||||
|   major, minor, type, type_name, patchlevel = TclTkLib.get_version | ||||
|   major, minor, type, patchlevel = TclTkLib.get_version | ||||
|   USE_OLD_TRACE_OPTION_STYLE = (major < 8) || (major == 8 && minor < 4) | ||||
| 
 | ||||
|   #TkCore::INTERP.add_tk_procs('rb_var', 'args', | ||||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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/ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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={}) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,5 +17,5 @@ end | |||
| class Tk::BWidget::ArrowButton | ||||
|   TkCommandNames = ['ArrowButton'.freeze].freeze | ||||
|   WidgetClassName = 'ArrowButton'.freeze | ||||
|   WidgetClassNames[WidgetClassName] = self | ||||
|   WidgetClassNames[WidgetClassName] ||= self | ||||
| end | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ end | |||
| class Tk::BWidget::ButtonBox | ||||
|   TkCommandNames = ['ButtonBox'.freeze].freeze | ||||
|   WidgetClassName = 'ButtonBox'.freeze | ||||
|   WidgetClassNames[WidgetClassName] = self | ||||
|   WidgetClassNames[WidgetClassName] ||= self | ||||
| 
 | ||||
|   include TkItemConfigMethod | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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') | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 = '' | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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))) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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' << | ||||
|  |  | |||
|  | @ -16,5 +16,5 @@ end | |||
| class Tk::BWidget::ProgressBar | ||||
|   TkCommandNames = ['ProgressBar'.freeze].freeze | ||||
|   WidgetClassName = 'ProgressBar'.freeze | ||||
|   WidgetClassNames[WidgetClassName] = self | ||||
|   WidgetClassNames[WidgetClassName] ||= self | ||||
| end | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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')) | ||||
|  |  | |||
|  | @ -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')) | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -16,5 +16,5 @@ end | |||
| class Tk::BWidget::Separator | ||||
|   TkCommandNames = ['Separator'.freeze].freeze | ||||
|   WidgetClassName = 'Separator'.freeze | ||||
|   WidgetClassNames[WidgetClassName] = self | ||||
|   WidgetClassNames[WidgetClassName] ||= self | ||||
| end | ||||
|  |  | |||
|  | @ -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' | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 nagai
						nagai