1# 2# tk.rb - Tk interface module using tcltklib 3# by Yukihiro Matsumoto <matz@netlab.jp> 4 5# use Shigehiro's tcltklib 6require 'tcltklib' 7require 'tkutil' 8 9# autoload 10require 'tk/autoload' 11 12# for Mutex 13require 'thread' 14 15class TclTkIp 16 # backup original (without encoding) _eval and _invoke 17 alias _eval_without_enc _eval 18 alias __eval__ _eval 19 alias _invoke_without_enc _invoke 20 alias __invoke__ _invoke 21 22 def _ip_id_ 23 # for RemoteTkIp 24 '' 25 end 26 27 alias __initialize__ initialize 28 private :__initialize__ 29 30 def initialize(*args) 31 __initialize__(*args) 32 33 @force_default_encoding ||= TkUtil.untrust([false]) 34 @encoding ||= TkUtil.untrust([nil]) 35 def @encoding.to_s; self.join(nil); end 36 end 37end 38 39# define TkComm module (step 1: basic functions) 40module TkComm 41 include TkUtil 42 extend TkUtil 43 44 WidgetClassNames = TkUtil.untrust({}) 45 TkExtlibAutoloadModule = TkUtil.untrust([]) 46 47 # None = Object.new ### --> definition is moved to TkUtil module 48 # def None.to_s 49 # 'None' 50 # end 51 # None.freeze 52 53 #Tk_CMDTBL = {} 54 #Tk_WINDOWS = {} 55 Tk_IDs = [ 56 TkUtil.untrust("00000"), # [0]-cmdid 57 TkUtil.untrust("00000") # [1]-winid 58 ] 59 Tk_IDs.instance_eval{ 60 @mutex = Mutex.new 61 def mutex; @mutex; end 62 freeze 63 } 64 65 # for backward compatibility 66 Tk_CMDTBL = Object.new 67 def Tk_CMDTBL.method_missing(id, *args) 68 TkCore::INTERP.tk_cmd_tbl.__send__(id, *args) 69 end 70 Tk_CMDTBL.freeze 71 Tk_WINDOWS = Object.new 72 def Tk_WINDOWS.method_missing(id, *args) 73 TkCore::INTERP.tk_windows.__send__(id, *args) 74 end 75 Tk_WINDOWS.freeze 76 77 self.instance_eval{ 78 @cmdtbl = TkUtil.untrust([]) 79 } 80 81 unless const_defined?(:GET_CONFIGINFO_AS_ARRAY) 82 # GET_CONFIGINFO_AS_ARRAY = false => returns a Hash { opt =>val, ... } 83 # true => returns an Array [[opt,val], ... ] 84 # val is a list which includes resource info. 85 GET_CONFIGINFO_AS_ARRAY = true 86 end 87 unless const_defined?(:GET_CONFIGINFOwoRES_AS_ARRAY) 88 # for configinfo without resource info; list of [opt, value] pair 89 # false => returns a Hash { opt=>val, ... } 90 # true => returns an Array [[opt,val], ... ] 91 GET_CONFIGINFOwoRES_AS_ARRAY = true 92 end 93 # *** ATTENTION *** 94 # 'current_configinfo' method always returns a Hash under all cases of above. 95 96 def error_at 97 frames = caller() 98 frames.delete_if do |c| 99 c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+! 100 end 101 frames 102 end 103 private :error_at 104 105 def _genobj_for_tkwidget(path) 106 return TkRoot.new if path == '.' 107 108 begin 109 #tk_class = TkCore::INTERP._invoke('winfo', 'class', path) 110 tk_class = Tk.ip_invoke_without_enc('winfo', 'class', path) 111 rescue 112 return path 113 end 114 115 if ruby_class = WidgetClassNames[tk_class] 116 ruby_class_name = ruby_class.name 117 # gen_class_name = ruby_class_name + 'GeneratedOnTk' 118 gen_class_name = ruby_class_name 119 classname_def = '' 120 else # ruby_class == nil 121 if Tk.const_defined?(tk_class) 122 Tk.const_get(tk_class) # auto_load 123 ruby_class = WidgetClassNames[tk_class] 124 end 125 126 unless ruby_class 127 mods = TkExtlibAutoloadModule.find_all{|m| m.const_defined?(tk_class)} 128 mods.each{|mod| 129 begin 130 mod.const_get(tk_class) # auto_load 131 break if (ruby_class = WidgetClassNames[tk_class]) 132 rescue LoadError 133 # ignore load error 134 end 135 } 136 end 137 138 unless ruby_class 139 std_class = 'Tk' << tk_class 140 if Object.const_defined?(std_class) 141 Object.const_get(std_class) # auto_load 142 ruby_class = WidgetClassNames[tk_class] 143 end 144 end 145 146 unless ruby_class 147 if Tk.const_defined?('TOPLEVEL_ALIASES') && 148 Tk::TOPLEVEL_ALIASES.const_defined?(std_class) 149 Tk::TOPLEVEL_ALIASES.const_get(std_class) # auto_load 150 ruby_class = WidgetClassNames[tk_class] 151 end 152 end 153 154 if ruby_class 155 # found 156 ruby_class_name = ruby_class.name 157 gen_class_name = ruby_class_name 158 classname_def = '' 159 else 160 # unknown 161 ruby_class_name = 'TkWindow' 162 gen_class_name = 'TkWidget_' + tk_class 163 classname_def = "WidgetClassName = '#{tk_class}'.freeze" 164 end 165 end 166 167################################### 168=begin 169 if ruby_class = WidgetClassNames[tk_class] 170 ruby_class_name = ruby_class.name 171 # gen_class_name = ruby_class_name + 'GeneratedOnTk' 172 gen_class_name = ruby_class_name 173 classname_def = '' 174 else 175 mod = TkExtlibAutoloadModule.find{|m| m.const_defined?(tk_class)} 176 if mod 177 ruby_class_name = mod.name + '::' + tk_class 178 gen_class_name = ruby_class_name 179 classname_def = '' 180 elsif Object.const_defined?('Tk' + tk_class) 181 ruby_class_name = 'Tk' + tk_class 182 # gen_class_name = ruby_class_name + 'GeneratedOnTk' 183 gen_class_name = ruby_class_name 184 classname_def = '' 185 else 186 ruby_class_name = 'TkWindow' 187 # gen_class_name = ruby_class_name + tk_class + 'GeneratedOnTk' 188 gen_class_name = 'TkWidget_' + tk_class 189 classname_def = "WidgetClassName = '#{tk_class}'.freeze" 190 end 191 end 192=end 193 194=begin 195 unless Object.const_defined? gen_class_name 196 Object.class_eval "class #{gen_class_name}<#{ruby_class_name} 197 #{classname_def} 198 end" 199 end 200 Object.class_eval "#{gen_class_name}.new('widgetname'=>'#{path}', 201 'without_creating'=>true)" 202=end 203 base = Object 204 gen_class_name.split('::').each{|klass| 205 next if klass == '' 206 if base.const_defined?(klass) 207 base = base.class_eval klass 208 else 209 base = base.class_eval "class #{klass}<#{ruby_class_name} 210 #{classname_def} 211 end 212 #{klass}" 213 end 214 } 215 base.class_eval "#{gen_class_name}.new('widgetname'=>'#{path}', 216 'without_creating'=>true)" 217 end 218 private :_genobj_for_tkwidget 219 module_function :_genobj_for_tkwidget 220 221 def _at(x,y=nil) 222 if y 223 "@#{Integer(x)},#{Integer(y)}" 224 else 225 "@#{Integer(x)}" 226 end 227 end 228 module_function :_at 229 230 def tk_tcl2ruby(val, enc_mode = false, listobj = true) 231=begin 232 if val =~ /^rb_out\S* (c(_\d+_)?\d+)/ 233 #return Tk_CMDTBL[$1] 234 return TkCore::INTERP.tk_cmd_tbl[$1] 235 #cmd_obj = TkCore::INTERP.tk_cmd_tbl[$1] 236 #if cmd_obj.kind_of?(Proc) || cmd_obj.kind_of?(Method) 237 # cmd_obj 238 #else 239 # cmd_obj.cmd 240 #end 241 end 242=end 243 if val =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ 244 return TkCore::INTERP.tk_cmd_tbl[$4] 245 end 246 #if val.include? ?\s 247 # return val.split.collect{|v| tk_tcl2ruby(v)} 248 #end 249 case val 250 when /\A@font\S+\z/ 251 TkFont.get_obj(val) 252 when /\A-?\d+\z/ 253 val.to_i 254 when /\A\.\S*\z/ 255 #Tk_WINDOWS[val] ? Tk_WINDOWS[val] : _genobj_for_tkwidget(val) 256 TkCore::INTERP.tk_windows[val]? 257 TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val) 258 when /\Ai(_\d+_)?\d+\z/ 259 TkImage::Tk_IMGTBL.mutex.synchronize{ 260 TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val 261 } 262 when /\A-?\d+\.?\d*(e[-+]?\d+)?\z/ 263 val.to_f 264 when /\\ / 265 val.gsub(/\\ /, ' ') 266 when /[^\\] / 267 if listobj 268 #tk_split_escstr(val).collect{|elt| 269 # tk_tcl2ruby(elt, enc_mode, listobj) 270 #} 271 val = _toUTF8(val) unless enc_mode 272 tk_split_escstr(val, false, false).collect{|elt| 273 tk_tcl2ruby(elt, true, listobj) 274 } 275 elsif enc_mode 276 _fromUTF8(val) 277 else 278 val 279 end 280 else 281 if enc_mode 282 _fromUTF8(val) 283 else 284 val 285 end 286 end 287 end 288 289 private :tk_tcl2ruby 290 module_function :tk_tcl2ruby 291 #private_class_method :tk_tcl2ruby 292 293unless const_defined?(:USE_TCLs_LIST_FUNCTIONS) 294 USE_TCLs_LIST_FUNCTIONS = true 295end 296 297if USE_TCLs_LIST_FUNCTIONS 298 ########################################################################### 299 # use Tcl function version of split_list 300 ########################################################################### 301 302 def tk_split_escstr(str, src_enc=true, dst_enc=true) 303 str = _toUTF8(str) if src_enc 304 if dst_enc 305 TkCore::INTERP._split_tklist(str).map!{|s| _fromUTF8(s)} 306 else 307 TkCore::INTERP._split_tklist(str) 308 end 309 end 310 311 def tk_split_sublist(str, depth=-1, src_enc=true, dst_enc=true) 312 # return [] if str == "" 313 # list = TkCore::INTERP._split_tklist(str) 314 str = _toUTF8(str) if src_enc 315 316 if depth == 0 317 return "" if str == "" 318 list = [str] 319 else 320 return [] if str == "" 321 list = TkCore::INTERP._split_tklist(str) 322 end 323 if list.size == 1 324 # tk_tcl2ruby(list[0], nil, false) 325 tk_tcl2ruby(list[0], dst_enc, false) 326 else 327 list.collect{|token| tk_split_sublist(token, depth - 1, false, dst_enc)} 328 end 329 end 330 331 def tk_split_list(str, depth=0, src_enc=true, dst_enc=true) 332 return [] if str == "" 333 str = _toUTF8(str) if src_enc 334 TkCore::INTERP._split_tklist(str).map!{|token| 335 tk_split_sublist(token, depth - 1, false, dst_enc) 336 } 337 end 338 339 def tk_split_simplelist(str, src_enc=true, dst_enc=true) 340 #lst = TkCore::INTERP._split_tklist(str) 341 #if (lst.size == 1 && lst =~ /^\{.*\}$/) 342 # TkCore::INTERP._split_tklist(str[1..-2]) 343 #else 344 # lst 345 #end 346 347 str = _toUTF8(str) if src_enc 348 if dst_enc 349 TkCore::INTERP._split_tklist(str).map!{|s| _fromUTF8(s)} 350 else 351 TkCore::INTERP._split_tklist(str) 352 end 353 end 354 355 def array2tk_list(ary, enc=nil) 356 return "" if ary.size == 0 357 358 sys_enc = TkCore::INTERP.encoding 359 sys_enc = TclTkLib.encoding_system unless sys_enc 360 361 dst_enc = (enc == nil)? sys_enc: enc 362 363 dst = ary.collect{|e| 364 if e.kind_of? Array 365 s = array2tk_list(e, enc) 366 elsif e.kind_of? Hash 367 tmp_ary = [] 368 #e.each{|k,v| tmp_ary << k << v } 369 e.each{|k,v| tmp_ary << "-#{_get_eval_string(k)}" << v } 370 s = array2tk_list(tmp_ary, enc) 371 else 372 s = _get_eval_string(e, enc) 373 end 374 375 if dst_enc != true && dst_enc != false 376 if (s_enc = s.instance_variable_get(:@encoding)) 377 s_enc = s_enc.to_s 378 elsif TkCore::WITH_ENCODING 379 s_enc = s.encoding.name 380 else 381 s_enc = sys_enc 382 end 383 dst_enc = true if s_enc != dst_enc 384 end 385 386 s 387 } 388 389 if sys_enc && dst_enc 390 dst.map!{|s| _toUTF8(s)} 391 ret = TkCore::INTERP._merge_tklist(*dst) 392 if TkCore::WITH_ENCODING 393 if dst_enc.kind_of?(String) 394 ret = _fromUTF8(ret, dst_enc) 395 ret.force_encoding(dst_enc) 396 else 397 ret.force_encoding('utf-8') 398 end 399 else # without encoding 400 if dst_enc.kind_of?(String) 401 ret = _fromUTF8(ret, dst_enc) 402 ret.instance_variable_set(:@encoding, dst_enc) 403 else 404 ret.instance_variable_set(:@encoding, 'utf-8') 405 end 406 end 407 ret 408 else 409 TkCore::INTERP._merge_tklist(*dst) 410 end 411 end 412 413else 414 ########################################################################### 415 # use Ruby script version of split_list (traditional methods) 416 ########################################################################### 417 418 def tk_split_escstr(str, src_enc=true, dst_enc=true) 419 return [] if str == "" 420 list = [] 421 token = nil 422 escape = false 423 brace = 0 424 str.split('').each {|c| 425 brace += 1 if c == '{' && !escape 426 brace -= 1 if c == '}' && !escape 427 if brace == 0 && c == ' ' && !escape 428 list << token.gsub(/^\{(.*)\}$/, '\1') if token 429 token = nil 430 else 431 token = (token || "") << c 432 end 433 escape = (c == '\\' && !escape) 434 } 435 list << token.gsub(/^\{(.*)\}$/, '\1') if token 436 list 437 end 438 439 def tk_split_sublist(str, depth=-1, src_enc=true, dst_enc=true) 440 #return [] if str == "" 441 #return [tk_split_sublist(str[1..-2])] if str =~ /^\{.*\}$/ 442 #list = tk_split_escstr(str) 443 if depth == 0 444 return "" if str == "" 445 str = str[1..-2] if str =~ /^\{.*\}$/ 446 list = [str] 447 else 448 return [] if str == [] 449 return [tk_split_sublist(str[1..-2], depth - 1)] if str =~ /^\{.*\}$/ 450 list = tk_split_escstr(str) 451 end 452 if list.size == 1 453 tk_tcl2ruby(list[0], nil, false) 454 else 455 list.collect{|token| tk_split_sublist(token, depth - 1)} 456 end 457 end 458 459 def tk_split_list(str, depth=0, src_enc=true, dst_enc=true) 460 return [] if str == "" 461 tk_split_escstr(str).collect{|token| 462 tk_split_sublist(token, depth - 1) 463 } 464 end 465 466 def tk_split_simplelist(str, src_enc=true, dst_enc=true) 467 return [] if str == "" 468 list = [] 469 token = nil 470 escape = false 471 brace = 0 472 str.split('').each {|c| 473 if c == '\\' && !escape 474 escape = true 475 token = (token || "") << c if brace > 0 476 next 477 end 478 brace += 1 if c == '{' && !escape 479 brace -= 1 if c == '}' && !escape 480 if brace == 0 && c == ' ' && !escape 481 list << token.gsub(/^\{(.*)\}$/, '\1') if token 482 token = nil 483 else 484 token = (token || "") << c 485 end 486 escape = false 487 } 488 list << token.gsub(/^\{(.*)\}$/, '\1') if token 489 list 490 end 491 492 def array2tk_list(ary, enc=nil) 493 ary.collect{|e| 494 if e.kind_of? Array 495 "{#{array2tk_list(e, enc)}}" 496 elsif e.kind_of? Hash 497 # "{#{e.to_a.collect{|ee| array2tk_list(ee)}.join(' ')}}" 498 e.each{|k,v| tmp_ary << "-#{_get_eval_string(k)}" << v } 499 array2tk_list(tmp_ary, enc) 500 else 501 s = _get_eval_string(e, enc) 502 (s.index(/\s/) || s.size == 0)? "{#{s}}": s 503 end 504 }.join(" ") 505 end 506end 507 508 private :tk_split_escstr, :tk_split_sublist 509 private :tk_split_list, :tk_split_simplelist 510 private :array2tk_list 511 512 module_function :tk_split_escstr, :tk_split_sublist 513 module_function :tk_split_list, :tk_split_simplelist 514 module_function :array2tk_list 515 516 private_class_method :tk_split_escstr, :tk_split_sublist 517 private_class_method :tk_split_list, :tk_split_simplelist 518# private_class_method :array2tk_list 519 520=begin 521 ### --> definition is moved to TkUtil module 522 def _symbolkey2str(keys) 523 h = {} 524 keys.each{|key,value| h[key.to_s] = value} 525 h 526 end 527 private :_symbolkey2str 528 module_function :_symbolkey2str 529=end 530 531=begin 532 ### --> definition is moved to TkUtil module 533 # def hash_kv(keys, enc_mode = nil, conf = [], flat = false) 534 def hash_kv(keys, enc_mode = nil, conf = nil) 535 # Hash {key=>val, key=>val, ... } or Array [ [key, val], [key, val], ... ] 536 # ==> Array ['-key', val, '-key', val, ... ] 537 dst = [] 538 if keys and keys != None 539 keys.each{|k, v| 540 #dst.push("-#{k}") 541 dst.push('-' + k.to_s) 542 if v != None 543 # v = _get_eval_string(v, enc_mode) if (enc_mode || flat) 544 v = _get_eval_string(v, enc_mode) if enc_mode 545 dst.push(v) 546 end 547 } 548 end 549 if conf 550 conf + dst 551 else 552 dst 553 end 554 end 555 private :hash_kv 556 module_function :hash_kv 557=end 558 559=begin 560 ### --> definition is moved to TkUtil module 561 def bool(val) 562 case val 563 when "1", 1, 'yes', 'true' 564 true 565 else 566 false 567 end 568 end 569 570 def number(val) 571 case val 572 when /^-?\d+$/ 573 val.to_i 574 when /^-?\d+\.?\d*(e[-+]?\d+)?$/ 575 val.to_f 576 else 577 fail(ArgumentError, "invalid value for Number:'#{val}'") 578 end 579 end 580 def string(val) 581 if val == "{}" 582 '' 583 elsif val[0] == ?{ && val[-1] == ?} 584 val[1..-2] 585 else 586 val 587 end 588 end 589 def num_or_str(val) 590 begin 591 number(val) 592 rescue ArgumentError 593 string(val) 594 end 595 end 596=end 597 598 def list(val, depth=0, enc=true) 599 tk_split_list(val, depth, enc, enc) 600 end 601 def simplelist(val, src_enc=true, dst_enc=true) 602 tk_split_simplelist(val, src_enc, dst_enc) 603 end 604 def window(val) 605 if val =~ /^\./ 606 #Tk_WINDOWS[val]? Tk_WINDOWS[val] : _genobj_for_tkwidget(val) 607 TkCore::INTERP.tk_windows[val]? 608 TkCore::INTERP.tk_windows[val] : _genobj_for_tkwidget(val) 609 else 610 nil 611 end 612 end 613 def image_obj(val) 614 if val =~ /^i(_\d+_)?\d+$/ 615 TkImage::Tk_IMGTBL.mutex.synchronize{ 616 TkImage::Tk_IMGTBL[val]? TkImage::Tk_IMGTBL[val] : val 617 } 618 else 619 val 620 end 621 end 622 def procedure(val) 623=begin 624 if val =~ /^rb_out\S* (c(_\d+_)?\d+)/ 625 #Tk_CMDTBL[$1] 626 #TkCore::INTERP.tk_cmd_tbl[$1] 627 TkCore::INTERP.tk_cmd_tbl[$1].cmd 628=end 629 if val =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ 630 return TkCore::INTERP.tk_cmd_tbl[$4].cmd 631 else 632 #nil 633 val 634 end 635 end 636 private :bool, :number, :num_or_str, :num_or_nil, :string 637 private :list, :simplelist, :window, :image_obj, :procedure 638 module_function :bool, :number, :num_or_str, :num_or_nil, :string 639 module_function :list, :simplelist, :window, :image_obj, :procedure 640 641 if (RUBY_VERSION.split('.').map{|n| n.to_i} <=> [1,8,7]) < 0 642 def slice_ary(ary, size) 643 sliced = [] 644 wk_ary = ary.dup 645 until wk_ary.size.zero? 646 sub_ary = [] 647 size.times{ sub_ary << wk_ary.shift } 648 yield(sub_ary) if block_given? 649 sliced << sub_ary 650 end 651 (block_given?)? ary: sliced 652 end 653 else 654 def slice_ary(ary, size, &b) 655 if b 656 ary.each_slice(size, &b) 657 else 658 ary.each_slice(size).to_a 659 end 660 end 661 end 662 private :slice_ary 663 module_function :slice_ary 664 665 def subst(str, *opts) 666 # opts := :nobackslashes | :nocommands | novariables 667 tk_call('subst', 668 *(opts.collect{|opt| 669 opt = opt.to_s 670 (opt[0] == ?-)? opt: '-' << opt 671 } << str)) 672 end 673 674 def _toUTF8(str, encoding = nil) 675 TkCore::INTERP._toUTF8(str, encoding) 676 end 677 def _fromUTF8(str, encoding = nil) 678 TkCore::INTERP._fromUTF8(str, encoding) 679 end 680 private :_toUTF8, :_fromUTF8 681 module_function :_toUTF8, :_fromUTF8 682 683 def _callback_entry_class?(cls) 684 cls <= Proc || cls <= Method || cls <= TkCallbackEntry 685 end 686 private :_callback_entry_class? 687 module_function :_callback_entry_class? 688 689 def _callback_entry?(obj) 690 obj.kind_of?(Proc) || obj.kind_of?(Method) || obj.kind_of?(TkCallbackEntry) 691 end 692 private :_callback_entry? 693 module_function :_callback_entry? 694 695=begin 696 ### --> definition is moved to TkUtil module 697 def _get_eval_string(str, enc_mode = nil) 698 return nil if str == None 699 if str.kind_of?(TkObject) 700 str = str.path 701 elsif str.kind_of?(String) 702 str = _toUTF8(str) if enc_mode 703 elsif str.kind_of?(Symbol) 704 str = str.id2name 705 str = _toUTF8(str) if enc_mode 706 elsif str.kind_of?(Hash) 707 str = hash_kv(str, enc_mode).join(" ") 708 elsif str.kind_of?(Array) 709 str = array2tk_list(str) 710 str = _toUTF8(str) if enc_mode 711 elsif str.kind_of?(Proc) 712 str = install_cmd(str) 713 elsif str == nil 714 str = "" 715 elsif str == false 716 str = "0" 717 elsif str == true 718 str = "1" 719 elsif (str.respond_to?(:to_eval)) 720 str = str.to_eval() 721 str = _toUTF8(str) if enc_mode 722 else 723 str = str.to_s() || '' 724 unless str.kind_of? String 725 fail RuntimeError, "fail to convert the object to a string" 726 end 727 str = _toUTF8(str) if enc_mode 728 end 729 return str 730 end 731=end 732=begin 733 def _get_eval_string(obj, enc_mode = nil) 734 case obj 735 when Numeric 736 obj.to_s 737 when String 738 (enc_mode)? _toUTF8(obj): obj 739 when Symbol 740 (enc_mode)? _toUTF8(obj.id2name): obj.id2name 741 when TkObject 742 obj.path 743 when Hash 744 hash_kv(obj, enc_mode).join(' ') 745 when Array 746 (enc_mode)? _toUTF8(array2tk_list(obj)): array2tk_list(obj) 747 when Proc, Method, TkCallbackEntry 748 install_cmd(obj) 749 when false 750 '0' 751 when true 752 '1' 753 when nil 754 '' 755 when None 756 nil 757 else 758 if (obj.respond_to?(:to_eval)) 759 (enc_mode)? _toUTF8(obj.to_eval): obj.to_eval 760 else 761 begin 762 obj = obj.to_s || '' 763 rescue 764 fail RuntimeError, "fail to convert object '#{obj}' to string" 765 end 766 (enc_mode)? _toUTF8(obj): obj 767 end 768 end 769 end 770 private :_get_eval_string 771 module_function :_get_eval_string 772=end 773 774=begin 775 ### --> definition is moved to TkUtil module 776 def _get_eval_enc_str(obj) 777 return obj if obj == None 778 _get_eval_string(obj, true) 779 end 780 private :_get_eval_enc_str 781 module_function :_get_eval_enc_str 782=end 783 784=begin 785 ### --> obsolete 786 def ruby2tcl(v, enc_mode = nil) 787 if v.kind_of?(Hash) 788 v = hash_kv(v) 789 v.flatten! 790 v.collect{|e|ruby2tcl(e, enc_mode)} 791 else 792 _get_eval_string(v, enc_mode) 793 end 794 end 795 private :ruby2tcl 796=end 797 798=begin 799 ### --> definition is moved to TkUtil module 800 def _conv_args(args, enc_mode, *src_args) 801 conv_args = [] 802 src_args.each{|arg| 803 conv_args << _get_eval_string(arg, enc_mode) unless arg == None 804 # if arg.kind_of?(Hash) 805 # arg.each{|k, v| 806 # args << '-' + k.to_s 807 # args << _get_eval_string(v, enc_mode) 808 # } 809 # elsif arg != None 810 # args << _get_eval_string(arg, enc_mode) 811 # end 812 } 813 args + conv_args 814 end 815 private :_conv_args 816=end 817 818 def _curr_cmd_id 819 #id = format("c%.4d", Tk_IDs[0]) 820 id = "c" + TkCore::INTERP._ip_id_ + TkComm::Tk_IDs[0] 821 end 822 def _next_cmd_id 823 TkComm::Tk_IDs.mutex.synchronize{ 824 id = _curr_cmd_id 825 #Tk_IDs[0] += 1 826 TkComm::Tk_IDs[0].succ! 827 id 828 } 829 end 830 private :_curr_cmd_id, :_next_cmd_id 831 module_function :_curr_cmd_id, :_next_cmd_id 832 833 def TkComm.install_cmd(cmd, local_cmdtbl=nil) 834 return '' if cmd == '' 835 begin 836 ns = TkCore::INTERP._invoke_without_enc('namespace', 'current') 837 ns = nil if ns == '::' # for backward compatibility 838 rescue 839 # probably, Tcl7.6 840 ns = nil 841 end 842 id = _next_cmd_id 843 #Tk_CMDTBL[id] = cmd 844 if cmd.kind_of?(TkCallbackEntry) 845 TkCore::INTERP.tk_cmd_tbl[id] = cmd 846 else 847 TkCore::INTERP.tk_cmd_tbl[id] = TkCore::INTERP.get_cb_entry(cmd) 848 end 849 @cmdtbl = [] unless defined? @cmdtbl 850 TkUtil.untrust(@cmdtbl) unless @cmdtbl.tainted? 851 @cmdtbl.push id 852 853 if local_cmdtbl && local_cmdtbl.kind_of?(Array) 854 begin 855 local_cmdtbl << id 856 rescue Exception 857 # ignore 858 end 859 end 860 861 #return Kernel.format("rb_out %s", id); 862 if ns 863 'rb_out' << TkCore::INTERP._ip_id_ << ' ' << ns << ' ' << id 864 else 865 'rb_out' << TkCore::INTERP._ip_id_ << ' ' << id 866 end 867 end 868 def TkComm.uninstall_cmd(id, local_cmdtbl=nil) 869 #id = $1 if /rb_out\S* (c(_\d+_)?\d+)/ =~ id 870 id = $4 if id =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ 871 872 if local_cmdtbl && local_cmdtbl.kind_of?(Array) 873 begin 874 local_cmdtbl.delete(id) 875 rescue Exception 876 # ignore 877 end 878 end 879 @cmdtbl.delete(id) 880 881 #Tk_CMDTBL.delete(id) 882 TkCore::INTERP.tk_cmd_tbl.delete(id) 883 end 884 # private :install_cmd, :uninstall_cmd 885 # module_function :install_cmd, :uninstall_cmd 886 def install_cmd(cmd) 887 TkComm.install_cmd(cmd, @cmdtbl) 888 end 889 def uninstall_cmd(id) 890 TkComm.uninstall_cmd(id, @cmdtbl) 891 end 892 893=begin 894 def install_win(ppath,name=nil) 895 if !name or name == '' 896 #name = format("w%.4d", Tk_IDs[1]) 897 #Tk_IDs[1] += 1 898 name = "w" + Tk_IDs[1] 899 Tk_IDs[1].succ! 900 end 901 if name[0] == ?. 902 @path = name.dup 903 elsif !ppath or ppath == "." 904 @path = Kernel.format(".%s", name); 905 else 906 @path = Kernel.format("%s.%s", ppath, name) 907 end 908 #Tk_WINDOWS[@path] = self 909 TkCore::INTERP.tk_windows[@path] = self 910 end 911=end 912 def install_win(ppath,name=nil) 913 if name 914 if name == '' 915 raise ArgumentError, "invalid wiget-name '#{name}'" 916 end 917 if name[0] == ?. 918 @path = '' + name 919 @path.freeze 920 return TkCore::INTERP.tk_windows[@path] = self 921 end 922 else 923 Tk_IDs.mutex.synchronize{ 924 name = "w" + TkCore::INTERP._ip_id_ + Tk_IDs[1] 925 Tk_IDs[1].succ! 926 } 927 end 928 if !ppath or ppath == '.' 929 @path = '.' + name 930 else 931 @path = ppath + '.' + name 932 end 933 @path.freeze 934 TkCore::INTERP.tk_windows[@path] = self 935 end 936 937 def uninstall_win() 938 #Tk_WINDOWS.delete(@path) 939 TkCore::INTERP.tk_windows.delete(@path) 940 end 941 private :install_win, :uninstall_win 942 943 def _epath(win) 944 if win.kind_of?(TkObject) 945 win.epath 946 elsif win.respond_to?(:epath) 947 win.epath 948 else 949 win 950 end 951 end 952 private :_epath 953end 954 955# define TkComm module (step 2: event binding) 956module TkComm 957 include TkEvent 958 extend TkEvent 959 960 def tk_event_sequence(context) 961 if context.kind_of? TkVirtualEvent 962 context = context.path 963 end 964 if context.kind_of? Array 965 context = context.collect{|ev| 966 if ev.kind_of? TkVirtualEvent 967 ev.path 968 else 969 ev 970 end 971 }.join("><") 972 end 973 if /,/ =~ context 974 context = context.split(/\s*,\s*/).join("><") 975 else 976 context 977 end 978 end 979 980 def _bind_core(mode, what, context, cmd, *args) 981 id = install_bind(cmd, *args) if cmd 982 begin 983 tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", 984 mode + id])) 985 rescue 986 uninstall_cmd(id) if cmd 987 fail 988 end 989 end 990 991 def _bind(what, context, cmd, *args) 992 _bind_core('', what, context, cmd, *args) 993 end 994 995 def _bind_append(what, context, cmd, *args) 996 _bind_core('+', what, context, cmd, *args) 997 end 998 999 def _bind_remove(what, context) 1000 tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", ''])) 1001 end 1002 1003 def _bindinfo(what, context=nil) 1004 if context 1005 if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!! 1006 enum_obj = tk_call_without_enc(*what+["<#{tk_event_sequence(context)}>"]).each_line 1007 else 1008 enum_obj = tk_call_without_enc(*what+["<#{tk_event_sequence(context)}>"]) 1009 end 1010 enum_obj.collect {|cmdline| 1011=begin 1012 if cmdline =~ /^rb_out\S* (c(?:_\d+_)?\d+)\s+(.*)$/ 1013 #[Tk_CMDTBL[$1], $2] 1014 [TkCore::INTERP.tk_cmd_tbl[$1], $2] 1015=end 1016 if cmdline =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/ 1017 [TkCore::INTERP.tk_cmd_tbl[$4], $5] 1018 else 1019 cmdline 1020 end 1021 } 1022 else 1023 tk_split_simplelist(tk_call_without_enc(*what)).collect!{|seq| 1024 l = seq.scan(/<*[^<>]+>*/).collect!{|subseq| 1025 case (subseq) 1026 when /^<<[^<>]+>>$/ 1027 TkVirtualEvent.getobj(subseq[1..-2]) 1028 when /^<[^<>]+>$/ 1029 subseq[1..-2] 1030 else 1031 subseq.split('') 1032 end 1033 }.flatten 1034 (l.size == 1) ? l[0] : l 1035 } 1036 end 1037 end 1038 1039 def _bind_core_for_event_class(klass, mode, what, context, cmd, *args) 1040 id = install_bind_for_event_class(klass, cmd, *args) if cmd 1041 begin 1042 tk_call_without_enc(*(what + ["<#{tk_event_sequence(context)}>", 1043 mode + id])) 1044 rescue 1045 uninstall_cmd(id) if cmd 1046 fail 1047 end 1048 end 1049 1050 def _bind_for_event_class(klass, what, context, cmd, *args) 1051 _bind_core_for_event_class(klass, '', what, context, cmd, *args) 1052 end 1053 1054 def _bind_append_for_event_class(klass, what, context, cmd, *args) 1055 _bind_core_for_event_class(klass, '+', what, context, cmd, *args) 1056 end 1057 1058 def _bind_remove_for_event_class(klass, what, context) 1059 _bind_remove(what, context) 1060 end 1061 1062 def _bindinfo_for_event_class(klass, what, context=nil) 1063 _bindinfo(what, context) 1064 end 1065 1066 private :tk_event_sequence 1067 private :_bind_core, :_bind, :_bind_append, :_bind_remove, :_bindinfo 1068 private :_bind_core_for_event_class, :_bind_for_event_class, 1069 :_bind_append_for_event_class, :_bind_remove_for_event_class, 1070 :_bindinfo_for_event_class 1071 1072 #def bind(tagOrClass, context, cmd=Proc.new, *args) 1073 # _bind(["bind", tagOrClass], context, cmd, *args) 1074 # tagOrClass 1075 #end 1076 def bind(tagOrClass, context, *args) 1077 # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 1078 if TkComm._callback_entry?(args[0]) || !block_given? 1079 cmd = args.shift 1080 else 1081 cmd = Proc.new 1082 end 1083 _bind(["bind", tagOrClass], context, cmd, *args) 1084 tagOrClass 1085 end 1086 1087 #def bind_append(tagOrClass, context, cmd=Proc.new, *args) 1088 # _bind_append(["bind", tagOrClass], context, cmd, *args) 1089 # tagOrClass 1090 #end 1091 def bind_append(tagOrClass, context, *args) 1092 # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 1093 if TkComm._callback_entry?(args[0]) || !block_given? 1094 cmd = args.shift 1095 else 1096 cmd = Proc.new 1097 end 1098 _bind_append(["bind", tagOrClass], context, cmd, *args) 1099 tagOrClass 1100 end 1101 1102 def bind_remove(tagOrClass, context) 1103 _bind_remove(['bind', tagOrClass], context) 1104 tagOrClass 1105 end 1106 1107 def bindinfo(tagOrClass, context=nil) 1108 _bindinfo(['bind', tagOrClass], context) 1109 end 1110 1111 #def bind_all(context, cmd=Proc.new, *args) 1112 # _bind(['bind', 'all'], context, cmd, *args) 1113 # TkBindTag::ALL 1114 #end 1115 def bind_all(context, *args) 1116 # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 1117 if TkComm._callback_entry?(args[0]) || !block_given? 1118 cmd = args.shift 1119 else 1120 cmd = Proc.new 1121 end 1122 _bind(['bind', 'all'], context, cmd, *args) 1123 TkBindTag::ALL 1124 end 1125 1126 #def bind_append_all(context, cmd=Proc.new, *args) 1127 # _bind_append(['bind', 'all'], context, cmd, *args) 1128 # TkBindTag::ALL 1129 #end 1130 def bind_append_all(context, *args) 1131 # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 1132 if TkComm._callback_entry?(args[0]) || !block_given? 1133 cmd = args.shift 1134 else 1135 cmd = Proc.new 1136 end 1137 _bind_append(['bind', 'all'], context, cmd, *args) 1138 TkBindTag::ALL 1139 end 1140 1141 def bind_remove_all(context) 1142 _bind_remove(['bind', 'all'], context) 1143 TkBindTag::ALL 1144 end 1145 1146 def bindinfo_all(context=nil) 1147 _bindinfo(['bind', 'all'], context) 1148 end 1149end 1150 1151 1152module TkCore 1153 include TkComm 1154 extend TkComm 1155 1156 WITH_RUBY_VM = Object.const_defined?(:RubyVM) && ::RubyVM.class == Class 1157 WITH_ENCODING = defined?(::Encoding.default_external) && true 1158 #WITH_ENCODING = Object.const_defined?(:Encoding) && ::Encoding.class == Class 1159 1160 unless self.const_defined? :INTERP 1161 if self.const_defined? :IP_NAME 1162 name = IP_NAME.to_s 1163 else 1164 #name = nil 1165 name = $0 1166 end 1167 if self.const_defined? :IP_OPTS 1168 if IP_OPTS.kind_of?(Hash) 1169 opts = hash_kv(IP_OPTS).join(' ') 1170 else 1171 opts = IP_OPTS.to_s 1172 end 1173 else 1174 opts = '' 1175 end 1176 1177 # RUN_EVENTLOOP_ON_MAIN_THREAD = true 1178 1179 unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD 1180 if WITH_RUBY_VM ### check Ruby 1.9 !!!!!!! 1181 # *** NEED TO FIX *** 1182 case RUBY_PLATFORM 1183 when /cygwin/ 1184 RUN_EVENTLOOP_ON_MAIN_THREAD = true 1185 when /darwin/ # MacOS X 1186=begin 1187 ip = TclTkIp.new(name, opts) 1188 if ip._invoke_without_enc('tk', 'windowingsystem') == 'aqua' && 1189 (TclTkLib.get_version<=>[8,4,TclTkLib::RELEASE_TYPE::FINAL,6]) > 0 1190=end 1191 if TclTkLib::WINDOWING_SYSTEM == 'aqua' && 1192 (TclTkLib.get_version<=>[8,4,TclTkLib::RELEASE_TYPE::FINAL,6]) > 0 1193 # *** KNOWN BUG *** 1194 # Main event loop thread of TkAqua (> Tk8.4.9) must be the main 1195 # application thread. So, ruby1.9 users must call Tk.mainloop on 1196 # the main application thread. 1197 # 1198 # *** ADD (2009/05/10) *** 1199 # In some cases (I don't know the description of conditions), 1200 # TkAqua 8.4.7 has a same kind of hang-up trouble. 1201 # So, if 8.4.7 or later, set RUN_EVENTLOOP_ON_MAIN_THREAD to true. 1202 # When you want to control this mode, please call the following 1203 # (set true/false as you want) before "require 'tk'". 1204 # ---------------------------------------------------------- 1205 # module TkCore; RUN_EVENTLOOP_ON_MAIN_THREAD = true; end 1206 # ---------------------------------------------------------- 1207 # 1208 # *** ADD (2010/07/05) *** 1209 # The value of TclTkLib::WINDOWING_SYSTEM is defined at compiling. 1210 # If it is inconsistent with linked DLL, please call the following 1211 # before "require 'tk'". 1212 # ---------------------------------------------------------- 1213 # require 'tcltklib' 1214 # module TclTkLib 1215 # remove_const :WINDOWING_SYSTEM 1216 # WINDOWING_SYSTEM = 'x11' # or 'aqua' 1217 # end 1218 # ---------------------------------------------------------- 1219 # 1220 RUN_EVENTLOOP_ON_MAIN_THREAD = true 1221 else 1222 RUN_EVENTLOOP_ON_MAIN_THREAD = false 1223=begin 1224 ip.delete 1225 ip = nil 1226=end 1227 end 1228 else 1229 RUN_EVENTLOOP_ON_MAIN_THREAD = false 1230 end 1231 1232 else # Ruby 1.8.x 1233 RUN_EVENTLOOP_ON_MAIN_THREAD = false 1234 end 1235 end 1236 1237 if !WITH_RUBY_VM || RUN_EVENTLOOP_ON_MAIN_THREAD ### check Ruby 1.9 !!!!!!! 1238 INTERP = TclTkIp.new(name, opts) unless self.const_defined? :INTERP 1239 else 1240 INTERP_MUTEX = Mutex.new 1241 INTERP_ROOT_CHECK = ConditionVariable.new 1242 INTERP_THREAD = Thread.new{ 1243 begin 1244 #Thread.current[:interp] = interp = TclTkIp.new(name, opts) 1245 interp = TclTkIp.new(name, opts) 1246 rescue => e 1247 Thread.current[:interp] = e 1248 raise e 1249 end 1250 1251 interp.mainloop_abort_on_exception = true 1252 Thread.current.instance_variable_set("@interp", interp) 1253 1254 status = [nil] 1255 def status.value 1256 self[0] 1257 end 1258 def status.value=(val) 1259 self[0] = val 1260 end 1261 1262 Thread.current[:status] = status 1263 #sleep 1264 1265 # like as 1.8, withdraw a root widget before calling Tk.mainloop 1266 interp._eval <<EOS 1267wm withdraw . 1268rename wm __wm_orig__ 1269proc wm {subcmd win args} { 1270 set val [eval [list __wm_orig__ $subcmd $win] $args] 1271 if {[string equal $subcmd withdraw] && [string equal $win .]} { 1272 rename wm {} 1273 rename __wm_orig__ wm 1274 } 1275 return $val 1276} 1277proc __startup_rbtk_mainloop__ {args} { 1278 rename __startup_rbtk_mainloop__ {} 1279 if {[info command __wm_orig__] == "__wm_orig__"} { 1280 rename wm {} 1281 rename __wm_orig__ wm 1282 if [string equal [wm state .] withdrawn] { 1283 wm deiconify . 1284 } 1285 } 1286} 1287set __initial_state_of_rubytk__ 1 1288trace add variable __initial_state_of_rubytk__ unset __startup_rbtk_mainloop__ 1289 1290# complete initializing 1291ruby {TkCore::INTERP_THREAD[:interp] = TkCore::INTERP_THREAD.instance_variable_get('@interp')} 1292EOS 1293 1294 begin 1295 begin 1296 #TclTkLib.mainloop_abort_on_exception = false 1297 #interp.mainloop_abort_on_exception = true 1298 #Thread.current[:interp] = interp 1299 #Thread.current[:status].value = TclTkLib.mainloop(true) 1300 Thread.current[:status].value = interp.mainloop(true) 1301 rescue SystemExit=>e 1302 Thread.current[:status].value = e 1303 rescue Exception=>e 1304 Thread.current[:status].value = e 1305 p e if $DEBUG 1306 retry if interp.has_mainwindow? 1307 ensure 1308 INTERP_MUTEX.synchronize{ INTERP_ROOT_CHECK.broadcast } 1309 end 1310 1311 unless interp.deleted? 1312 #Thread.current[:status].value = TclTkLib.mainloop(false) 1313 Thread.current[:status].value = interp.mainloop(false) 1314 end 1315 1316 ensure 1317 # interp must be deleted before the thread for interp is dead. 1318 # If not, raise Tcl_Panic on Tcl_AsyncDelete because async handler 1319 # deleted by the wrong thread. 1320 interp.delete 1321 end 1322 } 1323 1324 # check a Tcl/Tk interpreter is initialized 1325 until INTERP_THREAD[:interp] 1326 # Thread.pass 1327 INTERP_THREAD.run 1328 end 1329 1330 # INTERP_THREAD.run 1331 raise INTERP_THREAD[:interp] if INTERP_THREAD[:interp].kind_of? Exception 1332 1333 # check an eventloop is running 1334 while INTERP_THREAD.alive? && TclTkLib.mainloop_thread?.nil? 1335 INTERP_THREAD.run 1336 end 1337 1338 INTERP = INTERP_THREAD[:interp] 1339 INTERP_THREAD_STATUS = INTERP_THREAD[:status] 1340 1341 # delete the interpreter and kill the eventloop thread at exit 1342 END{ 1343 if INTERP_THREAD.alive? 1344 INTERP.delete 1345 INTERP_THREAD.kill 1346 end 1347 } 1348 1349 # (for safety's sake) force the eventloop to run 1350 INTERP_THREAD.run 1351 end 1352 1353 def INTERP.__getip 1354 self 1355 end 1356 def INTERP.default_master? 1357 true 1358 end 1359 1360 INTERP.instance_eval{ 1361 # @tk_cmd_tbl = TkUtil.untrust({}) 1362 @tk_cmd_tbl = 1363 TkUtil.untrust(Hash.new{|hash, key| 1364 fail IndexError, "unknown command ID '#{key}'" 1365 }) 1366 def @tk_cmd_tbl.[]=(idx,val) 1367 if self.has_key?(idx) && Thread.current.group != ThreadGroup::Default 1368 fail SecurityError,"cannot change the entried command" 1369 end 1370 super(idx,val) 1371 end 1372 1373 @tk_windows = TkUtil.untrust({}) 1374 1375 @tk_table_list = TkUtil.untrust([]) 1376 1377 @init_ip_env = TkUtil.untrust([]) # table of Procs 1378 @add_tk_procs = TkUtil.untrust([]) # table of [name, args, body] 1379 1380 @force_default_encoding ||= TkUtil.untrust([false]) 1381 @encoding ||= TkUtil.untrust([nil]) 1382 def @encoding.to_s; self.join(nil); end 1383 1384 @cb_entry_class = Class.new(TkCallbackEntry){ 1385 class << self 1386 def inspect 1387 sprintf("#<Class(TkCallbackEntry):%0x>", self.__id__) 1388 end 1389 alias to_s inspect 1390 end 1391 1392 def initialize(ip, cmd) 1393 @ip = ip 1394 @cmd = cmd 1395 end 1396 attr_reader :ip, :cmd 1397 def call(*args) 1398 @ip.cb_eval(@cmd, *args) 1399 end 1400 def inspect 1401 sprintf("#<cb_entry:%0x>", self.__id__) 1402 end 1403 alias to_s inspect 1404 }.freeze 1405 } 1406 1407 def INTERP.cb_entry_class 1408 @cb_entry_class 1409 end 1410 def INTERP.tk_cmd_tbl 1411 @tk_cmd_tbl 1412 end 1413 def INTERP.tk_windows 1414 @tk_windows 1415 end 1416 1417 class Tk_OBJECT_TABLE 1418 def initialize(id) 1419 @id = id 1420 @mutex = Mutex.new 1421 end 1422 def mutex 1423 @mutex 1424 end 1425 def method_missing(m, *args, &b) 1426 TkCore::INTERP.tk_object_table(@id).__send__(m, *args, &b) 1427 end 1428 end 1429 1430 def INTERP.tk_object_table(id) 1431 @tk_table_list[id] 1432 end 1433 def INTERP.create_table 1434 id = @tk_table_list.size 1435 (tbl = {}).tainted? || TkUtil.untrust(tbl) 1436 @tk_table_list << tbl 1437# obj = Object.new 1438# obj.instance_eval <<-EOD 1439# def self.method_missing(m, *args) 1440# TkCore::INTERP.tk_object_table(#{id}).send(m, *args) 1441# end 1442# EOD 1443# return obj 1444 Tk_OBJECT_TABLE.new(id) 1445 end 1446 1447 def INTERP.get_cb_entry(cmd) 1448 @cb_entry_class.new(__getip, cmd).freeze 1449 end 1450 def INTERP.cb_eval(cmd, *args) 1451 TkUtil._get_eval_string(TkUtil.eval_cmd(cmd, *args)) 1452 end 1453 1454 def INTERP.init_ip_env(script = Proc.new) 1455 @init_ip_env << script 1456 script.call(self) 1457 end 1458 def INTERP.add_tk_procs(name, args = nil, body = nil) 1459 if name.kind_of?(Array) 1460 name.each{|param| self.add_tk_procs(*param)} 1461 else 1462 name = name.to_s 1463 @add_tk_procs << [name, args, body] 1464 self._invoke('proc', name, args, body) if args && body 1465 end 1466 end 1467 def INTERP.remove_tk_procs(*names) 1468 names.each{|name| 1469 name = name.to_s 1470 @add_tk_procs.delete_if{|elem| 1471 elem.kind_of?(Array) && elem[0].to_s == name 1472 } 1473 #self._invoke('rename', name, '') 1474 self.__invoke__('rename', name, '') 1475 } 1476 end 1477 def INTERP.init_ip_internal 1478 ip = self 1479 @init_ip_env.each{|script| script.call(ip)} 1480 @add_tk_procs.each{|name,args,body| ip._invoke('proc',name,args,body)} 1481 end 1482 end 1483 1484 unless self.const_defined? :RUN_EVENTLOOP_ON_MAIN_THREAD 1485 ### Ruby 1.9 !!!!!!!!!!!!!!!!!!!!!!!!!! 1486 RUN_EVENTLOOP_ON_MAIN_THREAD = false 1487 end 1488 1489 WIDGET_DESTROY_HOOK = '<WIDGET_DESTROY_HOOK>' 1490 INTERP._invoke_without_enc('event', 'add', 1491 "<#{WIDGET_DESTROY_HOOK}>", '<Destroy>') 1492 INTERP._invoke_without_enc('bind', 'all', "<#{WIDGET_DESTROY_HOOK}>", 1493 install_cmd(proc{|path| 1494 unless TkCore::INTERP.deleted? 1495 begin 1496 if (widget=TkCore::INTERP.tk_windows[path]) 1497 if widget.respond_to?(:__destroy_hook__) 1498 widget.__destroy_hook__ 1499 end 1500 end 1501 rescue Exception=>e 1502 p e if $DEBUG 1503 end 1504 end 1505 }) << ' %W') 1506 1507 INTERP.add_tk_procs(TclTkLib::FINALIZE_PROC_NAME, '', 1508 "catch { bind all <#{WIDGET_DESTROY_HOOK}> {} }") 1509 1510 INTERP.add_tk_procs('rb_out', 'ns args', <<-'EOL') 1511 if [regexp {^::} $ns] { 1512 set cmd {namespace eval $ns {ruby_cmd TkCore callback} $args} 1513 } else { 1514 set cmd {eval {ruby_cmd TkCore callback} $ns $args} 1515 } 1516 if {[set st [catch $cmd ret]] != 0} { 1517 #return -code $st $ret 1518 set idx [string first "\n\n" $ret] 1519 if {$idx > 0} { 1520 return -code $st \ 1521 -errorinfo [string range $ret [expr $idx + 2] \ 1522 [string length $ret]] \ 1523 [string range $ret 0 [expr $idx - 1]] 1524 } else { 1525 return -code $st $ret 1526 } 1527 } else { 1528 return $ret 1529 } 1530 EOL 1531=begin 1532 INTERP.add_tk_procs('rb_out', 'args', <<-'EOL') 1533 if {[set st [catch {eval {ruby_cmd TkCore callback} $args} ret]] != 0} { 1534 #return -code $st $ret 1535 set idx [string first "\n\n" $ret] 1536 if {$idx > 0} { 1537 return -code $st \ 1538 -errorinfo [string range $ret [expr $idx + 2] \ 1539 [string length $ret]] \ 1540 [string range $ret 0 [expr $idx - 1]] 1541 } else { 1542 return -code $st $ret 1543 } 1544 } else { 1545 return $ret 1546 } 1547 EOL 1548=end 1549=begin 1550 INTERP.add_tk_procs('rb_out', 'args', <<-'EOL') 1551 #regsub -all {\\} $args {\\\\} args 1552 #regsub -all {!} $args {\\!} args 1553 #regsub -all "{" $args "\\{" args 1554 regsub -all {(\\|!|\{|\})} $args {\\\1} args 1555 if {[set st [catch {ruby [format "TkCore.callback %%Q!%s!" $args]} ret]] != 0} { 1556 #return -code $st $ret 1557 set idx [string first "\n\n" $ret] 1558 if {$idx > 0} { 1559 return -code $st \ 1560 -errorinfo [string range $ret [expr $idx + 2] \ 1561 [string length $ret]] \ 1562 [string range $ret 0 [expr $idx - 1]] 1563 } else { 1564 return -code $st $ret 1565 } 1566 } else { 1567 return $ret 1568 } 1569 EOL 1570=end 1571 1572 at_exit{ INTERP.remove_tk_procs(TclTkLib::FINALIZE_PROC_NAME) } 1573 1574 EventFlag = TclTkLib::EventFlag 1575 1576 def callback_break 1577 fail TkCallbackBreak, "Tk callback returns 'break' status" 1578 end 1579 1580 def callback_continue 1581 fail TkCallbackContinue, "Tk callback returns 'continue' status" 1582 end 1583 1584 def callback_return 1585 fail TkCallbackReturn, "Tk callback returns 'return' status" 1586 end 1587 1588 def TkCore.callback(*arg) 1589 begin 1590 if TkCore::INTERP.tk_cmd_tbl.kind_of?(Hash) 1591 #TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) 1592 normal_ret = false 1593 ret = catch(:IRB_EXIT) do # IRB hack 1594 retval = TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) 1595 normal_ret = true 1596 retval 1597 end 1598 unless normal_ret 1599 # catch IRB_EXIT 1600 exit(ret) 1601 end 1602 ret 1603 end 1604 rescue SystemExit=>e 1605 exit(e.status) 1606 rescue Interrupt=>e 1607 fail(e) 1608 rescue Exception => e 1609 begin 1610 msg = _toUTF8(e.class.inspect) + ': ' + 1611 _toUTF8(e.message) + "\n" + 1612 "\n---< backtrace of Ruby side >-----\n" + 1613 _toUTF8(e.backtrace.join("\n")) + 1614 "\n---< backtrace of Tk side >-------" 1615 if TkCore::WITH_ENCODING 1616 msg.force_encoding('utf-8') 1617 else 1618 msg.instance_variable_set(:@encoding, 'utf-8') 1619 end 1620 rescue Exception 1621 msg = e.class.inspect + ': ' + e.message + "\n" + 1622 "\n---< backtrace of Ruby side >-----\n" + 1623 e.backtrace.join("\n") + 1624 "\n---< backtrace of Tk side >-------" 1625 end 1626 # TkCore::INTERP._set_global_var('errorInfo', msg) 1627 # fail(e) 1628 fail(e, msg) 1629 end 1630 end 1631=begin 1632 def TkCore.callback(arg_str) 1633 # arg = tk_split_list(arg_str) 1634 arg = tk_split_simplelist(arg_str) 1635 #_get_eval_string(TkUtil.eval_cmd(Tk_CMDTBL[arg.shift], *arg)) 1636 #_get_eval_string(TkUtil.eval_cmd(TkCore::INTERP.tk_cmd_tbl[arg.shift], 1637 # *arg)) 1638 # TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) 1639 begin 1640 TkCore::INTERP.tk_cmd_tbl[arg.shift].call(*arg) 1641 rescue Exception => e 1642 raise(e, e.class.inspect + ': ' + e.message + "\n" + 1643 "\n---< backtrace of Ruby side >-----\n" + 1644 e.backtrace.join("\n") + 1645 "\n---< backtrace of Tk side >-------") 1646 end 1647#=begin 1648# cb_obj = TkCore::INTERP.tk_cmd_tbl[arg.shift] 1649# unless $DEBUG 1650# cb_obj.call(*arg) 1651# else 1652# begin 1653# raise 'check backtrace' 1654# rescue 1655# # ignore backtrace before 'callback' 1656# pos = -($!.backtrace.size) 1657# end 1658# begin 1659# cb_obj.call(*arg) 1660# rescue 1661# trace = $!.backtrace 1662# raise $!, "\n#{trace[0]}: #{$!.message} (#{$!.class})\n" + 1663# "\tfrom #{trace[1..pos].join("\n\tfrom ")}" 1664# end 1665# end 1666#=end 1667 end 1668=end 1669 1670 def load_cmd_on_ip(tk_cmd) 1671 bool(tk_call('auto_load', tk_cmd)) 1672 end 1673 1674 def after(ms, cmd=Proc.new) 1675 cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret}) 1676 after_id = tk_call_without_enc("after",ms,cmdid) 1677 after_id.instance_variable_set('@cmdid', cmdid) 1678 after_id 1679 end 1680=begin 1681 def after(ms, cmd=Proc.new) 1682 crit_bup = Thread.critical 1683 Thread.critical = true 1684 1685 myid = _curr_cmd_id 1686 cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(myid); ret}) 1687 1688 Thread.critical = crit_bup 1689 1690 tk_call_without_enc("after",ms,cmdid) # return id 1691# return 1692# if false #defined? Thread 1693# Thread.start do 1694# ms = Float(ms)/1000 1695# ms = 10 if ms == 0 1696# sleep ms/1000 1697# cmd.call 1698# end 1699# else 1700# cmdid = install_cmd(cmd) 1701# tk_call("after",ms,cmdid) 1702# end 1703 end 1704=end 1705 1706 def after_idle(cmd=Proc.new) 1707 cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret}) 1708 after_id = tk_call_without_enc('after','idle',cmdid) 1709 after_id.instance_variable_set('@cmdid', cmdid) 1710 after_id 1711 end 1712=begin 1713 def after_idle(cmd=Proc.new) 1714 crit_bup = Thread.critical 1715 Thread.critical = true 1716 1717 myid = _curr_cmd_id 1718 cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(myid); ret}) 1719 1720 Thread.critical = crit_bup 1721 1722 tk_call_without_enc('after','idle',cmdid) 1723 end 1724=end 1725 1726 def after_cancel(afterId) 1727 tk_call_without_enc('after','cancel',afterId) 1728 if (cmdid = afterId.instance_variable_get('@cmdid')) 1729 afterId.instance_variable_set('@cmdid', nil) 1730 uninstall_cmd(cmdid) 1731 end 1732 afterId 1733 end 1734 1735 def windowingsystem 1736 tk_call_without_enc('tk', 'windowingsystem') 1737 end 1738 1739 def scaling(scale=nil) 1740 if scale 1741 tk_call_without_enc('tk', 'scaling', scale) 1742 else 1743 Float(number(tk_call_without_enc('tk', 'scaling'))) 1744 end 1745 end 1746 def scaling_displayof(win, scale=nil) 1747 if scale 1748 tk_call_without_enc('tk', 'scaling', '-displayof', win, scale) 1749 else 1750 Float(number(tk_call_without_enc('tk', '-displayof', win, 'scaling'))) 1751 end 1752 end 1753 1754 def inactive 1755 Integer(tk_call_without_enc('tk', 'inactive')) 1756 end 1757 def inactive_displayof(win) 1758 Integer(tk_call_without_enc('tk', 'inactive', '-displayof', win)) 1759 end 1760 def reset_inactive 1761 tk_call_without_enc('tk', 'inactive', 'reset') 1762 end 1763 def reset_inactive_displayof(win) 1764 tk_call_without_enc('tk', 'inactive', '-displayof', win, 'reset') 1765 end 1766 1767 def appname(name=None) 1768 tk_call('tk', 'appname', name) 1769 end 1770 1771 def appsend_deny 1772 tk_call('rename', 'send', '') 1773 end 1774 1775 def appsend(interp, async, *args) 1776 if $SAFE >= 4 1777 fail SecurityError, "cannot send Tk commands at level 4" 1778 elsif $SAFE >= 1 && args.find{|obj| obj.tainted?} 1779 fail SecurityError, "cannot send tainted Tk commands at level #{$SAFE}" 1780 end 1781 if async != true && async != false && async != nil 1782 args.unshift(async) 1783 async = false 1784 end 1785 if async 1786 tk_call('send', '-async', '--', interp, *args) 1787 else 1788 tk_call('send', '--', interp, *args) 1789 end 1790 end 1791 1792 def rb_appsend(interp, async, *args) 1793 if $SAFE >= 4 1794 fail SecurityError, "cannot send Ruby commands at level 4" 1795 elsif $SAFE >= 1 && args.find{|obj| obj.tainted?} 1796 fail SecurityError, "cannot send tainted Ruby commands at level #{$SAFE}" 1797 end 1798 if async != true && async != false && async != nil 1799 args.unshift(async) 1800 async = false 1801 end 1802 #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')} 1803 args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')} 1804 # args.push(').to_s"') 1805 # appsend(interp, async, 'ruby "(', *args) 1806 args.push('}.call)"') 1807 appsend(interp, async, 'ruby "TkComm._get_eval_string(proc{', *args) 1808 end 1809 1810 def appsend_displayof(interp, win, async, *args) 1811 if $SAFE >= 4 1812 fail SecurityError, "cannot send Tk commands at level 4" 1813 elsif $SAFE >= 1 && args.find{|obj| obj.tainted?} 1814 fail SecurityError, "cannot send tainted Tk commands at level #{$SAFE}" 1815 end 1816 win = '.' if win == nil 1817 if async != true && async != false && async != nil 1818 args.unshift(async) 1819 async = false 1820 end 1821 if async 1822 tk_call('send', '-async', '-displayof', win, '--', interp, *args) 1823 else 1824 tk_call('send', '-displayor', win, '--', interp, *args) 1825 end 1826 end 1827 1828 def rb_appsend_displayof(interp, win, async, *args) 1829 if $SAFE >= 4 1830 fail SecurityError, "cannot send Ruby commands at level 4" 1831 elsif $SAFE >= 1 && args.find{|obj| obj.tainted?} 1832 fail SecurityError, "cannot send tainted Ruby commands at level #{$SAFE}" 1833 end 1834 win = '.' if win == nil 1835 if async != true && async != false && async != nil 1836 args.unshift(async) 1837 async = false 1838 end 1839 #args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"]/, '\\\\\&')} 1840 args = args.collect!{|c| _get_eval_string(c).gsub(/[\[\]$"\\]/, '\\\\\&')} 1841 # args.push(').to_s"') 1842 # appsend_displayof(interp, win, async, 'ruby "(', *args) 1843 args.push('}.call)"') 1844 appsend(interp, win, async, 'ruby "TkComm._get_eval_string(proc{', *args) 1845 end 1846 1847 def info(*args) 1848 tk_call('info', *args) 1849 end 1850 1851 def mainloop(check_root = true) 1852 if !TkCore::WITH_RUBY_VM 1853 TclTkLib.mainloop(check_root) 1854 1855 elsif TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD 1856 # if TclTkLib::WINDOWING_SYSTEM == 'aqua' && 1857 #if TkCore::INTERP._invoke_without_enc('tk','windowingsystem')=='aqua' && 1858 # Thread.current != Thread.main && 1859 # (TclTkLib.get_version <=> [8,4,TclTkLib::RELEASE_TYPE::FINAL,9]) > 0 1860 # raise RuntimeError, 1861 # "eventloop on TkAqua ( > Tk8.4.9 ) works on the main thread only" 1862 #end 1863 if Thread.current != Thread.main 1864 raise RuntimeError, "Tk.mainloop is allowed on the main thread only" 1865 end 1866 TclTkLib.mainloop(check_root) 1867 1868 else ### Ruby 1.9 !!!!! 1869 unless TkCore::INTERP.default_master? 1870 # [MultiTkIp] slave interp ? 1871 return TkCore::INTERP._thread_tkwait('window', '.') if check_root 1872 end 1873 1874 # like as 1.8, withdraw a root widget before calling Tk.mainloop 1875 TkCore::INTERP._eval_without_enc('catch {unset __initial_state_of_rubytk__}') 1876 INTERP_THREAD.run 1877 1878 begin 1879 TclTkLib.set_eventloop_window_mode(true) 1880 1881 # force run the eventloop 1882 TkCore::INTERP._eval_without_enc('update') 1883 TkCore::INTERP._eval_without_enc('catch {set __initial_state_of_rubytk__}') 1884 INTERP_THREAD.run 1885 if check_root 1886 INTERP_MUTEX.synchronize{ 1887 INTERP_ROOT_CHECK.wait(INTERP_MUTEX) 1888 status = INTERP_THREAD_STATUS.value 1889 if status && TkCore::INTERP.default_master? 1890 INTERP_THREAD_STATUS.value = nil if $SAFE < 4 1891 raise status if status.kind_of?(Exception) 1892 end 1893 } 1894 else 1895 # INTERP_THREAD.value 1896 begin 1897 INTERP_THREAD.value 1898 rescue Exception => e 1899 raise e 1900 end 1901 end 1902 rescue Exception => e 1903 raise e 1904 ensure 1905 TclTkLib.set_eventloop_window_mode(false) 1906 end 1907 end 1908 end 1909 1910 def mainloop_thread? 1911 # true : current thread is mainloop 1912 # nil : there is no mainloop 1913 # false : mainloop is running on the other thread 1914 # ( At then, it is dangerous to call Tk interpreter directly. ) 1915 if !TkCore::WITH_RUBY_VM || TkCore::RUN_EVENTLOOP_ON_MAIN_THREAD 1916 ### Ruby 1.9 !!!!!!!!!!! 1917 TclTkLib.mainloop_thread? 1918 else 1919 Thread.current == INTERP_THREAD 1920 end 1921 end 1922 1923 def mainloop_exist? 1924 TclTkLib.mainloop_thread? != nil 1925 end 1926 1927 def is_mainloop? 1928 TclTkLib.mainloop_thread? == true 1929 end 1930 1931 def mainloop_watchdog(check_root = true) 1932 # watchdog restarts mainloop when mainloop is dead 1933 TclTkLib.mainloop_watchdog(check_root) 1934 end 1935 1936 def do_one_event(flag = TclTkLib::EventFlag::ALL) 1937 TclTkLib.do_one_event(flag) 1938 end 1939 1940 def set_eventloop_tick(timer_tick) 1941 TclTkLib.set_eventloop_tick(timer_tick) 1942 end 1943 1944 def get_eventloop_tick() 1945 TclTkLib.get_eventloop_tick 1946 end 1947 1948 def set_no_event_wait(wait) 1949 TclTkLib.set_no_even_wait(wait) 1950 end 1951 1952 def get_no_event_wait() 1953 TclTkLib.get_no_eventloop_wait 1954 end 1955 1956 def set_eventloop_weight(loop_max, no_event_tick) 1957 TclTkLib.set_eventloop_weight(loop_max, no_event_tick) 1958 end 1959 1960 def get_eventloop_weight() 1961 TclTkLib.get_eventloop_weight 1962 end 1963 1964 def restart(app_name = nil, keys = {}) 1965 TkCore::INTERP.init_ip_internal 1966 1967 tk_call('set', 'argv0', app_name) if app_name 1968 if keys.kind_of?(Hash) 1969 # tk_call('set', 'argc', keys.size * 2) 1970 tk_call('set', 'argv', hash_kv(keys).join(' ')) 1971 end 1972 1973 INTERP.restart 1974 nil 1975 end 1976 1977 def event_generate(win, context, keys=nil) 1978 #win = win.path if win.kind_of?(TkObject) 1979 if context.kind_of?(TkEvent::Event) 1980 context.generate(win, ((keys)? keys: {})) 1981 elsif keys 1982 tk_call_without_enc('event', 'generate', win, 1983 "<#{tk_event_sequence(context)}>", 1984 *hash_kv(keys, true)) 1985 else 1986 tk_call_without_enc('event', 'generate', win, 1987 "<#{tk_event_sequence(context)}>") 1988 end 1989 nil 1990 end 1991 1992 def messageBox(keys) 1993 tk_call('tk_messageBox', *hash_kv(keys)) 1994 end 1995 1996 def getOpenFile(keys = nil) 1997 tk_call('tk_getOpenFile', *hash_kv(keys)) 1998 end 1999 def getMultipleOpenFile(keys = nil) 2000 simplelist(tk_call('tk_getOpenFile', '-multiple', '1', *hash_kv(keys))) 2001 end 2002 2003 def getSaveFile(keys = nil) 2004 tk_call('tk_getSaveFile', *hash_kv(keys)) 2005 end 2006 def getMultipleSaveFile(keys = nil) 2007 simplelist(tk_call('tk_getSaveFile', '-multiple', '1', *hash_kv(keys))) 2008 end 2009 2010 def chooseColor(keys = nil) 2011 tk_call('tk_chooseColor', *hash_kv(keys)) 2012 end 2013 2014 def chooseDirectory(keys = nil) 2015 tk_call('tk_chooseDirectory', *hash_kv(keys)) 2016 end 2017 2018 def _ip_eval_core(enc_mode, cmd_string) 2019 case enc_mode 2020 when nil 2021 res = INTERP._eval(cmd_string) 2022 when false 2023 res = INTERP._eval_without_enc(cmd_string) 2024 when true 2025 res = INTERP._eval_with_enc(cmd_string) 2026 end 2027 if INTERP._return_value() != 0 2028 fail RuntimeError, res, error_at 2029 end 2030 return res 2031 end 2032 private :_ip_eval_core 2033 2034 def ip_eval(cmd_string) 2035 _ip_eval_core(nil, cmd_string) 2036 end 2037 2038 def ip_eval_without_enc(cmd_string) 2039 _ip_eval_core(false, cmd_string) 2040 end 2041 2042 def ip_eval_with_enc(cmd_string) 2043 _ip_eval_core(true, cmd_string) 2044 end 2045 2046 def _ip_invoke_core(enc_mode, *args) 2047 case enc_mode 2048 when false 2049 res = INTERP._invoke_without_enc(*args) 2050 when nil 2051 res = INTERP._invoke(*args) 2052 when true 2053 res = INTERP._invoke_with_enc(*args) 2054 end 2055 if INTERP._return_value() != 0 2056 fail RuntimeError, res, error_at 2057 end 2058 return res 2059 end 2060 private :_ip_invoke_core 2061 2062 def ip_invoke(*args) 2063 _ip_invoke_core(nil, *args) 2064 end 2065 2066 def ip_invoke_without_enc(*args) 2067 _ip_invoke_core(false, *args) 2068 end 2069 2070 def ip_invoke_with_enc(*args) 2071 _ip_invoke_core(true, *args) 2072 end 2073 2074 def _tk_call_core(enc_mode, *args) 2075 ### puts args.inspect if $DEBUG 2076 #args.collect! {|x|ruby2tcl(x, enc_mode)} 2077 #args.compact! 2078 #args.flatten! 2079 args = _conv_args([], enc_mode, *args) 2080 puts 'invoke args => ' + args.inspect if $DEBUG 2081 ### print "=> ", args.join(" ").inspect, "\n" if $DEBUG 2082 begin 2083 # res = TkUtil.untrust(INTERP._invoke(*args)) 2084 # res = INTERP._invoke(enc_mode, *args) 2085 res = _ip_invoke_core(enc_mode, *args) 2086 # >>>>> _invoke returns a TAINTED string <<<<< 2087 rescue NameError => err 2088 # err = $! 2089 begin 2090 args.unshift "unknown" 2091 #res = TkUtil.untrust(INTERP._invoke(*args)) 2092 #res = INTERP._invoke(enc_mode, *args) 2093 res = _ip_invoke_core(enc_mode, *args) 2094 # >>>>> _invoke returns a TAINTED string <<<<< 2095 rescue StandardError => err2 2096 fail err2 unless /^invalid command/ =~ err2.message 2097 fail err 2098 end 2099 end 2100 if INTERP._return_value() != 0 2101 fail RuntimeError, res, error_at 2102 end 2103 ### print "==> ", res.inspect, "\n" if $DEBUG 2104 return res 2105 end 2106 private :_tk_call_core 2107 2108 def tk_call(*args) 2109 _tk_call_core(nil, *args) 2110 end 2111 2112 def tk_call_without_enc(*args) 2113 _tk_call_core(false, *args) 2114 end 2115 2116 def tk_call_with_enc(*args) 2117 _tk_call_core(true, *args) 2118 end 2119 2120 def _tk_call_to_list_core(depth, arg_enc, val_enc, *args) 2121 args = _conv_args([], arg_enc, *args) 2122 val = _tk_call_core(false, *args) 2123 if !depth.kind_of?(Integer) || depth == 0 2124 tk_split_simplelist(val, false, val_enc) 2125 else 2126 tk_split_list(val, depth, false, val_enc) 2127 end 2128 end 2129 #private :_tk_call_to_list_core 2130 2131 def tk_call_to_list(*args) 2132 _tk_call_to_list_core(-1, nil, true, *args) 2133 end 2134 2135 def tk_call_to_list_without_enc(*args) 2136 _tk_call_to_list_core(-1, false, false, *args) 2137 end 2138 2139 def tk_call_to_list_with_enc(*args) 2140 _tk_call_to_list_core(-1, true, true, *args) 2141 end 2142 2143 def tk_call_to_simplelist(*args) 2144 _tk_call_to_list_core(0, nil, true, *args) 2145 end 2146 2147 def tk_call_to_simplelist_without_enc(*args) 2148 _tk_call_to_list_core(0, false, false, *args) 2149 end 2150 2151 def tk_call_to_simplelist_with_enc(*args) 2152 _tk_call_to_list_core(0, true, true, *args) 2153 end 2154end 2155 2156 2157module Tk 2158 include TkCore 2159 extend Tk 2160 2161 TCL_VERSION = INTERP._invoke_without_enc("info", "tclversion").freeze 2162 TCL_PATCHLEVEL = INTERP._invoke_without_enc("info", "patchlevel").freeze 2163 2164 major, minor = TCL_VERSION.split('.') 2165 TCL_MAJOR_VERSION = major.to_i 2166 TCL_MINOR_VERSION = minor.to_i 2167 2168 TK_VERSION = INTERP._invoke_without_enc("set", "tk_version").freeze 2169 TK_PATCHLEVEL = INTERP._invoke_without_enc("set", "tk_patchLevel").freeze 2170 2171 major, minor = TK_VERSION.split('.') 2172 TK_MAJOR_VERSION = major.to_i 2173 TK_MINOR_VERSION = minor.to_i 2174 2175 JAPANIZED_TK = (INTERP._invoke_without_enc("info", "commands", 2176 "kanji") != "").freeze 2177 2178 def Tk.const_missing(sym) 2179 case(sym) 2180 when :TCL_LIBRARY 2181 INTERP._invoke_without_enc('global', 'tcl_library') 2182 INTERP._invoke("set", "tcl_library").freeze 2183 2184 when :TK_LIBRARY 2185 INTERP._invoke_without_enc('global', 'tk_library') 2186 INTERP._invoke("set", "tk_library").freeze 2187 2188 when :LIBRARY 2189 INTERP._invoke("info", "library").freeze 2190 2191 #when :PKG_PATH, :PACKAGE_PATH, :TCL_PACKAGE_PATH 2192 # INTERP._invoke_without_enc('global', 'tcl_pkgPath') 2193 # tk_split_simplelist(INTERP._invoke('set', 'tcl_pkgPath')) 2194 2195 #when :LIB_PATH, :LIBRARY_PATH, :TCL_LIBRARY_PATH 2196 # INTERP._invoke_without_enc('global', 'tcl_libPath') 2197 # tk_split_simplelist(INTERP._invoke('set', 'tcl_libPath')) 2198 2199 when :PLATFORM, :TCL_PLATFORM 2200 if $SAFE >= 4 2201 fail SecurityError, "can't get #{sym} when $SAFE >= 4" 2202 end 2203 INTERP._invoke_without_enc('global', 'tcl_platform') 2204 Hash[*tk_split_simplelist(INTERP._invoke_without_enc('array', 'get', 2205 'tcl_platform'))] 2206 2207 when :ENV 2208 INTERP._invoke_without_enc('global', 'env') 2209 Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 'env'))] 2210 2211 #when :AUTO_PATH #<=== 2212 # tk_split_simplelist(INTERP._invoke('set', 'auto_path')) 2213 2214 #when :AUTO_OLDPATH 2215 # tk_split_simplelist(INTERP._invoke('set', 'auto_oldpath')) 2216 2217 when :AUTO_INDEX 2218 INTERP._invoke_without_enc('global', 'auto_index') 2219 Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 'auto_index'))] 2220 2221 when :PRIV, :PRIVATE, :TK_PRIV 2222 priv = {} 2223 if INTERP._invoke_without_enc('info', 'vars', 'tk::Priv') != "" 2224 var_nam = 'tk::Priv' 2225 else 2226 var_nam = 'tkPriv' 2227 end 2228 INTERP._invoke_without_enc('global', var_nam) 2229 Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', 2230 var_nam))].each{|k,v| 2231 k.freeze 2232 case v 2233 when /^-?\d+$/ 2234 priv[k] = v.to_i 2235 when /^-?\d+\.?\d*(e[-+]?\d+)?$/ 2236 priv[k] = v.to_f 2237 else 2238 priv[k] = v.freeze 2239 end 2240 } 2241 priv 2242 2243 else 2244 raise NameError, 'uninitialized constant Tk::' + sym.id2name 2245 end 2246 end 2247 2248 def Tk.errorInfo 2249 INTERP._invoke_without_enc('global', 'errorInfo') 2250 INTERP._invoke_without_enc('set', 'errorInfo') 2251 end 2252 2253 def Tk.errorCode 2254 INTERP._invoke_without_enc('global', 'errorCode') 2255 code = tk_split_simplelist(INTERP._invoke_without_enc('set', 'errorCode')) 2256 case code[0] 2257 when 'CHILDKILLED', 'CHILDSTATUS', 'CHILDSUSP' 2258 begin 2259 pid = Integer(code[1]) 2260 code[1] = pid 2261 rescue 2262 end 2263 end 2264 code 2265 end 2266 2267 def Tk.has_mainwindow? 2268 INTERP.has_mainwindow? 2269 end 2270 2271 def root 2272 Tk::Root.new 2273 end 2274 2275 def Tk.load_tclscript(file, enc=nil) 2276 if enc 2277 # TCL_VERSION >= 8.5 2278 tk_call('source', '-encoding', enc, file) 2279 else 2280 tk_call('source', file) 2281 end 2282 end 2283 2284 def Tk.load_tcllibrary(file, pkg_name=None, interp=None) 2285 tk_call('load', file, pkg_name, interp) 2286 end 2287 2288 def Tk.unload_tcllibrary(*args) 2289 if args[-1].kind_of?(Hash) 2290 keys = _symbolkey2str(args.pop) 2291 nocomp = (keys['nocomplain'])? '-nocomplain': None 2292 keeplib = (keys['keeplibrary'])? '-keeplibrary': None 2293 tk_call('unload', nocomp, keeplib, '--', *args) 2294 else 2295 tk_call('unload', *args) 2296 end 2297 end 2298 2299 def Tk.pkgconfig_list(mod) 2300 # Tk8.5 feature 2301 if mod.kind_of?(Module) 2302 if mod.respond_to?(:package_name) 2303 pkgname = mod.package_name 2304 elsif mod.const_defined?(:PACKAGE_NAME) 2305 pkgname = mod::PACKAGE_NAME 2306 else 2307 fail NotImplementedError, 'may not be a module for a Tcl extension' 2308 end 2309 else 2310 pkgname = mod.to_s 2311 end 2312 2313 pkgname = '::' << pkgname unless pkgname =~ /^::/ 2314 2315 tk_split_list(tk_call(pkgname + '::pkgconfig', 'list')) 2316 end 2317 2318 def Tk.pkgconfig_get(mod, key) 2319 # Tk8.5 feature 2320 if mod.kind_of?(Module) 2321 if mod.respond_to?(:package_name) 2322 pkgname = mod.package_name 2323 else 2324 fail NotImplementedError, 'may not be a module for a Tcl extension' 2325 end 2326 else 2327 pkgname = mod.to_s 2328 end 2329 2330 pkgname = '::' << pkgname unless pkgname =~ /^::/ 2331 2332 tk_call(pkgname + '::pkgconfig', 'get', key) 2333 end 2334 2335 def Tk.tcl_pkgconfig_list 2336 # Tk8.5 feature 2337 Tk.pkgconfig_list('::tcl') 2338 end 2339 2340 def Tk.tcl_pkgconfig_get(key) 2341 # Tk8.5 feature 2342 Tk.pkgconfig_get('::tcl', key) 2343 end 2344 2345 def Tk.tk_pkgconfig_list 2346 # Tk8.5 feature 2347 Tk.pkgconfig_list('::tk') 2348 end 2349 2350 def Tk.tk_pkgconfig_get(key) 2351 # Tk8.5 feature 2352 Tk.pkgconfig_get('::tk', key) 2353 end 2354 2355 def Tk.bell(nice = false) 2356 if nice 2357 tk_call_without_enc('bell', '-nice') 2358 else 2359 tk_call_without_enc('bell') 2360 end 2361 nil 2362 end 2363 2364 def Tk.bell_on_display(win, nice = false) 2365 if nice 2366 tk_call_without_enc('bell', '-displayof', win, '-nice') 2367 else 2368 tk_call_without_enc('bell', '-displayof', win) 2369 end 2370 nil 2371 end 2372 2373 def Tk.destroy(*wins) 2374 #tk_call_without_enc('destroy', *wins) 2375 tk_call_without_enc('destroy', *(wins.collect{|win| 2376 if win.kind_of?(TkWindow) 2377 win.epath 2378 else 2379 win 2380 end 2381 })) 2382 end 2383 2384 def Tk.exit 2385 TkCore::INTERP.has_mainwindow? && tk_call_without_enc('destroy', '.') 2386 end 2387 2388 ################################################ 2389 2390 def Tk.sleep(ms = nil, id = nil) 2391 if id 2392 var = (id.kind_of?(TkVariable))? id: TkVarAccess.new(id.to_s) 2393 else 2394 var = TkVariable.new 2395 end 2396 2397 var.value = tk_call_without_enc('after', ms, proc{ var.value = 0 }) if ms 2398 var.thread_wait 2399 ms 2400 end 2401 2402 def Tk.wakeup(id) 2403 ((id.kind_of?(TkVariable))? id: TkVarAccess.new(id.to_s)).value = 0 2404 nil 2405 end 2406 2407 ################################################ 2408 2409 def Tk.pack(*args) 2410 TkPack.configure(*args) 2411 end 2412 def Tk.pack_forget(*args) 2413 TkPack.forget(*args) 2414 end 2415 def Tk.unpack(*args) 2416 TkPack.forget(*args) 2417 end 2418 2419 def Tk.grid(*args) 2420 TkGrid.configure(*args) 2421 end 2422 def Tk.grid_forget(*args) 2423 TkGrid.forget(*args) 2424 end 2425 def Tk.ungrid(*args) 2426 TkGrid.forget(*args) 2427 end 2428 2429 def Tk.place(*args) 2430 TkPlace.configure(*args) 2431 end 2432 def Tk.place_forget(*args) 2433 TkPlace.forget(*args) 2434 end 2435 def Tk.unplace(*args) 2436 TkPlace.forget(*args) 2437 end 2438 2439 def Tk.update(idle=nil) 2440 if idle 2441 tk_call_without_enc('update', 'idletasks') 2442 else 2443 tk_call_without_enc('update') 2444 end 2445 end 2446 def Tk.update_idletasks 2447 update(true) 2448 end 2449 def update(idle=nil) 2450 # only for backward compatibility (This never be recommended to use) 2451 Tk.update(idle) 2452 self 2453 end 2454 2455 # NOTE:: 2456 # If no eventloop-thread is running, "thread_update" method is same 2457 # to "update" method. Else, "thread_update" method waits to complete 2458 # idletask operation on the eventloop-thread. 2459 def Tk.thread_update(idle=nil) 2460 if idle 2461 tk_call_without_enc('thread_update', 'idletasks') 2462 else 2463 tk_call_without_enc('thread_update') 2464 end 2465 end 2466 def Tk.thread_update_idletasks 2467 thread_update(true) 2468 end 2469 2470 def Tk.lower_window(win, below=None) 2471 tk_call('lower', _epath(win), _epath(below)) 2472 nil 2473 end 2474 def Tk.raise_window(win, above=None) 2475 tk_call('raise', _epath(win), _epath(above)) 2476 nil 2477 end 2478 2479 def Tk.current_grabs(win = nil) 2480 if win 2481 window(tk_call_without_enc('grab', 'current', win)) 2482 else 2483 tk_split_list(tk_call_without_enc('grab', 'current')) 2484 end 2485 end 2486 2487 def Tk.focus(display=nil) 2488 if display == nil 2489 window(tk_call_without_enc('focus')) 2490 else 2491 window(tk_call_without_enc('focus', '-displayof', display)) 2492 end 2493 end 2494 2495 def Tk.focus_to(win, force=false) 2496 if force 2497 tk_call_without_enc('focus', '-force', win) 2498 else 2499 tk_call_without_enc('focus', win) 2500 end 2501 end 2502 2503 def Tk.focus_lastfor(win) 2504 window(tk_call_without_enc('focus', '-lastfor', win)) 2505 end 2506 2507 def Tk.focus_next(win) 2508 TkManageFocus.next(win) 2509 end 2510 2511 def Tk.focus_prev(win) 2512 TkManageFocus.prev(win) 2513 end 2514 2515 def Tk.strictMotif(mode=None) 2516 bool(tk_call_without_enc('set', 'tk_strictMotif', mode)) 2517 end 2518 2519 def Tk.show_kinsoku(mode='both') 2520 begin 2521 if /^8\.*/ === TK_VERSION && JAPANIZED_TK 2522 tk_split_simplelist(tk_call('kinsoku', 'show', mode)) 2523 end 2524 rescue 2525 end 2526 end 2527 def Tk.add_kinsoku(chars, mode='both') 2528 begin 2529 if /^8\.*/ === TK_VERSION && JAPANIZED_TK 2530 tk_split_simplelist(tk_call('kinsoku', 'add', mode, 2531 *(chars.split('')))) 2532 else 2533 [] 2534 end 2535 rescue 2536 [] 2537 end 2538 end 2539 def Tk.delete_kinsoku(chars, mode='both') 2540 begin 2541 if /^8\.*/ === TK_VERSION && JAPANIZED_TK 2542 tk_split_simplelist(tk_call('kinsoku', 'delete', mode, 2543 *(chars.split('')))) 2544 end 2545 rescue 2546 end 2547 end 2548 2549 def Tk.toUTF8(str, encoding = nil) 2550 _toUTF8(str, encoding) 2551 end 2552 2553 def Tk.fromUTF8(str, encoding = nil) 2554 _fromUTF8(str, encoding) 2555 end 2556end 2557 2558########################################### 2559# string with Tcl's encoding 2560########################################### 2561module Tk 2562 def Tk.subst_utf_backslash(str) 2563 Tk::EncodedString.subst_utf_backslash(str) 2564 end 2565 def Tk.subst_tk_backslash(str) 2566 Tk::EncodedString.subst_tk_backslash(str) 2567 end 2568 def Tk.utf_to_backslash_sequence(str) 2569 Tk::EncodedString.utf_to_backslash_sequence(str) 2570 end 2571 def Tk.utf_to_backslash(str) 2572 Tk::EncodedString.utf_to_backslash_sequence(str) 2573 end 2574 def Tk.to_backslash_sequence(str) 2575 Tk::EncodedString.to_backslash_sequence(str) 2576 end 2577end 2578 2579 2580########################################### 2581# convert kanji string to/from utf-8 2582########################################### 2583if (/^(8\.[1-9]|9\.|[1-9][0-9])/ =~ Tk::TCL_VERSION && !Tk::JAPANIZED_TK) 2584 module Tk 2585 module Encoding 2586 extend Encoding 2587 2588 TkCommandNames = ['encoding'.freeze].freeze 2589 2590 ############################################# 2591 2592 if TkCore::WITH_ENCODING ### Ruby 1.9 2593 RubyEncoding = ::Encoding 2594 2595 # for saving GC cost 2596 #ENCNAMES_CMD = ['encoding'.freeze, 'names'.freeze] 2597 BINARY_NAME = 'binary'.freeze 2598 UTF8_NAME = 'utf-8'.freeze 2599 DEFAULT_EXTERNAL_NAME = RubyEncoding.default_external.name.freeze 2600 DEFAULT_INTERNAL_NAME = RubyEncoding.default_internal.name.freeze rescue nil 2601 2602 BINARY = RubyEncoding.find(BINARY_NAME) 2603 UNKNOWN = RubyEncoding.find('ASCII-8BIT') 2604 2605 ### start of creating ENCODING_TABLE 2606 ENCODING_TABLE = TkCore::INTERP.encoding_table 2607=begin 2608 ENCODING_TABLE = { 2609 'binary' => BINARY, 2610 # 'UNKNOWN-8BIT' => UNKNOWN, 2611 } 2612 2613 list = TkCore::INTERP._invoke_without_enc(ENCNAMES_CMD[0], 2614 ENCNAMES_CMD[1]) 2615 TkCore::INTERP._split_tklist(list).each{|name| 2616 begin 2617 enc = RubyEncoding.find(name) 2618 rescue ArgumentError 2619 case name 2620 when 'identity' 2621 enc = BINARY 2622 when 'shiftjis' 2623 enc = RubyEncoding.find('Shift_JIS') 2624 when 'unicode' 2625 enc = RubyEncoding.find('UTF-8') 2626 #if Tk.tk_call('set', 'tcl_platform(byteOrder)') =='littleEndian' 2627 # enc = RubyEncoding.find('UTF-16LE') 2628 #else 2629 # enc = RubyEncoding.find('UTF-16BE') 2630 #end 2631 when 'symbol' 2632 # single byte data 2633 enc = RubyEncoding.find('ASCII-8BIT') ### ??? 2634 else 2635 # unsupported on Ruby, but supported on Tk 2636 enc = TkCore::INTERP.create_dummy_encoding_for_tk(name) 2637 end 2638 end 2639 ENCODING_TABLE[name.freeze] = enc 2640 } 2641=end 2642=begin 2643 def ENCODING_TABLE.get_name(enc) 2644 orig_enc = enc 2645 2646 # unles enc, use system default 2647 # 1st: Ruby/Tk default encoding 2648 # 2nd: Tcl/Tk default encoding 2649 # 3rd: Ruby's default_external 2650 enc ||= TkCore::INTERP.encoding 2651 enc ||= TclTkLib.encoding_system 2652 enc ||= DEFAULT_EXTERNAL_NAME 2653 2654 if enc.kind_of?(RubyEncoding) 2655 # Ruby's Encoding object 2656 if (name = self.key(enc)) 2657 return name 2658 end 2659 2660 # Is it new ? 2661 list = TkCore::INTERP._invoke_without_enc(ENCNAMES_CMD[0], 2662 ENCNAMES_CMD[1]) 2663 TkComm.simplelist(list).each{|name| 2664 if ((enc == RubyEncoding.find(name)) rescue false) 2665 # new relation!! update table 2666 self[name.freeze] = enc 2667 return name 2668 end 2669 } 2670 else 2671 # String or Symbol ? 2672 if self[name = enc.to_s] 2673 return name 2674 end 2675 2676 # Is it new ? 2677 if (enc_obj = (RubyEncoding.find(name) rescue false)) 2678 list = TkCore::INTERP._invoke_without_enc(ENCNAMES_CMD[0], 2679 ENCNAMES_CMD[1]) 2680 if TkComm.simplelist(list).index(name) 2681 # Tk's encoding name ? 2682 self[name.freeze] = enc_obj # new relation!! update table 2683 return name 2684 else 2685 # Ruby's encoding name ? 2686 if (name = self.key(enc_obj)) 2687 return name 2688 end 2689 end 2690 end 2691 end 2692 2693 fail ArgumentError, "unsupported Tk encoding '#{orig_enc}'" 2694 end 2695 2696 def ENCODING_TABLE.get_obj(enc) 2697 # returns the encoding object. 2698 # If 'enc' is the encoding name on Tk only, it returns nil. 2699 ((obj = self[self.get_name(enc)]).kind_of?(RubyEncoding))? obj: nil 2700 end 2701=end 2702 ### end of creating ENCODING_TABLE 2703 2704 end 2705 2706 ############################################# 2707 2708 if TkCore::WITH_ENCODING 2709 ################################ 2710 ### Ruby 1.9 2711 ################################ 2712 def force_default_encoding(mode) 2713 TkCore::INTERP.force_default_encoding = mode 2714 end 2715 2716 def force_default_encoding? 2717 TkCore::INTERP.force_default_encoding? 2718 end 2719 2720 def default_encoding=(enc) 2721 TkCore::INTERP.default_encoding = Tk::Encoding::ENCODING_TABLE.get_name(enc) 2722 end 2723 2724 def encoding=(enc) 2725 TkCore::INTERP.encoding = Tk::Encoding::ENCODING_TABLE.get_name(enc) 2726 end 2727 2728 def encoding_name 2729 Tk::Encoding::ENCODING_TABLE.get_name(TkCore::INTERP.encoding) 2730 end 2731 def encoding_obj 2732 Tk::Encoding::ENCODING_TABLE.get_obj(TkCore::INTERP.encoding) 2733 end 2734 alias encoding encoding_name 2735 alias default_encoding encoding_name 2736 2737 def tk_encoding_names 2738 #TkComm.simplelist(TkCore::INTERP._invoke_without_enc(Tk::Encoding::ENCNAMES_CMD[0], Tk::Encoding::ENCNAMES_CMD[1])) 2739 TkComm.simplelist(TkCore::INTERP._invoke_without_enc('encoding', 'names')) 2740 end 2741 def encoding_names 2742 self.tk_encoding_names.find_all{|name| 2743 Tk::Encoding::ENCODING_TABLE.get_name(name) rescue false 2744 } 2745 end 2746 def encoding_objs 2747 self.tk_encoding_names.map!{|name| 2748 Tk::Encoding::ENCODING_TABLE.get_obj(name) rescue nil 2749 }.compact 2750 end 2751 2752 def encoding_system=(enc) 2753 TclTkLib.encoding_system = Tk::Encoding::ENCODING_TABLE.get_name(enc) 2754 end 2755 2756 def encoding_system_name 2757 Tk::Encoding::ENCODING_TABLE.get_name(TclTkLib.encoding_system) 2758 end 2759 def encoding_system_obj 2760 Tk::Encoding::ENCODING_TABLE.get_obj(TclTkLib.encoding_system) 2761 end 2762 alias encoding_system encoding_system_name 2763 2764 ################################ 2765 else 2766 ################################ 2767 ### Ruby 1.8- 2768 ################################ 2769 def force_default_encoding=(mode) 2770 true 2771 end 2772 2773 def force_default_encoding? 2774 true 2775 end 2776 2777 def default_encoding=(enc) 2778 TkCore::INTERP.default_encoding = enc 2779 end 2780 2781 def encoding=(enc) 2782 TkCore::INTERP.encoding = enc 2783 end 2784 2785 def encoding_obj 2786 TkCore::INTERP.encoding 2787 end 2788 def encoding_name 2789 TkCore::INTERP.encoding 2790 end 2791 alias encoding encoding_name 2792 alias default_encoding encoding_name 2793 2794 def tk_encoding_names 2795 TkComm.simplelist(Tk.tk_call('encoding', 'names')) 2796 end 2797 def encoding_objs 2798 self.tk_encoding_names 2799 end 2800 def encoding_names 2801 self.tk_encoding_names 2802 end 2803 2804 def encoding_system=(enc) 2805 TclTkLib.encoding_system = enc 2806 end 2807 2808 def encoding_system_name 2809 TclTkLib.encoding_system 2810 end 2811 def encoding_system_obj 2812 TclTkLib.encoding_system 2813 end 2814 alias encoding_system encoding_system_name 2815 2816 ################################ 2817 end 2818 2819 def encoding_convertfrom(str, enc=nil) 2820 enc = encoding_system_name unless enc 2821 str = str.dup 2822 if TkCore::WITH_ENCODING 2823 if str.kind_of?(Tk::EncodedString) 2824 str.__instance_variable_set('@encoding', nil) 2825 else 2826 str.instance_variable_set('@encoding', nil) 2827 end 2828 str.force_encoding('binary') 2829 else 2830 str.instance_variable_set('@encoding', 'binary') 2831 end 2832 ret = TkCore::INTERP._invoke_without_enc('encoding', 'convertfrom', 2833 enc, str) 2834 if TkCore::WITH_ENCODING 2835 ret.force_encoding('utf-8') 2836 else 2837 Tk::UTF8_String.new(ret) 2838 end 2839 ret 2840 end 2841 alias encoding_convert_from encoding_convertfrom 2842 2843 def encoding_convertto(str, enc=nil) 2844 # str must be a UTF-8 string 2845 enc = encoding_system_name unless enc 2846 ret = TkCore::INTERP._invoke_without_enc('encoding', 'convertto', 2847 enc, str) 2848 #ret.instance_variable_set('@encoding', 'binary') 2849 if TkCore::WITH_ENCODING 2850 #ret.force_encoding(Tk::Encoding::ENCODING_TABLE.get_obj('binary')) 2851 ret.force_encoding(Tk::Encoding::ENCODING_TABLE.get_obj(enc)) 2852 end 2853 ret 2854 end 2855 alias encoding_convert_to encoding_convertto 2856 2857 def encoding_dirs 2858 # Tcl8.5 feature 2859 TkComm.simplelist(Tk.tk_call_without_enc('encoding', 'dirs')) 2860 end 2861 2862 def encoding_dirs=(dir_list) # an array or a Tcl's list string 2863 # Tcl8.5 feature 2864 Tk.tk_call_without_enc('encoding', 'dirs', dir_list) 2865 end 2866 end 2867 2868 extend Encoding 2869 end 2870 2871 class TclTkIp 2872 def force_default_encoding=(mode) 2873 @force_default_encoding[0] = (mode)? true: false 2874 end 2875 2876 def force_default_encoding? 2877 @force_default_encoding[0] ||= false 2878 end 2879 2880 def default_encoding=(name) 2881 name = name.name if Tk::WITH_ENCODING && name.kind_of?(::Encoding) 2882 @encoding[0] = name.to_s.dup 2883 end 2884 2885 # from tkencoding.rb by ttate@jaist.ac.jp 2886 #attr_accessor :encoding 2887 def encoding=(name) 2888 self.force_default_encoding = true # for comaptibility 2889 self.default_encoding = name 2890 end 2891 2892 def encoding_name 2893 (@encoding[0])? @encoding[0].dup: nil 2894 end 2895 alias encoding encoding_name 2896 alias default_encoding encoding_name 2897 2898 def encoding_obj 2899 if Tk::WITH_ENCODING 2900 Tk::Encoding.tcl2rb_encoding(@encoding[0]) 2901 else 2902 (@encoding[0])? @encoding[0].dup: nil 2903 end 2904 end 2905 2906 alias __toUTF8 _toUTF8 2907 alias __fromUTF8 _fromUTF8 2908 2909 if Object.const_defined?(:Encoding) && ::Encoding.class == Class 2910 # with Encoding (Ruby 1.9+) 2911 # 2912 # use functions on Tcl as default. 2913 # but when unsupported encoding on Tcl, use methods on Ruby. 2914 # 2915 def _toUTF8(str, enc = nil) 2916 if enc 2917 # use given encoding 2918 begin 2919 enc_name = Tk::Encoding::ENCODING_TABLE.get_name(enc) 2920 rescue 2921 # unknown encoding for Tk -> try to convert encoding on Ruby 2922 str = str.dup.force_encoding(enc) 2923 str.encode!(Tk::Encoding::UTF8_NAME) # modify self !! 2924 return str # if no error, probably succeed converting 2925 end 2926 end 2927 2928 enc_name ||= str.instance_variable_get(:@encoding) 2929 2930 enc_name ||= 2931 Tk::Encoding::ENCODING_TABLE.get_name(str.encoding) rescue nil 2932 2933 if enc_name 2934 # str has its encoding information 2935 encstr = __toUTF8(str, enc_name) 2936 encstr.force_encoding(Tk::Encoding::UTF8_NAME) 2937 return encstr 2938 else 2939 # str.encoding isn't supported by Tk -> try to convert on Ruby 2940 begin 2941 return str.encode(Tk::Encoding::UTF8_NAME) # new string 2942 rescue 2943 # error -> ignore, try to use default encoding of Ruby/Tk 2944 end 2945 end 2946 2947 #enc_name ||= 2948 # Tk::Encoding::ENCODING_TABLE.get_name(Tk.encoding) rescue nil 2949 enc_name ||= Tk::Encoding::ENCODING_TABLE.get_name(nil) 2950 2951 # is 'binary' encoding? 2952 if enc_name == Tk::Encoding::BINARY_NAME 2953 return str.dup.force_encoding(Tk::Encoding::BINARY_NAME) 2954 end 2955 2956 # force default encoding? 2957 if ! str.kind_of?(Tk::EncodedString) && self.force_default_encoding? 2958 enc_name = Tk::Encoding::ENCODING_TABLE.get_name(Tk.default_encoding) 2959 end 2960 2961 encstr = __toUTF8(str, enc_name) 2962 encstr.force_encoding(Tk::Encoding::UTF8_NAME) 2963 encstr 2964 end 2965 def _fromUTF8(str, enc = nil) 2966 # str must be UTF-8 or binary. 2967 enc_name = str.instance_variable_get(:@encoding) 2968 enc_name ||= 2969 Tk::Encoding::ENCODING_TABLE.get_name(str.encoding) rescue nil 2970 2971 # is 'binary' encoding? 2972 if enc_name == Tk::Encoding::BINARY_NAME 2973 return str.dup.force_encoding(Tk::Encoding::BINARY_NAME) 2974 end 2975 2976 # get target encoding name (if enc == nil, use default encoding) 2977 begin 2978 enc_name = Tk::Encoding::ENCODING_TABLE.get_name(enc) 2979 rescue 2980 # then, enc != nil 2981 # unknown encoding for Tk -> try to convert encoding on Ruby 2982 str = str.dup.force_encoding(Tk::Encoding::UTF8_NAME) 2983 str.encode!(enc) # modify self !! 2984 return str # if no error, probably succeed converting 2985 end 2986 2987 encstr = __fromUTF8(str, enc_name) 2988 encstr.force_encoding(Tk::Encoding::ENCODING_TABLE.get_obj(enc_name)) 2989 encstr 2990 end 2991 ### 2992 else 2993 # without Encoding (Ruby 1.8) 2994 def _toUTF8(str, encoding = nil) 2995 __toUTF8(str, encoding) 2996 end 2997 def _fromUTF8(str, encoding = nil) 2998 __fromUTF8(str, encoding) 2999 end 3000 ### 3001 end 3002 3003 alias __eval _eval 3004 alias __invoke _invoke 3005 3006 def _eval(cmd) 3007 _fromUTF8(__eval(_toUTF8(cmd))) 3008 end 3009 3010 def _invoke(*cmds) 3011 _fromUTF8(__invoke(*(cmds.collect{|cmd| _toUTF8(cmd)}))) 3012 end 3013 3014 alias _eval_with_enc _eval 3015 alias _invoke_with_enc _invoke 3016 3017=begin 3018 #### --> definition is moved to TclTkIp module 3019 3020 def _toUTF8(str, encoding = nil) 3021 # decide encoding 3022 if encoding 3023 encoding = encoding.to_s 3024 elsif str.kind_of?(Tk::EncodedString) && str.encoding != nil 3025 encoding = str.encoding.to_s 3026 elsif str.instance_variable_get(:@encoding) 3027 encoding = str.instance_variable_get(:@encoding).to_s 3028 elsif defined?(@encoding) && @encoding != nil 3029 encoding = @encoding.to_s 3030 else 3031 encoding = __invoke('encoding', 'system') 3032 end 3033 3034 # convert 3035 case encoding 3036 when 'utf-8', 'binary' 3037 str 3038 else 3039 __toUTF8(str, encoding) 3040 end 3041 end 3042 3043 def _fromUTF8(str, encoding = nil) 3044 unless encoding 3045 if defined?(@encoding) && @encoding != nil 3046 encoding = @encoding.to_s 3047 else 3048 encoding = __invoke('encoding', 'system') 3049 end 3050 end 3051 3052 if str.kind_of?(Tk::EncodedString) 3053 if str.encoding == 'binary' 3054 str 3055 else 3056 __fromUTF8(str, encoding) 3057 end 3058 elsif str.instance_variable_get(:@encoding).to_s == 'binary' 3059 str 3060 else 3061 __fromUTF8(str, encoding) 3062 end 3063 end 3064=end 3065 3066=begin 3067 def _eval(cmd) 3068 if defined?(@encoding) && @encoding != 'utf-8' 3069 ret = if cmd.kind_of?(Tk::EncodedString) 3070 case cmd.encoding 3071 when 'utf-8', 'binary' 3072 __eval(cmd) 3073 else 3074 __eval(_toUTF8(cmd, cmd.encoding)) 3075 end 3076 elsif cmd.instance_variable_get(:@encoding) == 'binary' 3077 __eval(cmd) 3078 else 3079 __eval(_toUTF8(cmd, @encoding)) 3080 end 3081 if ret.kind_of?(String) && ret.instance_variable_get(:@encoding) == 'binary' 3082 ret 3083 else 3084 _fromUTF8(ret, @encoding) 3085 end 3086 else 3087 __eval(cmd) 3088 end 3089 end 3090 3091 def _invoke(*cmds) 3092 if defined?(@encoding) && @encoding != 'utf-8' 3093 cmds = cmds.collect{|cmd| 3094 if cmd.kind_of?(Tk::EncodedString) 3095 case cmd.encoding 3096 when 'utf-8', 'binary' 3097 cmd 3098 else 3099 _toUTF8(cmd, cmd.encoding) 3100 end 3101 elsif cmd.instance_variable_get(:@encoding) == 'binary' 3102 cmd 3103 else 3104 _toUTF8(cmd, @encoding) 3105 end 3106 } 3107 ret = __invoke(*cmds) 3108 if ret.kind_of?(String) && ret.instance_variable_get(:@encoding) == 'binary' 3109 ret 3110 else 3111 _fromUTF8(ret, @encoding) 3112 end 3113 else 3114 __invoke(*cmds) 3115 end 3116 end 3117=end 3118 end 3119 3120 module TclTkLib 3121 class << self 3122 def force_default_encoding=(mode) 3123 TkCore::INTERP.force_default_encoding = mode 3124 end 3125 3126 def force_default_encoding? 3127 TkCore::INTERP.force_default_encoding? 3128 end 3129 3130 def default_encoding=(name) 3131 TkCore::INTERP.default_encoding = name 3132 end 3133 3134 alias _encoding encoding 3135 alias _encoding= encoding= 3136 def encoding=(name) 3137 name = name.name if name.kind_of?(::Encoding) if Tk::WITH_ENCODING 3138 TkCore::INTERP.encoding = name 3139 end 3140 3141 def encoding_name 3142 TkCore::INTERP.encoding 3143 end 3144 alias encoding encoding_name 3145 alias default_encoding encoding_name 3146 3147 def encoding_obj 3148 if Tk::WITH_ENCODING 3149 Tk::Encoding.tcl2rb_encoding(TkCore::INTERP.encoding) 3150 else 3151 TkCore::INTERP.encoding 3152 end 3153 end 3154 end 3155 end 3156 3157 # estimate encoding 3158 unless TkCore::WITH_ENCODING 3159 case $KCODE 3160 when /^e/i # EUC 3161 Tk.encoding = 'euc-jp' 3162 Tk.encoding_system = 'euc-jp' 3163 when /^s/i # SJIS 3164 begin 3165 if Tk.encoding_system == 'cp932' 3166 Tk.encoding = 'cp932' 3167 else 3168 Tk.encoding = 'shiftjis' 3169 Tk.encoding_system = 'shiftjis' 3170 end 3171 rescue StandardError, NameError 3172 Tk.encoding = 'shiftjis' 3173 Tk.encoding_system = 'shiftjis' 3174 end 3175 when /^u/i # UTF8 3176 Tk.encoding = 'utf-8' 3177 Tk.encoding_system = 'utf-8' 3178 else # NONE 3179 if defined? DEFAULT_TK_ENCODING 3180 Tk.encoding_system = DEFAULT_TK_ENCODING 3181 end 3182 begin 3183 Tk.encoding = Tk.encoding_system 3184 rescue StandardError, NameError 3185 Tk.encoding = 'utf-8' 3186 Tk.encoding_system = 'utf-8' 3187 end 3188 end 3189 3190 else ### Ruby 1.9 !!!!!!!!!!!! 3191 # loc_enc_obj = (::Encoding.find(::Encoding.locale_charmap) rescue Tk::Encoding::UNKNOWN) 3192 loc_enc_obj = ::Encoding.find("locale") 3193 ext_enc_obj = ::Encoding.default_external 3194 int_enc_obj = ::Encoding.default_internal || ext_enc_obj 3195 tksys_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(Tk.encoding_system) 3196 # p [Tk.encoding, Tk.encoding_system, loc_enc_obj, ext_enc_obj] 3197 3198=begin 3199 if ext_enc_obj == Tk::Encoding::UNKNOWN 3200 if defined? DEFAULT_TK_ENCODING 3201 if DEFAULT_TK_ENCODING.kind_of?(::Encoding) 3202 tk_enc_name = DEFAULT_TK_ENCODING.name 3203 tksys_enc_name = DEFAULT_TK_ENCODING.name 3204 else 3205 tk_enc_name = DEFAULT_TK_ENCODING 3206 tksys_enc_name = DEFAULT_TK_ENCODING 3207 end 3208 else 3209 tk_enc_name = loc_enc_obj.name 3210 tksys_enc_name = loc_enc_obj.name 3211 end 3212 else 3213 tk_enc_name = ext_enc_obj.name 3214 tksys_enc_name = ext_enc_obj.name 3215 end 3216 3217 # Tk.encoding = tk_enc_name 3218 Tk.default_encoding = tk_enc_name 3219 Tk.encoding_system = tksys_enc_name 3220=end 3221 3222 if ext_enc_obj == Tk::Encoding::UNKNOWN 3223 if loc_enc_obj == Tk::Encoding::UNKNOWN 3224 # use Tk.encoding_system 3225 else 3226 # use locale_charmap 3227 begin 3228 loc_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(loc_enc_obj) 3229 if loc_enc_name && loc_enc_name != tksys_enc_name 3230 # use locale_charmap 3231 Tk.encoding_system = loc_enc_name 3232 else 3233 # use Tk.encoding_system 3234 end 3235 rescue ArgumentError 3236 # unsupported encoding on Tk -> use Tk.encoding_system 3237 end 3238 end 3239 else 3240 begin 3241 ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj) 3242 if ext_enc_name && ext_enc_name != tksys_enc_name 3243 # use default_external 3244 Tk.encoding_system = ext_enc_name 3245 else 3246 # use Tk.encoding_system 3247 end 3248 rescue ArgumentError 3249 # unsupported encoding on Tk -> use Tk.encoding_system 3250 end 3251 end 3252 3253 # setup Tk.encoding 3254 enc_name = nil 3255 3256 begin 3257 default_def = DEFAULT_TK_ENCODING 3258 if ::Encoding.find(default_def.to_s) != Tk::Encoding::UNKNOWN 3259 enc_name = Tk::Encoding::ENCODING_TABLE.get_name(default_def) 3260 end 3261 rescue NameError 3262 # ignore 3263 enc_name = nil 3264 rescue ArgumentError 3265 enc_name = nil 3266 fail ArgumentError, 3267 "DEFAULT_TK_ENCODING has an unknown encoding #{default_def}" 3268 end 3269 3270 unless enc_name 3271 #if ext_enc_obj == Tk::Encoding::UNKNOWN 3272 if int_enc_obj == Tk::Encoding::UNKNOWN 3273 if loc_enc_obj == Tk::Encoding::UNKNOWN 3274 # use Tk.encoding_system 3275 enc_name = tksys_enc_name 3276 else 3277 # use locale_charmap 3278 begin 3279 loc_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(loc_enc_obj) 3280 if loc_enc_name 3281 # use locale_charmap 3282 enc_name = loc_enc_name 3283 else 3284 # use Tk.encoding_system 3285 enc_name = tksys_enc_name 3286 end 3287 rescue ArgumentError 3288 # unsupported encoding on Tk -> use Tk.encoding_system 3289 enc_name = tksys_enc_name 3290 end 3291 end 3292 else 3293 begin 3294 #ext_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(ext_enc_obj) 3295 #if ext_enc_name && ext_enc_name != tksys_enc_name 3296 int_enc_name = Tk::Encoding::ENCODING_TABLE.get_name(int_enc_obj) 3297 if int_enc_name 3298 # use default_internal 3299 enc_name = int_enc_name 3300 else 3301 # use Tk.encoding_system 3302 enc_name = tksys_enc_name 3303 end 3304 rescue ArgumentError 3305 # unsupported encoding on Tk -> use Tk.encoding_system 3306 enc_name = tksys_enc_name 3307 end 3308 end 3309 end 3310 3311 Tk.default_encoding = (enc_name)? enc_name: tksys_enc_name 3312 end 3313 3314else 3315 # dummy methods 3316 module Tk 3317 module Encoding 3318 extend Encoding 3319 3320 def force_default_encoding=(mode) 3321 nil 3322 end 3323 3324 def force_default_encoding? 3325 nil 3326 end 3327 3328 def default_encoding=(enc) 3329 nil 3330 end 3331 def default_encoding 3332 nil 3333 end 3334 3335 def encoding=(name) 3336 nil 3337 end 3338 def encoding 3339 nil 3340 end 3341 def encoding_names 3342 nil 3343 end 3344 def encoding_system 3345 nil 3346 end 3347 def encoding_system=(enc) 3348 nil 3349 end 3350 3351 def encoding_convertfrom(str, enc=None) 3352 str 3353 end 3354 alias encoding_convert_from encoding_convertfrom 3355 3356 def encoding_convertto(str, enc=None) 3357 str 3358 end 3359 alias encoding_convert_to encoding_convertto 3360 def encoding_dirs 3361 nil 3362 end 3363 def encoding_dirs=(dir_array) 3364 nil 3365 end 3366 end 3367 3368 extend Encoding 3369 end 3370 3371 class TclTkIp 3372 attr_accessor :encoding 3373 3374 alias __eval _eval 3375 alias __invoke _invoke 3376 3377 alias _eval_with_enc _eval 3378 alias _invoke_with_enc _invoke 3379 end 3380end 3381 3382 3383module TkBindCore 3384 #def bind(context, cmd=Proc.new, *args) 3385 # Tk.bind(self, context, cmd, *args) 3386 #end 3387 def bind(context, *args) 3388 # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 3389 if TkComm._callback_entry?(args[0]) || !block_given? 3390 cmd = args.shift 3391 else 3392 cmd = Proc.new 3393 end 3394 Tk.bind(self, context, cmd, *args) 3395 end 3396 3397 #def bind_append(context, cmd=Proc.new, *args) 3398 # Tk.bind_append(self, context, cmd, *args) 3399 #end 3400 def bind_append(context, *args) 3401 # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 3402 if TkComm._callback_entry?(args[0]) || !block_given? 3403 cmd = args.shift 3404 else 3405 cmd = Proc.new 3406 end 3407 Tk.bind_append(self, context, cmd, *args) 3408 end 3409 3410 def bind_remove(context) 3411 Tk.bind_remove(self, context) 3412 end 3413 3414 def bindinfo(context=nil) 3415 Tk.bindinfo(self, context) 3416 end 3417end 3418 3419 3420module TkTreatFont 3421 def __font_optkeys 3422 ['font'] 3423 end 3424 private :__font_optkeys 3425 3426 def __pathname 3427 self.path 3428 end 3429 private :__pathname 3430 3431 ################################ 3432 3433 def font_configinfo(key = nil) 3434 optkeys = __font_optkeys 3435 if key && !optkeys.find{|opt| opt.to_s == key.to_s} 3436 fail ArgumentError, "unknown font option name `#{key}'" 3437 end 3438 3439 win, tag = __pathname.split(':') 3440 3441 if key 3442 pathname = [win, tag, key].join(';') 3443 TkFont.used_on(pathname) || 3444 TkFont.init_widget_font(pathname, *__confinfo_cmd) 3445 elsif optkeys.size == 1 3446 pathname = [win, tag, optkeys[0]].join(';') 3447 TkFont.used_on(pathname) || 3448 TkFont.init_widget_font(pathname, *__confinfo_cmd) 3449 else 3450 fonts = {} 3451 optkeys.each{|k| 3452 k = k.to_s 3453 pathname = [win, tag, k].join(';') 3454 fonts[k] = 3455 TkFont.used_on(pathname) || 3456 TkFont.init_widget_font(pathname, *__confinfo_cmd) 3457 } 3458 fonts 3459 end 3460 end 3461 alias fontobj font_configinfo 3462 3463 def font_configure(slot) 3464 pathname = __pathname 3465 3466 slot = _symbolkey2str(slot) 3467 3468 __font_optkeys.each{|optkey| 3469 optkey = optkey.to_s 3470 l_optkey = 'latin' << optkey 3471 a_optkey = 'ascii' << optkey 3472 k_optkey = 'kanji' << optkey 3473 3474 if slot.key?(optkey) 3475 fnt = slot.delete(optkey) 3476 if fnt.kind_of?(TkFont) 3477 slot.delete(l_optkey) 3478 slot.delete(a_optkey) 3479 slot.delete(k_optkey) 3480 3481 fnt.call_font_configure([pathname, optkey], *(__config_cmd << {})) 3482 next 3483 else 3484 if fnt 3485 if (slot.key?(l_optkey) || 3486 slot.key?(a_optkey) || 3487 slot.key?(k_optkey)) 3488 fnt = TkFont.new(fnt) 3489 3490 lfnt = slot.delete(l_optkey) 3491 lfnt = slot.delete(a_optkey) if slot.key?(a_optkey) 3492 kfnt = slot.delete(k_optkey) 3493 3494 fnt.latin_replace(lfnt) if lfnt 3495 fnt.kanji_replace(kfnt) if kfnt 3496 3497 fnt.call_font_configure([pathname, optkey], 3498 *(__config_cmd << {})) 3499 next 3500 else 3501 fnt = hash_kv(fnt) if fnt.kind_of?(Hash) 3502 unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 3503 tk_call(*(__config_cmd << "-#{optkey}" << fnt)) 3504 else 3505 begin 3506 tk_call(*(__config_cmd << "-#{optkey}" << fnt)) 3507 rescue 3508 # ignore 3509 end 3510 end 3511 end 3512 end 3513 next 3514 end 3515 end 3516 3517 lfnt = slot.delete(l_optkey) 3518 lfnt = slot.delete(a_optkey) if slot.key?(a_optkey) 3519 kfnt = slot.delete(k_optkey) 3520 3521 if lfnt && kfnt 3522 TkFont.new(lfnt, kfnt).call_font_configure([pathname, optkey], 3523 *(__config_cmd << {})) 3524 elsif lfnt 3525 latinfont_configure([lfnt, optkey]) 3526 elsif kfnt 3527 kanjifont_configure([kfnt, optkey]) 3528 end 3529 } 3530 3531 # configure other (without font) options 3532 tk_call(*(__config_cmd.concat(hash_kv(slot)))) if slot != {} 3533 self 3534 end 3535 3536 def latinfont_configure(ltn, keys=nil) 3537 if ltn.kind_of?(Array) 3538 key = ltn[1] 3539 ltn = ltn[0] 3540 else 3541 key = nil 3542 end 3543 3544 optkeys = __font_optkeys 3545 if key && !optkeys.find{|opt| opt.to_s == key.to_s} 3546 fail ArgumentError, "unknown font option name `#{key}'" 3547 end 3548 3549 win, tag = __pathname.split(':') 3550 3551 optkeys = [key] if key 3552 3553 optkeys.each{|optkey| 3554 optkey = optkey.to_s 3555 3556 pathname = [win, tag, optkey].join(';') 3557 3558 if (fobj = TkFont.used_on(pathname)) 3559 fobj = TkFont.new(fobj) # create a new TkFont object 3560 elsif Tk::JAPANIZED_TK 3561 fobj = fontobj # create a new TkFont object 3562 else 3563 ltn = hash_kv(ltn) if ltn.kind_of?(Hash) 3564 unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 3565 tk_call(*(__config_cmd << "-#{optkey}" << ltn)) 3566 else 3567 begin 3568 tk_call(*(__config_cmd << "-#{optkey}" << ltn)) 3569 rescue => e 3570 # ignore 3571 end 3572 end 3573 next 3574 end 3575 3576 if fobj.kind_of?(TkFont) 3577 if ltn.kind_of?(TkFont) 3578 conf = {} 3579 ltn.latin_configinfo.each{|k,val| conf[k] = val} 3580 if keys 3581 fobj.latin_configure(conf.update(keys)) 3582 else 3583 fobj.latin_configure(conf) 3584 end 3585 else 3586 fobj.latin_replace(ltn) 3587 end 3588 end 3589 3590 fobj.call_font_configure([pathname, optkey], *(__config_cmd << {})) 3591 } 3592 self 3593 end 3594 alias asciifont_configure latinfont_configure 3595 3596 def kanjifont_configure(knj, keys=nil) 3597 if knj.kind_of?(Array) 3598 key = knj[1] 3599 knj = knj[0] 3600 else 3601 key = nil 3602 end 3603 3604 optkeys = __font_optkeys 3605 if key && !optkeys.find{|opt| opt.to_s == key.to_s} 3606 fail ArgumentError, "unknown font option name `#{key}'" 3607 end 3608 3609 win, tag = __pathname.split(':') 3610 3611 optkeys = [key] if key 3612 3613 optkeys.each{|optkey| 3614 optkey = optkey.to_s 3615 3616 pathname = [win, tag, optkey].join(';') 3617 3618 if (fobj = TkFont.used_on(pathname)) 3619 fobj = TkFont.new(fobj) # create a new TkFont object 3620 elsif Tk::JAPANIZED_TK 3621 fobj = fontobj # create a new TkFont object 3622 else 3623 knj = hash_kv(knj) if knj.kind_of?(Hash) 3624 unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 3625 tk_call(*(__config_cmd << "-#{optkey}" << knj)) 3626 else 3627 begin 3628 tk_call(*(__config_cmd << "-#{optkey}" << knj)) 3629 rescue => e 3630 # ignore 3631 end 3632 end 3633 next 3634 end 3635 3636 if fobj.kind_of?(TkFont) 3637 if knj.kind_of?(TkFont) 3638 conf = {} 3639 knj.kanji_configinfo.each{|k,val| conf[k] = val} 3640 if keys 3641 fobj.kanji_configure(conf.update(keys)) 3642 else 3643 fobj.kanji_configure(conf) 3644 end 3645 else 3646 fobj.kanji_replace(knj) 3647 end 3648 end 3649 3650 fobj.call_font_configure([pathname, optkey], *(__config_cmd << {})) 3651 } 3652 self 3653 end 3654 3655 def font_copy(win, wintag=nil, winkey=nil, targetkey=nil) 3656 if wintag 3657 if winkey 3658 fnt = win.tagfontobj(wintag, winkey).dup 3659 else 3660 fnt = win.tagfontobj(wintag).dup 3661 end 3662 else 3663 if winkey 3664 fnt = win.fontobj(winkey).dup 3665 else 3666 fnt = win.fontobj.dup 3667 end 3668 end 3669 3670 if targetkey 3671 fnt.call_font_configure([__pathname, targetkey], *(__config_cmd << {})) 3672 else 3673 fnt.call_font_configure(__pathname, *(__config_cmd << {})) 3674 end 3675 self 3676 end 3677 3678 def latinfont_copy(win, wintag=nil, winkey=nil, targetkey=nil) 3679 if targetkey 3680 fontobj(targetkey).dup.call_font_configure([__pathname, targetkey], 3681 *(__config_cmd << {})) 3682 else 3683 fontobj.dup.call_font_configure(__pathname, *(__config_cmd << {})) 3684 end 3685 3686 if wintag 3687 if winkey 3688 fontobj.latin_replace(win.tagfontobj(wintag, winkey).latin_font_id) 3689 else 3690 fontobj.latin_replace(win.tagfontobj(wintag).latin_font_id) 3691 end 3692 else 3693 if winkey 3694 fontobj.latin_replace(win.fontobj(winkey).latin_font_id) 3695 else 3696 fontobj.latin_replace(win.fontobj.latin_font_id) 3697 end 3698 end 3699 self 3700 end 3701 alias asciifont_copy latinfont_copy 3702 3703 def kanjifont_copy(win, wintag=nil, winkey=nil, targetkey=nil) 3704 if targetkey 3705 fontobj(targetkey).dup.call_font_configure([__pathname, targetkey], 3706 *(__config_cmd << {})) 3707 else 3708 fontobj.dup.call_font_configure(__pathname, *(__config_cmd << {})) 3709 end 3710 3711 if wintag 3712 if winkey 3713 fontobj.kanji_replace(win.tagfontobj(wintag, winkey).kanji_font_id) 3714 else 3715 fontobj.kanji_replace(win.tagfontobj(wintag).kanji_font_id) 3716 end 3717 else 3718 if winkey 3719 fontobj.kanji_replace(win.fontobj(winkey).kanji_font_id) 3720 else 3721 fontobj.kanji_replace(win.fontobj.kanji_font_id) 3722 end 3723 end 3724 self 3725 end 3726end 3727 3728 3729module TkConfigMethod 3730 include TkUtil 3731 include TkTreatFont 3732 3733 def TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 3734 @mode || false 3735 end 3736 def TkConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__!(mode) 3737 fail SecurityError, "can't change the mode" if $SAFE>=4 3738 @mode = (mode)? true: false 3739 end 3740 3741 def __cget_cmd 3742 [self.path, 'cget'] 3743 end 3744 private :__cget_cmd 3745 3746 def __config_cmd 3747 [self.path, 'configure'] 3748 end 3749 private :__config_cmd 3750 3751 def __confinfo_cmd 3752 __config_cmd 3753 end 3754 private :__confinfo_cmd 3755 3756 def __configinfo_struct 3757 {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, 3758 :default_value=>3, :current_value=>4} 3759 end 3760 private :__configinfo_struct 3761 3762 def __optkey_aliases 3763 {} 3764 end 3765 private :__optkey_aliases 3766 3767 def __numval_optkeys 3768 [] 3769 end 3770 private :__numval_optkeys 3771 3772 def __numstrval_optkeys 3773 [] 3774 end 3775 private :__numstrval_optkeys 3776 3777 def __boolval_optkeys 3778 ['exportselection', 'jump', 'setgrid', 'takefocus'] 3779 end 3780 private :__boolval_optkeys 3781 3782 def __strval_optkeys 3783 [ 3784 'text', 'label', 'show', 'data', 'file', 3785 'activebackground', 'activeforeground', 'background', 3786 'disabledforeground', 'disabledbackground', 'foreground', 3787 'highlightbackground', 'highlightcolor', 'insertbackground', 3788 'selectbackground', 'selectforeground', 'troughcolor' 3789 ] 3790 end 3791 private :__strval_optkeys 3792 3793 def __listval_optkeys 3794 [] 3795 end 3796 private :__listval_optkeys 3797 3798 def __numlistval_optkeys 3799 [] 3800 end 3801 private :__numlistval_optkeys 3802 3803 def __tkvariable_optkeys 3804 ['variable', 'textvariable'] 3805 end 3806 private :__tkvariable_optkeys 3807 3808 def __val2ruby_optkeys # { key=>proc, ... } 3809 # The method is used to convert a opt-value to a ruby's object. 3810 # When get the value of the option "key", "proc.call(value)" is called. 3811 {} 3812 end 3813 private :__val2ruby_optkeys 3814 3815 def __ruby2val_optkeys # { key=>proc, ... } 3816 # The method is used to convert a ruby's object to a opt-value. 3817 # When set the value of the option "key", "proc.call(value)" is called. 3818 # That is, "-#{key} #{proc.call(value)}". 3819 {} 3820 end 3821 private :__ruby2val_optkeys 3822 3823 def __methodcall_optkeys # { key=>method, ... } 3824 # The method is used to both of get and set. 3825 # Usually, the 'key' will not be a widget option. 3826 {} 3827 end 3828 private :__methodcall_optkeys 3829 3830 def __keyonly_optkeys # { def_key=>undef_key or nil, ... } 3831 {} 3832 end 3833 private :__keyonly_optkeys 3834 3835 def __conv_keyonly_opts(keys) 3836 return keys unless keys.kind_of?(Hash) 3837 keyonly = __keyonly_optkeys 3838 keys2 = {} 3839 keys.each{|k, v| 3840 optkey = keyonly.find{|kk,vv| kk.to_s == k.to_s} 3841 if optkey 3842 defkey, undefkey = optkey 3843 if v 3844 keys2[defkey.to_s] = None 3845 elsif undefkey 3846 keys2[undefkey.to_s] = None 3847 else 3848 # remove key 3849 end 3850 else 3851 keys2[k.to_s] = v 3852 end 3853 } 3854 keys2 3855 end 3856 private :__conv_keyonly_opts 3857 3858 def config_hash_kv(keys, enc_mode = nil, conf = nil) 3859 hash_kv(__conv_keyonly_opts(keys), enc_mode, conf) 3860 end 3861 3862 ################################ 3863 3864 def [](id) 3865 cget(id) 3866 end 3867 3868 def []=(id, val) 3869 configure(id, val) 3870 val 3871 end 3872 3873 def cget_tkstring(option) 3874 opt = option.to_s 3875 fail ArgumentError, "Invalid option `#{option.inspect}'" if opt.length == 0 3876 tk_call_without_enc(*(__cget_cmd << "-#{opt}")) 3877 end 3878 3879 def __cget_core(slot) 3880 orig_slot = slot 3881 slot = slot.to_s 3882 3883 if slot.length == 0 3884 fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" 3885 end 3886 3887 alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot} 3888 if real_name 3889 slot = real_name.to_s 3890 end 3891 3892 if ( method = _symbolkey2str(__val2ruby_optkeys())[slot] ) 3893 optval = tk_call_without_enc(*(__cget_cmd << "-#{slot}")) 3894 begin 3895 return method.call(optval) 3896 rescue => e 3897 warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG 3898 return optval 3899 end 3900 end 3901 3902 if ( method = _symbolkey2str(__methodcall_optkeys)[slot] ) 3903 return self.__send__(method) 3904 end 3905 3906 case slot 3907 when /^(#{__numval_optkeys.join('|')})$/ 3908 begin 3909 number(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) 3910 rescue 3911 nil 3912 end 3913 3914 when /^(#{__numstrval_optkeys.join('|')})$/ 3915 num_or_str(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) 3916 3917 when /^(#{__boolval_optkeys.join('|')})$/ 3918 begin 3919 bool(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) 3920 rescue 3921 nil 3922 end 3923 3924 when /^(#{__listval_optkeys.join('|')})$/ 3925 simplelist(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) 3926 3927 when /^(#{__numlistval_optkeys.join('|')})$/ 3928 conf = tk_call_without_enc(*(__cget_cmd << "-#{slot}")) 3929 if conf =~ /^[0-9+-]/ 3930 list(conf) 3931 else 3932 conf 3933 end 3934 3935 when /^(#{__strval_optkeys.join('|')})$/ 3936 _fromUTF8(tk_call_without_enc(*(__cget_cmd << "-#{slot}"))) 3937 3938 when /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/ 3939 fontcode = $1 3940 fontkey = $2 3941 fnt = tk_tcl2ruby(tk_call_without_enc(*(__cget_cmd << "-#{fontkey}")), true) 3942 unless fnt.kind_of?(TkFont) 3943 fnt = fontobj(fontkey) 3944 end 3945 if fontcode == 'kanji' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/ 3946 # obsolete; just for compatibility 3947 fnt.kanji_font 3948 else 3949 fnt 3950 end 3951 3952 when /^(#{__tkvariable_optkeys.join('|')})$/ 3953 v = tk_call_without_enc(*(__cget_cmd << "-#{slot}")) 3954 (v.empty?)? nil: TkVarAccess.new(v) 3955 3956 else 3957 tk_tcl2ruby(tk_call_without_enc(*(__cget_cmd << "-#{slot}")), true) 3958 end 3959 end 3960 private :__cget_core 3961 3962 def cget(slot) 3963 unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 3964 __cget_core(slot) 3965 else 3966 begin 3967 __cget_core(slot) 3968 rescue => e 3969 if current_configinfo.has_key?(slot.to_s) 3970 # error on known option 3971 fail e 3972 else 3973 # unknown option 3974 nil 3975 end 3976 end 3977 end 3978 end 3979 def cget_strict(slot) 3980 # never use TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 3981 __cget_core(slot) 3982 end 3983 3984 def __configure_core(slot, value=None) 3985 if slot.kind_of? Hash 3986 slot = _symbolkey2str(slot) 3987 3988 __optkey_aliases.each{|alias_name, real_name| 3989 alias_name = alias_name.to_s 3990 if slot.has_key?(alias_name) 3991 slot[real_name.to_s] = slot.delete(alias_name) 3992 end 3993 } 3994 3995 __methodcall_optkeys.each{|key, method| 3996 value = slot.delete(key.to_s) 3997 self.__send__(method, value) if value 3998 } 3999 4000 __ruby2val_optkeys.each{|key, method| 4001 key = key.to_s 4002 slot[key] = method.call(slot[key]) if slot.has_key?(key) 4003 } 4004 4005 __keyonly_optkeys.each{|defkey, undefkey| 4006 conf = slot.find{|kk, vv| kk == defkey.to_s} 4007 if conf 4008 k, v = conf 4009 if v 4010 slot[k] = None 4011 else 4012 slot[undefkey.to_s] = None if undefkey 4013 slot.delete(k) 4014 end 4015 end 4016 } 4017 4018 if (slot.find{|k, v| k =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/}) 4019 font_configure(slot) 4020 elsif slot.size > 0 4021 tk_call(*(__config_cmd.concat(hash_kv(slot)))) 4022 end 4023 4024 else 4025 orig_slot = slot 4026 slot = slot.to_s 4027 if slot.length == 0 4028 fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" 4029 end 4030 4031 alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot} 4032 if real_name 4033 slot = real_name.to_s 4034 end 4035 4036 if ( conf = __keyonly_optkeys.find{|k, v| k.to_s == slot} ) 4037 defkey, undefkey = conf 4038 if value 4039 tk_call(*(__config_cmd << "-#{defkey}")) 4040 elsif undefkey 4041 tk_call(*(__config_cmd << "-#{undefkey}")) 4042 end 4043 elsif ( method = _symbolkey2str(__ruby2val_optkeys)[slot] ) 4044 tk_call(*(__config_cmd << "-#{slot}" << method.call(value))) 4045 elsif ( method = _symbolkey2str(__methodcall_optkeys)[slot] ) 4046 self.__send__(method, value) 4047 elsif (slot =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) 4048 if value == None 4049 fontobj($2) 4050 else 4051 font_configure({slot=>value}) 4052 end 4053 else 4054 tk_call(*(__config_cmd << "-#{slot}" << value)) 4055 end 4056 end 4057 self 4058 end 4059 private :__configure_core 4060 4061 def __check_available_configure_options(keys) 4062 availables = self.current_configinfo.keys 4063 4064 # add non-standard keys 4065 availables |= __font_optkeys.map{|k| 4066 [k.to_s, "latin#{k}", "ascii#{k}", "kanji#{k}"] 4067 }.flatten 4068 availables |= __methodcall_optkeys.keys.map{|k| k.to_s} 4069 availables |= __keyonly_optkeys.keys.map{|k| k.to_s} 4070 4071 keys = _symbolkey2str(keys) 4072 keys.delete_if{|k, v| !(availables.include?(k))} 4073 end 4074 4075 def configure(slot, value=None) 4076 unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 4077 __configure_core(slot, value) 4078 else 4079 if slot.kind_of?(Hash) 4080 begin 4081 __configure_core(slot) 4082 rescue 4083 slot = __check_available_configure_options(slot) 4084 __configure_core(slot) unless slot.empty? 4085 end 4086 else 4087 begin 4088 __configure_core(slot, value) 4089 rescue => e 4090 if current_configinfo.has_key?(slot.to_s) 4091 # error on known option 4092 fail e 4093 else 4094 # unknown option 4095 nil 4096 end 4097 end 4098 end 4099 end 4100 self 4101 end 4102 4103 def configure_cmd(slot, value) 4104 configure(slot, install_cmd(value)) 4105 end 4106 4107 def __configinfo_core(slot = nil) 4108 if TkComm::GET_CONFIGINFO_AS_ARRAY 4109 if (slot && 4110 slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) 4111 fontkey = $2 4112 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")))) 4113 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")), false, true) 4114 conf[__configinfo_struct[:key]] = 4115 conf[__configinfo_struct[:key]][1..-1] 4116 if ( ! __configinfo_struct[:alias] \ 4117 || conf.size > __configinfo_struct[:alias] + 1 ) 4118 fnt = conf[__configinfo_struct[:default_value]] 4119 if TkFont.is_system_font?(fnt) 4120 conf[__configinfo_struct[:default_value]] = TkNamedFont.new(fnt) 4121 end 4122 conf[__configinfo_struct[:current_value]] = fontobj(fontkey) 4123 elsif ( __configinfo_struct[:alias] \ 4124 && conf.size == __configinfo_struct[:alias] + 1 \ 4125 && conf[__configinfo_struct[:alias]][0] == ?- ) 4126 conf[__configinfo_struct[:alias]] = 4127 conf[__configinfo_struct[:alias]][1..-1] 4128 end 4129 conf 4130 else 4131 if slot 4132 slot = slot.to_s 4133 4134 alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot} 4135 if real_name 4136 slot = real_name.to_s 4137 end 4138 4139 case slot 4140 when /^(#{__val2ruby_optkeys().keys.join('|')})$/ 4141 method = _symbolkey2str(__val2ruby_optkeys())[slot] 4142 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd() << "-#{slot}")), false, true) 4143 if ( __configinfo_struct[:default_value] \ 4144 && conf[__configinfo_struct[:default_value]] ) 4145 optval = conf[__configinfo_struct[:default_value]] 4146 begin 4147 val = method.call(optval) 4148 rescue => e 4149 warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG 4150 val = optval 4151 end 4152 conf[__configinfo_struct[:default_value]] = val 4153 end 4154 if ( conf[__configinfo_struct[:current_value]] ) 4155 optval = conf[__configinfo_struct[:current_value]] 4156 begin 4157 val = method.call(optval) 4158 rescue => e 4159 warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG 4160 val = optval 4161 end 4162 conf[__configinfo_struct[:current_value]] = val 4163 end 4164 4165 when /^(#{__methodcall_optkeys.keys.join('|')})$/ 4166 method = _symbolkey2str(__methodcall_optkeys)[slot] 4167 return [slot, '', '', '', self.__send__(method)] 4168 4169 when /^(#{__numval_optkeys.join('|')})$/ 4170 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4171 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4172 4173 if ( __configinfo_struct[:default_value] \ 4174 && conf[__configinfo_struct[:default_value]]) 4175 begin 4176 conf[__configinfo_struct[:default_value]] = 4177 number(conf[__configinfo_struct[:default_value]]) 4178 rescue 4179 conf[__configinfo_struct[:default_value]] = nil 4180 end 4181 end 4182 if ( conf[__configinfo_struct[:current_value]] ) 4183 begin 4184 conf[__configinfo_struct[:current_value]] = 4185 number(conf[__configinfo_struct[:current_value]]) 4186 rescue 4187 conf[__configinfo_struct[:current_value]] = nil 4188 end 4189 end 4190 4191 when /^(#{__numstrval_optkeys.join('|')})$/ 4192 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4193 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4194 4195 if ( __configinfo_struct[:default_value] \ 4196 && conf[__configinfo_struct[:default_value]]) 4197 conf[__configinfo_struct[:default_value]] = 4198 num_or_str(conf[__configinfo_struct[:default_value]]) 4199 end 4200 if ( conf[__configinfo_struct[:current_value]] ) 4201 conf[__configinfo_struct[:current_value]] = 4202 num_or_str(conf[__configinfo_struct[:current_value]]) 4203 end 4204 4205 when /^(#{__boolval_optkeys.join('|')})$/ 4206 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4207 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4208 4209 if ( __configinfo_struct[:default_value] \ 4210 && conf[__configinfo_struct[:default_value]]) 4211 begin 4212 conf[__configinfo_struct[:default_value]] = 4213 bool(conf[__configinfo_struct[:default_value]]) 4214 rescue 4215 conf[__configinfo_struct[:default_value]] = nil 4216 end 4217 end 4218 if ( conf[__configinfo_struct[:current_value]] ) 4219 begin 4220 conf[__configinfo_struct[:current_value]] = 4221 bool(conf[__configinfo_struct[:current_value]]) 4222 rescue 4223 conf[__configinfo_struct[:current_value]] = nil 4224 end 4225 end 4226 4227 when /^(#{__listval_optkeys.join('|')})$/ 4228 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4229 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4230 4231 if ( __configinfo_struct[:default_value] \ 4232 && conf[__configinfo_struct[:default_value]]) 4233 conf[__configinfo_struct[:default_value]] = 4234 simplelist(conf[__configinfo_struct[:default_value]]) 4235 end 4236 if ( conf[__configinfo_struct[:current_value]] ) 4237 conf[__configinfo_struct[:current_value]] = 4238 simplelist(conf[__configinfo_struct[:current_value]]) 4239 end 4240 4241 when /^(#{__numlistval_optkeys.join('|')})$/ 4242 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4243 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4244 4245 if ( __configinfo_struct[:default_value] \ 4246 && conf[__configinfo_struct[:default_value]] \ 4247 && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ ) 4248 conf[__configinfo_struct[:default_value]] = 4249 list(conf[__configinfo_struct[:default_value]]) 4250 end 4251 if ( conf[__configinfo_struct[:current_value]] \ 4252 && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ ) 4253 conf[__configinfo_struct[:current_value]] = 4254 list(conf[__configinfo_struct[:current_value]]) 4255 end 4256 4257 when /^(#{__strval_optkeys.join('|')})$/ 4258 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4259 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4260 4261 when /^(#{__tkvariable_optkeys.join('|')})$/ 4262 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4263 4264 if ( __configinfo_struct[:default_value] \ 4265 && conf[__configinfo_struct[:default_value]]) 4266 v = conf[__configinfo_struct[:default_value]] 4267 if v.empty? 4268 conf[__configinfo_struct[:default_value]] = nil 4269 else 4270 conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v) 4271 end 4272 end 4273 if ( conf[__configinfo_struct[:current_value]] ) 4274 v = conf[__configinfo_struct[:current_value]] 4275 if v.empty? 4276 conf[__configinfo_struct[:current_value]] = nil 4277 else 4278 conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v) 4279 end 4280 end 4281 4282 else 4283 # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4284 # conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true) 4285 conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 1, false, true) 4286 end 4287 conf[__configinfo_struct[:key]] = 4288 conf[__configinfo_struct[:key]][1..-1] 4289 4290 if ( __configinfo_struct[:alias] \ 4291 && conf.size == __configinfo_struct[:alias] + 1 \ 4292 && conf[__configinfo_struct[:alias]][0] == ?- ) 4293 conf[__configinfo_struct[:alias]] = 4294 conf[__configinfo_struct[:alias]][1..-1] 4295 end 4296 4297 conf 4298 4299 else 4300 # ret = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*__confinfo_cmd))).collect{|conflist| 4301 # conf = tk_split_simplelist(conflist) 4302 ret = tk_split_simplelist(tk_call_without_enc(*__confinfo_cmd), false, false).collect{|conflist| 4303 conf = tk_split_simplelist(conflist, false, true) 4304 conf[__configinfo_struct[:key]] = 4305 conf[__configinfo_struct[:key]][1..-1] 4306 4307 optkey = conf[__configinfo_struct[:key]] 4308 case optkey 4309 when /^(#{__val2ruby_optkeys().keys.join('|')})$/ 4310 method = _symbolkey2str(__val2ruby_optkeys())[optkey] 4311 if ( __configinfo_struct[:default_value] \ 4312 && conf[__configinfo_struct[:default_value]] ) 4313 optval = conf[__configinfo_struct[:default_value]] 4314 begin 4315 val = method.call(optval) 4316 rescue => e 4317 warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG 4318 val = optval 4319 end 4320 conf[__configinfo_struct[:default_value]] = val 4321 end 4322 if ( conf[__configinfo_struct[:current_value]] ) 4323 optval = conf[__configinfo_struct[:current_value]] 4324 begin 4325 val = method.call(optval) 4326 rescue => e 4327 warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG 4328 val = optval 4329 end 4330 conf[__configinfo_struct[:current_value]] = val 4331 end 4332 4333 when /^(#{__strval_optkeys.join('|')})$/ 4334 # do nothing 4335 4336 when /^(#{__numval_optkeys.join('|')})$/ 4337 if ( __configinfo_struct[:default_value] \ 4338 && conf[__configinfo_struct[:default_value]] ) 4339 begin 4340 conf[__configinfo_struct[:default_value]] = 4341 number(conf[__configinfo_struct[:default_value]]) 4342 rescue 4343 conf[__configinfo_struct[:default_value]] = nil 4344 end 4345 end 4346 if ( conf[__configinfo_struct[:current_value]] ) 4347 begin 4348 conf[__configinfo_struct[:current_value]] = 4349 number(conf[__configinfo_struct[:current_value]]) 4350 rescue 4351 conf[__configinfo_struct[:current_value]] = nil 4352 end 4353 end 4354 4355 when /^(#{__numstrval_optkeys.join('|')})$/ 4356 if ( __configinfo_struct[:default_value] \ 4357 && conf[__configinfo_struct[:default_value]] ) 4358 conf[__configinfo_struct[:default_value]] = 4359 num_or_str(conf[__configinfo_struct[:default_value]]) 4360 end 4361 if ( conf[__configinfo_struct[:current_value]] ) 4362 conf[__configinfo_struct[:current_value]] = 4363 num_or_str(conf[__configinfo_struct[:current_value]]) 4364 end 4365 4366 when /^(#{__boolval_optkeys.join('|')})$/ 4367 if ( __configinfo_struct[:default_value] \ 4368 && conf[__configinfo_struct[:default_value]] ) 4369 begin 4370 conf[__configinfo_struct[:default_value]] = 4371 bool(conf[__configinfo_struct[:default_value]]) 4372 rescue 4373 conf[__configinfo_struct[:default_value]] = nil 4374 end 4375 end 4376 if ( conf[__configinfo_struct[:current_value]] ) 4377 begin 4378 conf[__configinfo_struct[:current_value]] = 4379 bool(conf[__configinfo_struct[:current_value]]) 4380 rescue 4381 conf[__configinfo_struct[:current_value]] = nil 4382 end 4383 end 4384 4385 when /^(#{__listval_optkeys.join('|')})$/ 4386 if ( __configinfo_struct[:default_value] \ 4387 && conf[__configinfo_struct[:default_value]] ) 4388 conf[__configinfo_struct[:default_value]] = 4389 simplelist(conf[__configinfo_struct[:default_value]]) 4390 end 4391 if ( conf[__configinfo_struct[:current_value]] ) 4392 conf[__configinfo_struct[:current_value]] = 4393 simplelist(conf[__configinfo_struct[:current_value]]) 4394 end 4395 4396 when /^(#{__numlistval_optkeys.join('|')})$/ 4397 if ( __configinfo_struct[:default_value] \ 4398 && conf[__configinfo_struct[:default_value]] \ 4399 && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ ) 4400 conf[__configinfo_struct[:default_value]] = 4401 list(conf[__configinfo_struct[:default_value]]) 4402 end 4403 if ( conf[__configinfo_struct[:current_value]] \ 4404 && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ ) 4405 conf[__configinfo_struct[:current_value]] = 4406 list(conf[__configinfo_struct[:current_value]]) 4407 end 4408 4409 when /^(#{__tkvariable_optkeys.join('|')})$/ 4410 if ( __configinfo_struct[:default_value] \ 4411 && conf[__configinfo_struct[:default_value]] ) 4412 v = conf[__configinfo_struct[:default_value]] 4413 if v.empty? 4414 conf[__configinfo_struct[:default_value]] = nil 4415 else 4416 conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v) 4417 end 4418 end 4419 if ( conf[__configinfo_struct[:current_value]] ) 4420 v = conf[__configinfo_struct[:current_value]] 4421 if v.empty? 4422 conf[__configinfo_struct[:current_value]] = nil 4423 else 4424 conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v) 4425 end 4426 end 4427 4428 else 4429 if ( __configinfo_struct[:default_value] \ 4430 && conf[__configinfo_struct[:default_value]] ) 4431 if conf[__configinfo_struct[:default_value]].index('{') 4432 conf[__configinfo_struct[:default_value]] = 4433 tk_split_list(conf[__configinfo_struct[:default_value]]) 4434 else 4435 conf[__configinfo_struct[:default_value]] = 4436 tk_tcl2ruby(conf[__configinfo_struct[:default_value]]) 4437 end 4438 end 4439 if conf[__configinfo_struct[:current_value]] 4440 if conf[__configinfo_struct[:current_value]].index('{') 4441 conf[__configinfo_struct[:current_value]] = 4442 tk_split_list(conf[__configinfo_struct[:current_value]]) 4443 else 4444 conf[__configinfo_struct[:current_value]] = 4445 tk_tcl2ruby(conf[__configinfo_struct[:current_value]]) 4446 end 4447 end 4448 end 4449 4450 if ( __configinfo_struct[:alias] \ 4451 && conf.size == __configinfo_struct[:alias] + 1 \ 4452 && conf[__configinfo_struct[:alias]][0] == ?- ) 4453 conf[__configinfo_struct[:alias]] = 4454 conf[__configinfo_struct[:alias]][1..-1] 4455 end 4456 4457 conf 4458 } 4459 4460 __font_optkeys.each{|optkey| 4461 optkey = optkey.to_s 4462 fontconf = ret.assoc(optkey) 4463 if fontconf && fontconf.size > 2 4464 ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/} 4465 fnt = fontconf[__configinfo_struct[:default_value]] 4466 if TkFont.is_system_font?(fnt) 4467 fontconf[__configinfo_struct[:default_value]] \ 4468 = TkNamedFont.new(fnt) 4469 end 4470 fontconf[__configinfo_struct[:current_value]] = fontobj(optkey) 4471 ret.push(fontconf) 4472 end 4473 } 4474 4475 __methodcall_optkeys.each{|optkey, m| 4476 ret << [optkey.to_s, '', '', '', self.__send__(m)] 4477 } 4478 4479 ret 4480 end 4481 end 4482 4483 else # ! TkComm::GET_CONFIGINFO_AS_ARRAY 4484 if (slot && 4485 slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) 4486 fontkey = $2 4487 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")))) 4488 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")), false, true) 4489 conf[__configinfo_struct[:key]] = 4490 conf[__configinfo_struct[:key]][1..-1] 4491 4492 if ( ! __configinfo_struct[:alias] \ 4493 || conf.size > __configinfo_struct[:alias] + 1 ) 4494 fnt = conf[__configinfo_struct[:default_value]] 4495 if TkFont.is_system_font?(fnt) 4496 conf[__configinfo_struct[:default_value]] = TkNamedFont.new(fnt) 4497 end 4498 conf[__configinfo_struct[:current_value]] = fontobj(fontkey) 4499 { conf.shift => conf } 4500 elsif ( __configinfo_struct[:alias] \ 4501 && conf.size == __configinfo_struct[:alias] + 1 ) 4502 if conf[__configinfo_struct[:alias]][0] == ?- 4503 conf[__configinfo_struct[:alias]] = 4504 conf[__configinfo_struct[:alias]][1..-1] 4505 end 4506 { conf[0] => conf[1] } 4507 else 4508 { conf.shift => conf } 4509 end 4510 else 4511 if slot 4512 slot = slot.to_s 4513 4514 alias_name, real_name = __optkey_aliases.find{|k,var| k.to_s == slot} 4515 if real_name 4516 slot = real_name.to_s 4517 end 4518 4519 case slot 4520 when /^(#{__val2ruby_optkeys().keys.join('|')})$/ 4521 method = _symbolkey2str(__val2ruby_optkeys())[slot] 4522 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4523 if ( __configinfo_struct[:default_value] \ 4524 && conf[__configinfo_struct[:default_value]] ) 4525 optval = conf[__configinfo_struct[:default_value]] 4526 begin 4527 val = method.call(optval) 4528 rescue => e 4529 warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG 4530 val = optval 4531 end 4532 conf[__configinfo_struct[:default_value]] = val 4533 end 4534 if ( conf[__configinfo_struct[:current_value]] ) 4535 optval = conf[__configinfo_struct[:current_value]] 4536 begin 4537 val = method.call(optval) 4538 rescue => e 4539 warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG 4540 val = optval 4541 end 4542 conf[__configinfo_struct[:current_value]] = val 4543 end 4544 4545 when /^(#{__methodcall_optkeys.keys.join('|')})$/ 4546 method = _symbolkey2str(__methodcall_optkeys)[slot] 4547 return {slot => ['', '', '', self.__send__(method)]} 4548 4549 when /^(#{__numval_optkeys.join('|')})$/ 4550 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4551 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4552 4553 if ( __configinfo_struct[:default_value] \ 4554 && conf[__configinfo_struct[:default_value]] ) 4555 begin 4556 conf[__configinfo_struct[:default_value]] = 4557 number(conf[__configinfo_struct[:default_value]]) 4558 rescue 4559 conf[__configinfo_struct[:default_value]] = nil 4560 end 4561 end 4562 if ( conf[__configinfo_struct[:current_value]] ) 4563 begin 4564 conf[__configinfo_struct[:current_value]] = 4565 number(conf[__configinfo_struct[:current_value]]) 4566 rescue 4567 conf[__configinfo_struct[:current_value]] = nil 4568 end 4569 end 4570 4571 when /^(#{__numstrval_optkeys.join('|')})$/ 4572 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4573 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4574 4575 if ( __configinfo_struct[:default_value] \ 4576 && conf[__configinfo_struct[:default_value]] ) 4577 conf[__configinfo_struct[:default_value]] = 4578 num_or_str(conf[__configinfo_struct[:default_value]]) 4579 end 4580 if ( conf[__configinfo_struct[:current_value]] ) 4581 conf[__configinfo_struct[:current_value]] = 4582 num_or_str(conf[__configinfo_struct[:current_value]]) 4583 end 4584 4585 when /^(#{__boolval_optkeys.join('|')})$/ 4586 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4587 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4588 4589 if ( __configinfo_struct[:default_value] \ 4590 && conf[__configinfo_struct[:default_value]] ) 4591 begin 4592 conf[__configinfo_struct[:default_value]] = 4593 bool(conf[__configinfo_struct[:default_value]]) 4594 rescue 4595 conf[__configinfo_struct[:default_value]] = nil 4596 end 4597 end 4598 if ( conf[__configinfo_struct[:current_value]] ) 4599 begin 4600 conf[__configinfo_struct[:current_value]] = 4601 bool(conf[__configinfo_struct[:current_value]]) 4602 rescue 4603 conf[__configinfo_struct[:current_value]] = nil 4604 end 4605 end 4606 4607 when /^(#{__listval_optkeys.join('|')})$/ 4608 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4609 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4610 4611 if ( __configinfo_struct[:default_value] \ 4612 && conf[__configinfo_struct[:default_value]] ) 4613 conf[__configinfo_struct[:default_value]] = 4614 simplelist(conf[__configinfo_struct[:default_value]]) 4615 end 4616 if ( conf[__configinfo_struct[:current_value]] ) 4617 conf[__configinfo_struct[:current_value]] = 4618 simplelist(conf[__configinfo_struct[:current_value]]) 4619 end 4620 4621 when /^(#{__numlistval_optkeys.join('|')})$/ 4622 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4623 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4624 4625 if ( __configinfo_struct[:default_value] \ 4626 && conf[__configinfo_struct[:default_value]] \ 4627 && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ ) 4628 conf[__configinfo_struct[:default_value]] = 4629 list(conf[__configinfo_struct[:default_value]]) 4630 end 4631 if ( conf[__configinfo_struct[:current_value]] \ 4632 && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ ) 4633 conf[__configinfo_struct[:current_value]] = 4634 list(conf[__configinfo_struct[:current_value]]) 4635 end 4636 4637 when /^(#{__tkvariable_optkeys.join('|')})$/ 4638 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4639 4640 if ( __configinfo_struct[:default_value] \ 4641 && conf[__configinfo_struct[:default_value]] ) 4642 v = conf[__configinfo_struct[:default_value]] 4643 if v.empty? 4644 conf[__configinfo_struct[:default_value]] = nil 4645 else 4646 conf[__configinfo_struct[:default_value]] = TkVarAccess.new(v) 4647 end 4648 end 4649 if ( conf[__configinfo_struct[:current_value]] ) 4650 v = conf[__configinfo_struct[:current_value]] 4651 if v.empty? 4652 conf[__configinfo_struct[:current_value]] = nil 4653 else 4654 conf[__configinfo_struct[:current_value]] = TkVarAccess.new(v) 4655 end 4656 end 4657 4658 when /^(#{__strval_optkeys.join('|')})$/ 4659 # conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4660 conf = tk_split_simplelist(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), false, true) 4661 else 4662 # conf = tk_split_list(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")))) 4663 conf = tk_split_list(tk_call_without_enc(*(__confinfo_cmd << "-#{slot}")), 0, false, true) 4664 end 4665 conf[__configinfo_struct[:key]] = 4666 conf[__configinfo_struct[:key]][1..-1] 4667 4668 if ( __configinfo_struct[:alias] \ 4669 && conf.size == __configinfo_struct[:alias] + 1 ) 4670 if conf[__configinfo_struct[:alias]][0] == ?- 4671 conf[__configinfo_struct[:alias]] = 4672 conf[__configinfo_struct[:alias]][1..-1] 4673 end 4674 { conf[0] => conf[1] } 4675 else 4676 { conf.shift => conf } 4677 end 4678 4679 else 4680 ret = {} 4681 # tk_split_simplelist(_fromUTF8(tk_call_without_enc(*__confinfo_cmd))).each{|conflist| 4682 # conf = tk_split_simplelist(conflist) 4683 tk_split_simplelist(tk_call_without_enc(*__confinfo_cmd), false, false).each{|conflist| 4684 conf = tk_split_simplelist(conflist, false, true) 4685 conf[__configinfo_struct[:key]] = 4686 conf[__configinfo_struct[:key]][1..-1] 4687 4688 optkey = conf[__configinfo_struct[:key]] 4689 case optkey 4690 when /^(#{__val2ruby_optkeys().keys.join('|')})$/ 4691 method = _symbolkey2str(__val2ruby_optkeys())[optkey] 4692 if ( __configinfo_struct[:default_value] \ 4693 && conf[__configinfo_struct[:default_value]] ) 4694 optval = conf[__configinfo_struct[:default_value]] 4695 begin 4696 val = method.call(optval) 4697 rescue => e 4698 warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG 4699 val = optval 4700 end 4701 conf[__configinfo_struct[:default_value]] = val 4702 end 4703 if ( conf[__configinfo_struct[:current_value]] ) 4704 optval = conf[__configinfo_struct[:current_value]] 4705 begin 4706 val = method.call(optval) 4707 rescue => e 4708 warn("Warning:: #{e.message} (when #{method}.call(#{optval.inspect})") if $DEBUG 4709 val = optval 4710 end 4711 conf[__configinfo_struct[:current_value]] = val 4712 end 4713 4714 when /^(#{__strval_optkeys.join('|')})$/ 4715 # do nothing 4716 4717 when /^(#{__numval_optkeys.join('|')})$/ 4718 if ( __configinfo_struct[:default_value] \ 4719 && conf[__configinfo_struct[:default_value]] ) 4720 begin 4721 conf[__configinfo_struct[:default_value]] = 4722 number(conf[__configinfo_struct[:default_value]]) 4723 rescue 4724 conf[__configinfo_struct[:default_value]] = nil 4725 end 4726 end 4727 if ( conf[__configinfo_struct[:current_value]] ) 4728 begin 4729 conf[__configinfo_struct[:current_value]] = 4730 number(conf[__configinfo_struct[:current_value]]) 4731 rescue 4732 conf[__configinfo_struct[:current_value]] = nil 4733 end 4734 end 4735 4736 when /^(#{__numstrval_optkeys.join('|')})$/ 4737 if ( __configinfo_struct[:default_value] \ 4738 && conf[__configinfo_struct[:default_value]] ) 4739 conf[__configinfo_struct[:default_value]] = 4740 num_or_str(conf[__configinfo_struct[:default_value]]) 4741 end 4742 if ( conf[__configinfo_struct[:current_value]] ) 4743 conf[__configinfo_struct[:current_value]] = 4744 num_or_str(conf[__configinfo_struct[:current_value]]) 4745 end 4746 4747 when /^(#{__boolval_optkeys.join('|')})$/ 4748 if ( __configinfo_struct[:default_value] \ 4749 && conf[__configinfo_struct[:default_value]] ) 4750 begin 4751 conf[__configinfo_struct[:default_value]] = 4752 bool(conf[__configinfo_struct[:default_value]]) 4753 rescue 4754 conf[__configinfo_struct[:default_value]] = nil 4755 end 4756 end 4757 if ( conf[__configinfo_struct[:current_value]] ) 4758 begin 4759 conf[__configinfo_struct[:current_value]] = 4760 bool(conf[__configinfo_struct[:current_value]]) 4761 rescue 4762 conf[__configinfo_struct[:current_value]] = nil 4763 end 4764 end 4765 4766 when /^(#{__listval_optkeys.join('|')})$/ 4767 if ( __configinfo_struct[:default_value] \ 4768 && conf[__configinfo_struct[:default_value]] ) 4769 conf[__configinfo_struct[:default_value]] = 4770 simplelist(conf[__configinfo_struct[:default_value]]) 4771 end 4772 if ( conf[__configinfo_struct[:current_value]] ) 4773 conf[__configinfo_struct[:current_value]] = 4774 simplelist(conf[__configinfo_struct[:current_value]]) 4775 end 4776 4777 when /^(#{__numlistval_optkeys.join('|')})$/ 4778 if ( __configinfo_struct[:default_value] \ 4779 && conf[__configinfo_struct[:default_value]] \ 4780 && conf[__configinfo_struct[:default_value]] =~ /^[0-9]/ ) 4781 conf[__configinfo_struct[:default_value]] = 4782 list(conf[__configinfo_struct[:default_value]]) 4783 end 4784 if ( conf[__configinfo_struct[:current_value]] \ 4785 && conf[__configinfo_struct[:current_value]] =~ /^[0-9]/ ) 4786 conf[__configinfo_struct[:current_value]] = 4787 list(conf[__configinfo_struct[:current_value]]) 4788 end 4789 4790 when /^(#{__tkvariable_optkeys.join('|')})$/ 4791 if ( __configinfo_struct[:default_value] \ 4792 && conf[__configinfo_struct[:default_value]] ) 4793 v = conf[__configinfo_struct[:default_value]] 4794 if v.empty? 4795 conf[__configinfo_struct[:default_value]] = nil 4796 else 4797 conf[__configinfo_struct[:default_value]] = TkVarAccess.new 4798 end 4799 end 4800 if ( conf[__configinfo_struct[:current_value]] ) 4801 v = conf[__configinfo_struct[:current_value]] 4802 if v.empty? 4803 conf[__configinfo_struct[:current_value]] = nil 4804 else 4805 conf[__configinfo_struct[:current_value]] = TkVarAccess.new 4806 end 4807 end 4808 4809 else 4810 if ( __configinfo_struct[:default_value] \ 4811 && conf[__configinfo_struct[:default_value]] ) 4812 if conf[__configinfo_struct[:default_value]].index('{') 4813 conf[__configinfo_struct[:default_value]] = 4814 tk_split_list(conf[__configinfo_struct[:default_value]]) 4815 else 4816 conf[__configinfo_struct[:default_value]] = 4817 tk_tcl2ruby(conf[__configinfo_struct[:default_value]]) 4818 end 4819 end 4820 if conf[__configinfo_struct[:current_value]] 4821 if conf[__configinfo_struct[:current_value]].index('{') 4822 conf[__configinfo_struct[:current_value]] = 4823 tk_split_list(conf[__configinfo_struct[:current_value]]) 4824 else 4825 conf[__configinfo_struct[:current_value]] = 4826 tk_tcl2ruby(conf[__configinfo_struct[:current_value]]) 4827 end 4828 end 4829 end 4830 4831 if ( __configinfo_struct[:alias] \ 4832 && conf.size == __configinfo_struct[:alias] + 1 ) 4833 if conf[__configinfo_struct[:alias]][0] == ?- 4834 conf[__configinfo_struct[:alias]] = 4835 conf[__configinfo_struct[:alias]][1..-1] 4836 end 4837 ret[conf[0]] = conf[1] 4838 else 4839 ret[conf.shift] = conf 4840 end 4841 } 4842 4843 __font_optkeys.each{|optkey| 4844 optkey = optkey.to_s 4845 fontconf = ret[optkey] 4846 if fontconf.kind_of?(Array) 4847 ret.delete(optkey) 4848 ret.delete('latin' << optkey) 4849 ret.delete('ascii' << optkey) 4850 ret.delete('kanji' << optkey) 4851 fnt = fontconf[__configinfo_struct[:default_value]] 4852 if TkFont.is_system_font?(fnt) 4853 fontconf[__configinfo_struct[:default_value]] \ 4854 = TkNamedFont.new(fnt) 4855 end 4856 fontconf[__configinfo_struct[:current_value]] = fontobj(optkey) 4857 ret[optkey] = fontconf 4858 end 4859 } 4860 4861 __methodcall_optkeys.each{|optkey, m| 4862 ret[optkey.to_s] = ['', '', '', self.__send__(m)] 4863 } 4864 4865 ret 4866 end 4867 end 4868 end 4869 end 4870 private :__configinfo_core 4871 4872 def configinfo(slot = nil) 4873 if slot && TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 4874 begin 4875 __configinfo_core(slot) 4876 rescue 4877 Array.new(__configinfo_struct.values.max).unshift(slot.to_s) 4878 end 4879 else 4880 __configinfo_core(slot) 4881 end 4882 end 4883 4884 def current_configinfo(slot = nil) 4885 if TkComm::GET_CONFIGINFO_AS_ARRAY 4886 if slot 4887 org_slot = slot 4888 begin 4889 conf = configinfo(slot) 4890 if ( ! __configinfo_struct[:alias] \ 4891 || conf.size > __configinfo_struct[:alias] + 1 ) 4892 return {conf[0] => conf[-1]} 4893 end 4894 slot = conf[__configinfo_struct[:alias]] 4895 end while(org_slot != slot) 4896 fail RuntimeError, 4897 "there is a configure alias loop about '#{org_slot}'" 4898 else 4899 ret = {} 4900 configinfo().each{|cnf| 4901 if ( ! __configinfo_struct[:alias] \ 4902 || cnf.size > __configinfo_struct[:alias] + 1 ) 4903 ret[cnf[0]] = cnf[-1] 4904 end 4905 } 4906 ret 4907 end 4908 else # ! TkComm::GET_CONFIGINFO_AS_ARRAY 4909 ret = {} 4910 configinfo(slot).each{|key, cnf| 4911 ret[key] = cnf[-1] if cnf.kind_of?(Array) 4912 } 4913 ret 4914 end 4915 end 4916end 4917 4918class TkObject<TkKernel 4919 extend TkCore 4920 include Tk 4921 include TkConfigMethod 4922 include TkBindCore 4923 4924### --> definition is moved to TkUtil module 4925# def path 4926# @path 4927# end 4928 4929 def epath 4930 @path 4931 end 4932 4933 def to_eval 4934 @path 4935 end 4936 4937 def tk_send(cmd, *rest) 4938 tk_call(path, cmd, *rest) 4939 end 4940 def tk_send_without_enc(cmd, *rest) 4941 tk_call_without_enc(path, cmd, *rest) 4942 end 4943 def tk_send_with_enc(cmd, *rest) 4944 tk_call_with_enc(path, cmd, *rest) 4945 end 4946 # private :tk_send, :tk_send_without_enc, :tk_send_with_enc 4947 4948 def tk_send_to_list(cmd, *rest) 4949 tk_call_to_list(path, cmd, *rest) 4950 end 4951 def tk_send_to_list_without_enc(cmd, *rest) 4952 tk_call_to_list_without_enc(path, cmd, *rest) 4953 end 4954 def tk_send_to_list_with_enc(cmd, *rest) 4955 tk_call_to_list_with_enc(path, cmd, *rest) 4956 end 4957 def tk_send_to_simplelist(cmd, *rest) 4958 tk_call_to_simplelist(path, cmd, *rest) 4959 end 4960 def tk_send_to_simplelist_without_enc(cmd, *rest) 4961 tk_call_to_simplelist_without_enc(path, cmd, *rest) 4962 end 4963 def tk_send_to_simplelist_with_enc(cmd, *rest) 4964 tk_call_to_simplelist_with_enc(path, cmd, *rest) 4965 end 4966 4967 def method_missing(id, *args) 4968 name = id.id2name 4969 case args.length 4970 when 1 4971 if name[-1] == ?= 4972 configure name[0..-2], args[0] 4973 args[0] 4974 else 4975 configure name, args[0] 4976 self 4977 end 4978 when 0 4979 begin 4980 cget(name) 4981 rescue 4982 if self.kind_of?(TkWindow) && name != "to_ary" && name != "to_str" 4983 fail NameError, 4984 "unknown option '#{id}' for #{self.inspect} (deleted widget?)" 4985 else 4986 super(id, *args) 4987 end 4988# fail NameError, 4989# "undefined local variable or method `#{name}' for #{self.to_s}", 4990# error_at 4991 end 4992 else 4993 super(id, *args) 4994# fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at 4995 end 4996 end 4997 4998=begin 4999 def [](id) 5000 cget(id) 5001 end 5002 5003 def []=(id, val) 5004 configure(id, val) 5005 val 5006 end 5007=end 5008 5009 def event_generate(context, keys=nil) 5010 if context.kind_of?(TkEvent::Event) 5011 context.generate(self, ((keys)? keys: {})) 5012 elsif keys 5013 #tk_call('event', 'generate', path, 5014 # "<#{tk_event_sequence(context)}>", *hash_kv(keys)) 5015 tk_call_without_enc('event', 'generate', path, 5016 "<#{tk_event_sequence(context)}>", 5017 *hash_kv(keys, true)) 5018 else 5019 #tk_call('event', 'generate', path, "<#{tk_event_sequence(context)}>") 5020 tk_call_without_enc('event', 'generate', path, 5021 "<#{tk_event_sequence(context)}>") 5022 end 5023 end 5024 5025 def tk_trace_variable(v) 5026 #unless v.kind_of?(TkVariable) 5027 # fail(ArgumentError, "type error (#{v.class}); must be TkVariable object") 5028 #end 5029 v 5030 end 5031 private :tk_trace_variable 5032 5033 def destroy 5034 #tk_call 'trace', 'vdelete', @tk_vn, 'w', @var_id if @var_id 5035 end 5036end 5037 5038 5039class TkWindow<TkObject 5040 include TkWinfo 5041 extend TkBindCore 5042 include Tk::Wm_for_General 5043 include Tk::Busy 5044 5045 @@WIDGET_INSPECT_FULL = false 5046 def TkWindow._widget_inspect_full_? 5047 @@WIDGET_INSPECT_FULL 5048 end 5049 def TkWindow._widget_inspect_full_=(mode) 5050 @@WIDGET_INSPECT_FULL = (mode && true) || false 5051 end 5052 5053 TkCommandNames = [].freeze 5054 ## ==> If TkCommandNames[0] is a string (not a null string), 5055 ## assume the string is a Tcl/Tk's create command of the widget class. 5056 WidgetClassName = ''.freeze 5057 # WidgetClassNames[WidgetClassName] = self 5058 ## ==> If self is a widget class, entry to the WidgetClassNames table. 5059 def self.to_eval 5060 self::WidgetClassName 5061 end 5062 5063 def initialize(parent=nil, keys=nil) 5064 if parent.kind_of? Hash 5065 keys = _symbolkey2str(parent) 5066 parent = keys.delete('parent') 5067 widgetname = keys.delete('widgetname') 5068 install_win(if parent then parent.path end, widgetname) 5069 without_creating = keys.delete('without_creating') 5070 # if without_creating && !widgetname 5071 # fail ArgumentError, 5072 # "if set 'without_creating' to true, need to define 'widgetname'" 5073 # end 5074 elsif keys 5075 keys = _symbolkey2str(keys) 5076 widgetname = keys.delete('widgetname') 5077 install_win(if parent then parent.path end, widgetname) 5078 without_creating = keys.delete('without_creating') 5079 # if without_creating && !widgetname 5080 # fail ArgumentError, 5081 # "if set 'without_creating' to true, need to define 'widgetname'" 5082 # end 5083 else 5084 install_win(if parent then parent.path end) 5085 end 5086 if self.method(:create_self).arity == 0 5087 p 'create_self has no arg' if $DEBUG 5088 create_self unless without_creating 5089 if keys 5090 # tk_call @path, 'configure', *hash_kv(keys) 5091 configure(keys) 5092 end 5093 else 5094 p 'create_self has args' if $DEBUG 5095 fontkeys = {} 5096 methodkeys = {} 5097 if keys 5098 #['font', 'kanjifont', 'latinfont', 'asciifont'].each{|key| 5099 # fontkeys[key] = keys.delete(key) if keys.key?(key) 5100 #} 5101 __font_optkeys.each{|key| 5102 fkey = key.to_s 5103 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) 5104 5105 fkey = "kanji#{key}" 5106 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) 5107 5108 fkey = "latin#{key}" 5109 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) 5110 5111 fkey = "ascii#{key}" 5112 fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) 5113 } 5114 5115 __optkey_aliases.each{|alias_name, real_name| 5116 alias_name = alias_name.to_s 5117 if keys.has_key?(alias_name) 5118 keys[real_name.to_s] = keys.delete(alias_name) 5119 end 5120 } 5121 5122 __methodcall_optkeys.each{|key| 5123 key = key.to_s 5124 methodkeys[key] = keys.delete(key) if keys.key?(key) 5125 } 5126 5127 __ruby2val_optkeys.each{|key, method| 5128 key = key.to_s 5129 keys[key] = method.call(keys[key]) if keys.has_key?(key) 5130 } 5131 end 5132 if without_creating && keys 5133 #configure(keys) 5134 configure(__conv_keyonly_opts(keys)) 5135 else 5136 #create_self(keys) 5137 create_self(__conv_keyonly_opts(keys)) 5138 end 5139 font_configure(fontkeys) unless fontkeys.empty? 5140 configure(methodkeys) unless methodkeys.empty? 5141 end 5142 end 5143 5144 def create_self(keys) 5145 # may need to override 5146 begin 5147 cmd = self.class::TkCommandNames[0] 5148 fail unless (cmd.kind_of?(String) && cmd.length > 0) 5149 rescue 5150 fail RuntimeError, "class #{self.class} may be an abstract class" 5151 end 5152 5153 if keys and keys != None 5154 unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 5155 tk_call_without_enc(cmd, @path, *hash_kv(keys, true)) 5156 else 5157 begin 5158 tk_call_without_enc(cmd, @path, *hash_kv(keys, true)) 5159 rescue => e 5160 tk_call_without_enc(cmd, @path) 5161 keys = __check_available_configure_options(keys) 5162 unless keys.empty? 5163 begin 5164 # try to configure 5165 configure(keys) 5166 rescue 5167 # fail => includes options adaptable when creattion only? 5168 begin 5169 tk_call_without_enc('destroy', @path) 5170 rescue 5171 # cannot rescue options error 5172 fail e 5173 else 5174 # re-create widget 5175 tk_call_without_enc(cmd, @path, *hash_kv(keys, true)) 5176 end 5177 end 5178 end 5179 end 5180 end 5181 else 5182 tk_call_without_enc(cmd, @path) 5183 end 5184 end 5185 private :create_self 5186 5187 def inspect 5188 if @@WIDGET_INSPECT_FULL 5189 super 5190 else 5191 str = super 5192 str[0..(str.index(' '))] << '@path=' << @path.inspect << '>' 5193 end 5194 end 5195 5196 def exist? 5197 TkWinfo.exist?(self) 5198 end 5199 5200 def bind_class 5201 @db_class || self.class() 5202 end 5203 5204 def database_classname 5205 TkWinfo.classname(self) 5206 end 5207 def database_class 5208 name = database_classname() 5209 if WidgetClassNames[name] 5210 WidgetClassNames[name] 5211 else 5212 TkDatabaseClass.new(name) 5213 end 5214 end 5215 def self.database_classname 5216 self::WidgetClassName 5217 end 5218 def self.database_class 5219 WidgetClassNames[self::WidgetClassName] 5220 end 5221 5222 def pack(keys = nil) 5223 #tk_call_without_enc('pack', epath, *hash_kv(keys, true)) 5224 if keys 5225 TkPack.configure(self, keys) 5226 else 5227 TkPack.configure(self) 5228 end 5229 self 5230 end 5231 5232 def pack_in(target, keys = nil) 5233 if keys 5234 keys = keys.dup 5235 keys['in'] = target 5236 else 5237 keys = {'in'=>target} 5238 end 5239 #tk_call 'pack', epath, *hash_kv(keys) 5240 TkPack.configure(self, keys) 5241 self 5242 end 5243 5244 def pack_forget 5245 #tk_call_without_enc('pack', 'forget', epath) 5246 TkPack.forget(self) 5247 self 5248 end 5249 alias unpack pack_forget 5250 5251 def pack_config(slot, value=None) 5252 #if slot.kind_of? Hash 5253 # tk_call 'pack', 'configure', epath, *hash_kv(slot) 5254 #else 5255 # tk_call 'pack', 'configure', epath, "-#{slot}", value 5256 #end 5257 if slot.kind_of? Hash 5258 TkPack.configure(self, slot) 5259 else 5260 TkPack.configure(self, slot=>value) 5261 end 5262 end 5263 alias pack_configure pack_config 5264 5265 def pack_info() 5266 #ilist = list(tk_call('pack', 'info', epath)) 5267 #info = {} 5268 #while key = ilist.shift 5269 # info[key[1..-1]] = ilist.shift 5270 #end 5271 #return info 5272 TkPack.info(self) 5273 end 5274 5275 def pack_propagate(mode=None) 5276 #if mode == None 5277 # bool(tk_call('pack', 'propagate', epath)) 5278 #else 5279 # tk_call('pack', 'propagate', epath, mode) 5280 # self 5281 #end 5282 if mode == None 5283 TkPack.propagate(self) 5284 else 5285 TkPack.propagate(self, mode) 5286 self 5287 end 5288 end 5289 5290 def pack_slaves() 5291 #list(tk_call('pack', 'slaves', epath)) 5292 TkPack.slaves(self) 5293 end 5294 5295 def grid(keys = nil) 5296 #tk_call 'grid', epath, *hash_kv(keys) 5297 if keys 5298 TkGrid.configure(self, keys) 5299 else 5300 TkGrid.configure(self) 5301 end 5302 self 5303 end 5304 5305 def grid_in(target, keys = nil) 5306 if keys 5307 keys = keys.dup 5308 keys['in'] = target 5309 else 5310 keys = {'in'=>target} 5311 end 5312 #tk_call 'grid', epath, *hash_kv(keys) 5313 TkGrid.configure(self, keys) 5314 self 5315 end 5316 5317 def grid_anchor(anchor=None) 5318 if anchor == None 5319 TkGrid.anchor(self) 5320 else 5321 TkGrid.anchor(self, anchor) 5322 self 5323 end 5324 end 5325 5326 def grid_forget 5327 #tk_call('grid', 'forget', epath) 5328 TkGrid.forget(self) 5329 self 5330 end 5331 alias ungrid grid_forget 5332 5333 def grid_bbox(*args) 5334 #list(tk_call('grid', 'bbox', epath, *args)) 5335 TkGrid.bbox(self, *args) 5336 end 5337 5338 def grid_config(slot, value=None) 5339 #if slot.kind_of? Hash 5340 # tk_call 'grid', 'configure', epath, *hash_kv(slot) 5341 #else 5342 # tk_call 'grid', 'configure', epath, "-#{slot}", value 5343 #end 5344 if slot.kind_of? Hash 5345 TkGrid.configure(self, slot) 5346 else 5347 TkGrid.configure(self, slot=>value) 5348 end 5349 end 5350 alias grid_configure grid_config 5351 5352 def grid_columnconfig(index, keys) 5353 #tk_call('grid', 'columnconfigure', epath, index, *hash_kv(keys)) 5354 TkGrid.columnconfigure(self, index, keys) 5355 end 5356 alias grid_columnconfigure grid_columnconfig 5357 5358 def grid_rowconfig(index, keys) 5359 #tk_call('grid', 'rowconfigure', epath, index, *hash_kv(keys)) 5360 TkGrid.rowconfigure(self, index, keys) 5361 end 5362 alias grid_rowconfigure grid_rowconfig 5363 5364 def grid_columnconfiginfo(index, slot=nil) 5365 #if slot 5366 # tk_call('grid', 'columnconfigure', epath, index, "-#{slot}").to_i 5367 #else 5368 # ilist = list(tk_call('grid', 'columnconfigure', epath, index)) 5369 # info = {} 5370 # while key = ilist.shift 5371 # info[key[1..-1]] = ilist.shift 5372 # end 5373 # info 5374 #end 5375 TkGrid.columnconfiginfo(self, index, slot) 5376 end 5377 5378 def grid_rowconfiginfo(index, slot=nil) 5379 #if slot 5380 # tk_call('grid', 'rowconfigure', epath, index, "-#{slot}").to_i 5381 #else 5382 # ilist = list(tk_call('grid', 'rowconfigure', epath, index)) 5383 # info = {} 5384 # while key = ilist.shift 5385 # info[key[1..-1]] = ilist.shift 5386 # end 5387 # info 5388 #end 5389 TkGrid.rowconfiginfo(self, index, slot) 5390 end 5391 5392 def grid_column(index, keys=nil) 5393 if keys.kind_of?(Hash) 5394 grid_columnconfigure(index, keys) 5395 else 5396 grid_columnconfiginfo(index, keys) 5397 end 5398 end 5399 5400 def grid_row(index, keys=nil) 5401 if keys.kind_of?(Hash) 5402 grid_rowconfigure(index, keys) 5403 else 5404 grid_rowconfiginfo(index, keys) 5405 end 5406 end 5407 5408 def grid_info() 5409 #list(tk_call('grid', 'info', epath)) 5410 TkGrid.info(self) 5411 end 5412 5413 def grid_location(x, y) 5414 #list(tk_call('grid', 'location', epath, x, y)) 5415 TkGrid.location(self, x, y) 5416 end 5417 5418 def grid_propagate(mode=None) 5419 #if mode == None 5420 # bool(tk_call('grid', 'propagate', epath)) 5421 #else 5422 # tk_call('grid', 'propagate', epath, mode) 5423 # self 5424 #end 5425 if mode == None 5426 TkGrid.propagate(self) 5427 else 5428 TkGrid.propagate(self, mode) 5429 self 5430 end 5431 end 5432 5433 def grid_remove() 5434 #tk_call 'grid', 'remove', epath 5435 TkGrid.remove(self) 5436 self 5437 end 5438 5439 def grid_size() 5440 #list(tk_call('grid', 'size', epath)) 5441 TkGrid.size(self) 5442 end 5443 5444 def grid_slaves(keys = nil) 5445 #list(tk_call('grid', 'slaves', epath, *hash_kv(args))) 5446 TkGrid.slaves(self, keys) 5447 end 5448 5449 def place(keys) 5450 #tk_call 'place', epath, *hash_kv(keys) 5451 TkPlace.configure(self, keys) 5452 self 5453 end 5454 5455 def place_in(target, keys = nil) 5456 if keys 5457 keys = keys.dup 5458 keys['in'] = target 5459 else 5460 keys = {'in'=>target} 5461 end 5462 #tk_call 'place', epath, *hash_kv(keys) 5463 TkPlace.configure(self, keys) 5464 self 5465 end 5466 5467 def place_forget 5468 #tk_call 'place', 'forget', epath 5469 TkPlace.forget(self) 5470 self 5471 end 5472 alias unplace place_forget 5473 5474 def place_config(slot, value=None) 5475 #if slot.kind_of? Hash 5476 # tk_call 'place', 'configure', epath, *hash_kv(slot) 5477 #else 5478 # tk_call 'place', 'configure', epath, "-#{slot}", value 5479 #end 5480 TkPlace.configure(self, slot, value) 5481 end 5482 alias place_configure place_config 5483 5484 def place_configinfo(slot = nil) 5485 # for >= Tk8.4a2 ? 5486 #if slot 5487 # conf = tk_split_list(tk_call('place', 'configure', epath, "-#{slot}") ) 5488 # conf[0] = conf[0][1..-1] 5489 # conf 5490 #else 5491 # tk_split_simplelist(tk_call('place', 5492 # 'configure', epath)).collect{|conflist| 5493 # conf = tk_split_simplelist(conflist) 5494 # conf[0] = conf[0][1..-1] 5495 # conf 5496 # } 5497 #end 5498 TkPlace.configinfo(self, slot) 5499 end 5500 5501 def place_info() 5502 #ilist = list(tk_call('place', 'info', epath)) 5503 #info = {} 5504 #while key = ilist.shift 5505 # info[key[1..-1]] = ilist.shift 5506 #end 5507 #return info 5508 TkPlace.info(self) 5509 end 5510 5511 def place_slaves() 5512 #list(tk_call('place', 'slaves', epath)) 5513 TkPlace.slaves(self) 5514 end 5515 5516 def set_focus(force=false) 5517 if force 5518 tk_call_without_enc('focus', '-force', path) 5519 else 5520 tk_call_without_enc('focus', path) 5521 end 5522 self 5523 end 5524 alias focus set_focus 5525 5526 def grab(opt = nil) 5527 unless opt 5528 tk_call_without_enc('grab', 'set', path) 5529 return self 5530 end 5531 5532 case opt 5533 when 'set', :set 5534 tk_call_without_enc('grab', 'set', path) 5535 return self 5536 when 'global', :global 5537 #return(tk_call('grab', 'set', '-global', path)) 5538 tk_call_without_enc('grab', 'set', '-global', path) 5539 return self 5540 when 'release', :release 5541 #return tk_call('grab', 'release', path) 5542 tk_call_without_enc('grab', 'release', path) 5543 return self 5544 when 'current', :current 5545 return window(tk_call_without_enc('grab', 'current', path)) 5546 when 'status', :status 5547 return tk_call_without_enc('grab', 'status', path) 5548 else 5549 return tk_call_without_enc('grab', opt, path) 5550 end 5551 end 5552 5553 def grab_current 5554 grab('current') 5555 end 5556 alias current_grab grab_current 5557 def grab_release 5558 grab('release') 5559 end 5560 alias release_grab grab_release 5561 def grab_set 5562 grab('set') 5563 end 5564 alias set_grab grab_set 5565 def grab_set_global 5566 grab('global') 5567 end 5568 alias set_global_grab grab_set_global 5569 def grab_status 5570 grab('status') 5571 end 5572 5573 def lower(below=None) 5574 # below = below.epath if below.kind_of?(TkObject) 5575 below = _epath(below) 5576 tk_call 'lower', epath, below 5577 self 5578 end 5579 alias lower_window lower 5580 def raise(above=None) 5581 #above = above.epath if above.kind_of?(TkObject) 5582 above = _epath(above) 5583 tk_call 'raise', epath, above 5584 self 5585 end 5586 alias raise_window raise 5587 5588 def command(cmd=nil, &b) 5589 if cmd 5590 configure_cmd('command', cmd) 5591 elsif b 5592 configure_cmd('command', Proc.new(&b)) 5593 else 5594 cget('command') 5595 end 5596 end 5597 5598 def colormodel(model=None) 5599 tk_call('tk', 'colormodel', path, model) 5600 self 5601 end 5602 5603 def caret(keys=nil) 5604 TkXIM.caret(path, keys) 5605 end 5606 5607 def destroy 5608 super 5609 children = [] 5610 rexp = /^#{self.path}\.[^.]+$/ 5611 TkCore::INTERP.tk_windows.each{|path, obj| 5612 children << [path, obj] if path =~ rexp 5613 } 5614 if defined?(@cmdtbl) 5615 for id in @cmdtbl 5616 uninstall_cmd id 5617 end 5618 end 5619 5620 children.each{|path, obj| 5621 obj.instance_eval{ 5622 if defined?(@cmdtbl) 5623 for id in @cmdtbl 5624 uninstall_cmd id 5625 end 5626 end 5627 } 5628 TkCore::INTERP.tk_windows.delete(path) 5629 } 5630 5631 begin 5632 tk_call_without_enc('destroy', epath) 5633 rescue 5634 end 5635 uninstall_win 5636 end 5637 5638 def wait_visibility(on_thread = true) 5639 if $SAFE >= 4 5640 fail SecurityError, "can't wait visibility at $SAFE >= 4" 5641 end 5642 on_thread &= (Thread.list.size != 1) 5643 if on_thread 5644 INTERP._thread_tkwait('visibility', path) 5645 else 5646 INTERP._invoke('tkwait', 'visibility', path) 5647 end 5648 end 5649 def eventloop_wait_visibility 5650 wait_visibility(false) 5651 end 5652 def thread_wait_visibility 5653 wait_visibility(true) 5654 end 5655 alias wait wait_visibility 5656 alias tkwait wait_visibility 5657 alias eventloop_wait eventloop_wait_visibility 5658 alias eventloop_tkwait eventloop_wait_visibility 5659 alias eventloop_tkwait_visibility eventloop_wait_visibility 5660 alias thread_wait thread_wait_visibility 5661 alias thread_tkwait thread_wait_visibility 5662 alias thread_tkwait_visibility thread_wait_visibility 5663 5664 def wait_destroy(on_thread = true) 5665 if $SAFE >= 4 5666 fail SecurityError, "can't wait destroy at $SAFE >= 4" 5667 end 5668 on_thread &= (Thread.list.size != 1) 5669 if on_thread 5670 INTERP._thread_tkwait('window', epath) 5671 else 5672 INTERP._invoke('tkwait', 'window', epath) 5673 end 5674 end 5675 alias wait_window wait_destroy 5676 def eventloop_wait_destroy 5677 wait_destroy(false) 5678 end 5679 alias eventloop_wait_window eventloop_wait_destroy 5680 def thread_wait_destroy 5681 wait_destroy(true) 5682 end 5683 alias thread_wait_window thread_wait_destroy 5684 5685 alias tkwait_destroy wait_destroy 5686 alias tkwait_window wait_destroy 5687 5688 alias eventloop_tkwait_destroy eventloop_wait_destroy 5689 alias eventloop_tkwait_window eventloop_wait_destroy 5690 5691 alias thread_tkwait_destroy thread_wait_destroy 5692 alias thread_tkwait_window thread_wait_destroy 5693 5694 def bindtags(taglist=nil) 5695 if taglist 5696 fail ArgumentError, "taglist must be Array" unless taglist.kind_of? Array 5697 tk_call('bindtags', path, taglist) 5698 taglist 5699 else 5700 list(tk_call('bindtags', path)).collect{|tag| 5701 if tag.kind_of?(String) 5702 if cls = WidgetClassNames[tag] 5703 cls 5704 elsif btag = TkBindTag.id2obj(tag) 5705 btag 5706 else 5707 tag 5708 end 5709 else 5710 tag 5711 end 5712 } 5713 end 5714 end 5715 5716 def bindtags=(taglist) 5717 bindtags(taglist) 5718 taglist 5719 end 5720 5721 def bindtags_shift 5722 taglist = bindtags 5723 tag = taglist.shift 5724 bindtags(taglist) 5725 tag 5726 end 5727 5728 def bindtags_unshift(tag) 5729 bindtags(bindtags().unshift(tag)) 5730 end 5731end 5732TkWidget = TkWindow 5733 5734# freeze core modules 5735#TclTkLib.freeze 5736#TclTkIp.freeze 5737#TkUtil.freeze 5738#TkKernel.freeze 5739#TkComm.freeze 5740#TkComm::Event.freeze 5741#TkCore.freeze 5742#Tk.freeze 5743 5744module Tk 5745 RELEASE_DATE = '2010-06-03'.freeze 5746 5747 autoload :AUTO_PATH, 'tk/variable' 5748 autoload :TCL_PACKAGE_PATH, 'tk/variable' 5749 autoload :PACKAGE_PATH, 'tk/variable' 5750 autoload :TCL_LIBRARY_PATH, 'tk/variable' 5751 autoload :LIBRARY_PATH, 'tk/variable' 5752 autoload :TCL_PRECISION, 'tk/variable' 5753end 5754 5755# call setup script for Tk extension libraries (base configuration) 5756begin 5757 require 'tkextlib/version.rb' 5758 require 'tkextlib/setup.rb' 5759rescue LoadError 5760 # ignore 5761end 5762