1# 2# treeview widget 3# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) 4# 5require 'tk' 6require 'tkextlib/tile.rb' 7 8module Tk 9 module Tile 10 class Treeview < TkWindow 11 end 12 end 13end 14 15module Tk::Tile::TreeviewConfig 16 include TkItemConfigMethod 17 18 def __item_configinfo_struct(id) 19 # maybe need to override 20 {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, 21 :default_value=>nil, :current_value=>1} 22 end 23 private :__item_configinfo_struct 24 25 def __itemconfiginfo_core(tagOrId, slot = nil) 26 if TkComm::GET_CONFIGINFO_AS_ARRAY 27 if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) 28 fontkey = $2 29 return [slot.to_s, tagfontobj(tagid(tagOrId), fontkey)] 30 else 31 if slot 32 slot = slot.to_s 33 34 alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot} 35 if real_name 36 slot = real_name.to_s 37 end 38 39 case slot 40 when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/ 41 begin 42 # On tile-0.7.{2-8}, 'state' options has no '-' at its head. 43 val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << slot)) 44 rescue 45 # Maybe, 'state' option has '-' in future. 46 val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 47 end 48 return [slot, val] 49 50 when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ 51 method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] 52 optval = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 53 begin 54 val = method.call(tagOrId, optval) 55 rescue => e 56 warn("Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG 57 val = optval 58 end 59 return [slot, val] 60 61 when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/ 62 method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] 63 return [slot, self.__send__(method, tagOrId)] 64 65 when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ 66 begin 67 val = number(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) 68 rescue 69 val = nil 70 end 71 return [slot, val] 72 73 when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ 74 val = num_or_str(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) 75 return [slot, val] 76 77 when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ 78 begin 79 val = bool(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) 80 rescue 81 val = nil 82 end 83 return [slot, val] 84 85 when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ 86 val = simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) 87 return [slot, val] 88 89 when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ 90 val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 91 if val =~ /^[0-9]/ 92 return [slot, list(val)] 93 else 94 return [slot, val] 95 end 96 97 when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ 98 val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 99 return [slot, val] 100 101 when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ 102 val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 103 if val.empty? 104 return [slot, nil] 105 else 106 return [slot, TkVarAccess.new(val)] 107 end 108 109 else 110 val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 111 if val.index('{') 112 return [slot, tk_split_list(val)] 113 else 114 return [slot, tk_tcl2ruby(val)] 115 end 116 end 117 118 else # ! slot 119 ret = Hash[*(tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false))].to_a.collect{|conf| 120 conf[0] = conf[0][1..-1] if conf[0][0] == ?- 121 case conf[0] 122 when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ 123 method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[conf[0]] 124 optval = conf[1] 125 begin 126 val = method.call(tagOrId, optval) 127 rescue => e 128 warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG 129 val = optval 130 end 131 conf[1] = val 132 133 when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ 134 # do nothing 135 136 when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ 137 begin 138 conf[1] = number(conf[1]) 139 rescue 140 conf[1] = nil 141 end 142 143 when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ 144 conf[1] = num_or_str(conf[1]) 145 146 when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ 147 begin 148 conf[1] = bool(conf[1]) 149 rescue 150 conf[1] = nil 151 end 152 153 when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ 154 conf[1] = simplelist(conf[1]) 155 156 when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ 157 if conf[1] =~ /^[0-9]/ 158 conf[1] = list(conf[1]) 159 end 160 161 when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ 162 if conf[1].empty? 163 conf[1] = nil 164 else 165 conf[1] = TkVarAccess.new(conf[1]) 166 end 167 168 else 169 if conf[1].index('{') 170 conf[1] = tk_split_list(conf[1]) 171 else 172 conf[1] = tk_tcl2ruby(conf[1]) 173 end 174 end 175 176 conf 177 } 178 179 __item_font_optkeys(tagid(tagOrId)).each{|optkey| 180 optkey = optkey.to_s 181 fontconf = ret.assoc(optkey) 182 if fontconf 183 ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/} 184 fontconf[1] = tagfontobj(tagid(tagOrId), optkey) 185 ret.push(fontconf) 186 end 187 } 188 189 __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method| 190 ret << [optkey.to_s, self.__send__(method, tagOrId)] 191 } 192 193 ret 194 end 195 end 196 197 else # ! TkComm::GET_CONFIGINFO_AS_ARRAY 198 if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) 199 fontkey = $2 200 return {slot.to_s => tagfontobj(tagid(tagOrId), fontkey)} 201 else 202 if slot 203 slot = slot.to_s 204 205 alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot} 206 if real_name 207 slot = real_name.to_s 208 end 209 210 case slot 211 when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/ 212 begin 213 # On tile-0.7.{2-8}, 'state' option has no '-' at its head. 214 val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << slot)) 215 rescue 216 # Maybe, 'state' option has '-' in future. 217 val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 218 end 219 return {slot => val} 220 221 when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ 222 method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] 223 optval = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 224 begin 225 val = method.call(tagOrId, optval) 226 rescue => e 227 warn("Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG 228 val = optval 229 end 230 return {slot => val} 231 232 when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/ 233 method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot] 234 return {slot => self.__send__(method, tagOrId)} 235 236 when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ 237 begin 238 val = number(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) 239 rescue 240 val = nil 241 end 242 return {slot => val} 243 244 when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ 245 val = num_or_str(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) 246 return {slot => val} 247 248 when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ 249 begin 250 val = bool(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) 251 rescue 252 val = nil 253 end 254 return {slot => val} 255 256 when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ 257 val = simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))) 258 return {slot => val} 259 260 when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ 261 val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 262 if val =~ /^[0-9]/ 263 return {slot => list(val)} 264 else 265 return {slot => val} 266 end 267 268 when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ 269 val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 270 return {slot => val} 271 272 when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ 273 val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 274 if val.empty? 275 return {slot => nil} 276 else 277 return {slot => TkVarAccess.new(val)} 278 end 279 280 else 281 val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")) 282 if val.index('{') 283 return {slot => tk_split_list(val)} 284 else 285 return {slot => tk_tcl2ruby(val)} 286 end 287 end 288 289 else # ! slot 290 ret = {} 291 ret = Hash[*(tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false))].to_a.collect{|conf| 292 conf[0] = conf[0][1..-1] if conf[0][0] == ?- 293 294 optkey = conf[0] 295 case optkey 296 when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ 297 method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey] 298 optval = conf[1] 299 begin 300 val = method.call(tagOrId, optval) 301 rescue => e 302 warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG 303 val = optval 304 end 305 conf[1] = val 306 307 when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/ 308 # do nothing 309 310 when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/ 311 begin 312 conf[1] = number(conf[1]) 313 rescue 314 conf[1] = nil 315 end 316 317 when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/ 318 conf[1] = num_or_str(conf[1]) 319 320 when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/ 321 begin 322 conf[1] = bool(conf[1]) 323 rescue 324 conf[1] = nil 325 end 326 327 when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/ 328 conf[1] = simplelist(conf[1]) 329 330 when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/ 331 if conf[1] =~ /^[0-9]/ 332 conf[1] = list(conf[1]) 333 end 334 335 when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/ 336 if conf[1].empty? 337 conf[1] = nil 338 else 339 conf[1] = TkVarAccess.new(conf[1]) 340 end 341 342 else 343 if conf[1].index('{') 344 return [slot, tk_split_list(conf[1])] 345 else 346 return [slot, tk_tcl2ruby(conf[1])] 347 end 348 end 349 350 ret[conf[0]] = conf[1] 351 } 352 353 __item_font_optkeys(tagid(tagOrId)).each{|optkey| 354 optkey = optkey.to_s 355 fontconf = ret[optkey] 356 if fontconf.kind_of?(Array) 357 ret.delete(optkey) 358 ret.delete('latin' << optkey) 359 ret.delete('ascii' << optkey) 360 ret.delete('kanji' << optkey) 361 fontconf[1] = tagfontobj(tagid(tagOrId), optkey) 362 ret[optkey] = fontconf 363 end 364 } 365 366 __item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method| 367 ret[optkey.to_s] = self.__send__(method, tagOrId) 368 } 369 370 ret 371 end 372 end 373 end 374 end 375 376 ################### 377 378 def __item_cget_cmd(id) 379 [self.path, *id] 380 end 381 private :__item_cget_cmd 382 383 def __item_config_cmd(id) 384 [self.path, *id] 385 end 386 private :__item_config_cmd 387 388 def __item_numstrval_optkeys(id) 389 case id[0] 390 when :item, 'item' 391 ['width'] 392 when :column, 'column' 393 super(id[1]) + ['minwidth'] 394 when :tag, 'tag' 395 super(id[1]) 396 when :heading, 'heading' 397 super(id[1]) 398 else 399 super(id[1]) 400 end 401 end 402 private :__item_numstrval_optkeys 403 404 def __item_strval_optkeys(id) 405 case id[0] 406 when :item, 'item' 407 super(id) + ['id'] 408 when :column, 'column' 409 super(id[1]) 410 when :tag, 'tag' 411 super(id[1]) 412 when :heading, 'heading' 413 super(id[1]) 414 else 415 super(id[1]) 416 end 417 end 418 private :__item_strval_optkeys 419 420 def __item_boolval_optkeys(id) 421 case id[0] 422 when :item, 'item' 423 ['open'] 424 when :column, 'column' 425 super(id[1]) + ['stretch'] 426 when :tag, 'tag' 427 super(id[1]) 428 when :heading, 'heading' 429 super(id[1]) 430 end 431 end 432 private :__item_boolval_optkeys 433 434 def __item_listval_optkeys(id) 435 case id[0] 436 when :item, 'item' 437 ['values'] 438 when :column, 'column' 439 [] 440 when :heading, 'heading' 441 [] 442 else 443 [] 444 end 445 end 446 private :__item_listval_optkeys 447 448 def __item_val2ruby_optkeys(id) 449 case id[0] 450 when :item, 'item' 451 { 452 'tags'=>proc{|arg_id, val| 453 simplelist(val).collect{|tag| 454 Tk::Tile::Treeview::Tag.id2obj(self, tag) 455 } 456 } 457 } 458 when :column, 'column' 459 {} 460 when :heading, 'heading' 461 {} 462 else 463 {} 464 end 465 end 466 private :__item_val2ruby_optkeys 467 468 def __tile_specific_item_optkeys(id) 469 case id[0] 470 when :item, 'item' 471 [] 472 when :column, 'column' 473 [] 474 when :heading, 'heading' 475 ['state'] # On tile-0.7.{2-8}, 'state' options has no '-' at its head. 476 else 477 [] 478 end 479 end 480 private :__item_val2ruby_optkeys 481 482 def itemconfiginfo(tagOrId, slot = nil) 483 __itemconfiginfo_core(tagOrId, slot) 484 end 485 486 def current_itemconfiginfo(tagOrId, slot = nil) 487 if TkComm::GET_CONFIGINFO_AS_ARRAY 488 if slot 489 org_slot = slot 490 begin 491 conf = __itemconfiginfo_core(tagOrId, slot) 492 if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ 493 || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) 494 return {conf[0] => conf[-1]} 495 end 496 slot = conf[__item_configinfo_struct(tagid(tagOrId))[:alias]] 497 end while(org_slot != slot) 498 fail RuntimeError, 499 "there is a configure alias loop about '#{org_slot}'" 500 else 501 ret = {} 502 __itemconfiginfo_core(tagOrId).each{|conf| 503 if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \ 504 || conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 ) 505 ret[conf[0]] = conf[-1] 506 end 507 } 508 ret 509 end 510 else # ! TkComm::GET_CONFIGINFO_AS_ARRAY 511 ret = {} 512 __itemconfiginfo_core(tagOrId, slot).each{|key, conf| 513 ret[key] = conf[-1] if conf.kind_of?(Array) 514 } 515 ret 516 end 517 end 518 519 alias __itemcget_tkstring itemcget_tkstring 520 alias __itemcget itemcget 521 alias __itemcget_strict itemcget_strict 522 alias __itemconfigure itemconfigure 523 alias __itemconfiginfo itemconfiginfo 524 alias __current_itemconfiginfo current_itemconfiginfo 525 526 private :__itemcget_tkstring, :__itemcget, :__itemcget_strict 527 private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo 528 529 # Treeview Item 530 def itemcget_tkstring(tagOrId, option) 531 __itemcget_tkstring([:item, tagOrId], option) 532 end 533 def itemcget(tagOrId, option) 534 __itemcget([:item, tagOrId], option) 535 end 536 def itemcget_strict(tagOrId, option) 537 __itemcget_strict([:item, tagOrId], option) 538 end 539 def itemconfigure(tagOrId, slot, value=None) 540 __itemconfigure([:item, tagOrId], slot, value) 541 end 542 def itemconfiginfo(tagOrId, slot=nil) 543 __itemconfiginfo([:item, tagOrId], slot) 544 end 545 def current_itemconfiginfo(tagOrId, slot=nil) 546 __current_itemconfiginfo([:item, tagOrId], slot) 547 end 548 549 # Treeview Column 550 def columncget_tkstring(tagOrId, option) 551 __itemcget_tkstring([:column, tagOrId], option) 552 end 553 def columncget(tagOrId, option) 554 __itemcget([:column, tagOrId], option) 555 end 556 def columncget_strict(tagOrId, option) 557 __itemcget_strict([:column, tagOrId], option) 558 end 559 def columnconfigure(tagOrId, slot, value=None) 560 __itemconfigure([:column, tagOrId], slot, value) 561 end 562 def columnconfiginfo(tagOrId, slot=nil) 563 __itemconfiginfo([:column, tagOrId], slot) 564 end 565 def current_columnconfiginfo(tagOrId, slot=nil) 566 __current_itemconfiginfo([:column, tagOrId], slot) 567 end 568 alias column_cget_tkstring columncget_tkstring 569 alias column_cget columncget 570 alias column_cget_strict columncget_strict 571 alias column_configure columnconfigure 572 alias column_configinfo columnconfiginfo 573 alias current_column_configinfo current_columnconfiginfo 574 575 # Treeview Heading 576 def headingcget_tkstring(tagOrId, option) 577 if __tile_specific_item_optkeys([:heading, tagOrId]).index(option.to_s) 578 begin 579 # On tile-0.7.{2-8}, 'state' options has no '-' at its head. 580 tk_call(*(__item_cget_cmd([:heading, tagOrId]) << option.to_s)) 581 rescue 582 # Maybe, 'state' option has '-' in future. 583 tk_call(*(__item_cget_cmd([:heading, tagOrId]) << "-#{option}")) 584 end 585 else 586 __itemcget_tkstring([:heading, tagOrId], option) 587 end 588 end 589 def headingcget_strict(tagOrId, option) 590 if __tile_specific_item_optkeys([:heading, tagOrId]).index(option.to_s) 591 begin 592 # On tile-0.7.{2-8}, 'state' options has no '-' at its head. 593 tk_call(*(__item_cget_cmd([:heading, tagOrId]) << option.to_s)) 594 rescue 595 # Maybe, 'state' option has '-' in future. 596 tk_call(*(__item_cget_cmd([:heading, tagOrId]) << "-#{option}")) 597 end 598 else 599 __itemcget_strict([:heading, tagOrId], option) 600 end 601 end 602 def headingcget(tagOrId, option) 603 unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ 604 headingcget_strict(tagOrId, option) 605 else 606 begin 607 headingcget_strict(tagOrId, option) 608 rescue => e 609 begin 610 if current_headingconfiginfo(tagOrId).has_key?(option.to_s) 611 # not tag error & option is known -> error on known option 612 fail e 613 else 614 # not tag error & option is unknown 615 nil 616 end 617 rescue 618 fail e # tag error 619 end 620 end 621 end 622 end 623 def headingconfigure(tagOrId, slot, value=None) 624 if slot.kind_of?(Hash) 625 slot = _symbolkey2str(slot) 626 sp_kv = [] 627 __tile_specific_item_optkeys([:heading, tagOrId]).each{|k| 628 sp_kv << k << _get_eval_string(slot.delete(k)) if slot.has_key?(k) 629 } 630 tk_call(*(__item_config_cmd([:heading, tagOrId]).concat(sp_kv))) 631 tk_call(*(__item_config_cmd([:heading, tagOrId]).concat(hash_kv(slot)))) 632 elsif __tile_specific_item_optkeys([:heading, tagOrId]).index(slot.to_s) 633 begin 634 # On tile-0.7.{2-8}, 'state' options has no '-' at its head. 635 tk_call(*(__item_cget_cmd([:heading, tagOrId]) << slot.to_s << value)) 636 rescue 637 # Maybe, 'state' option has '-' in future. 638 tk_call(*(__item_cget_cmd([:heading, tagOrId]) << "-#{slot}" << value)) 639 end 640 else 641 __itemconfigure([:heading, tagOrId], slot, value) 642 end 643 self 644 end 645 def headingconfiginfo(tagOrId, slot=nil) 646 __itemconfiginfo([:heading, tagOrId], slot) 647 end 648 def current_headingconfiginfo(tagOrId, slot=nil) 649 __current_itemconfiginfo([:heading, tagOrId], slot) 650 end 651 alias heading_cget_tkstring headingcget_tkstring 652 alias heading_cget headingcget 653 alias heading_cget_strict headingcget_strict 654 alias heading_configure headingconfigure 655 alias heading_configinfo headingconfiginfo 656 alias current_heading_configinfo current_headingconfiginfo 657 658 # Treeview Tag 659 def tagcget_tkstring(tagOrId, option) 660 __itemcget_tkstring([:tag, :configure, tagOrId], option) 661 end 662 def tagcget(tagOrId, option) 663 __itemcget([:tag, :configure, tagOrId], option) 664 end 665 def tagcget_strict(tagOrId, option) 666 __itemcget_strict([:tag, :configure, tagOrId], option) 667 end 668 def tagconfigure(tagOrId, slot, value=None) 669 __itemconfigure([:tag, :configure, tagOrId], slot, value) 670 end 671 def tagconfiginfo(tagOrId, slot=nil) 672 __itemconfiginfo([:tag, :configure, tagOrId], slot) 673 end 674 def current_tagconfiginfo(tagOrId, slot=nil) 675 __current_itemconfiginfo([:tag, :configure, tagOrId], slot) 676 end 677 alias tag_cget_tkstring tagcget_tkstring 678 alias tag_cget tagcget 679 alias tag_cget_strict tagcget_strict 680 alias tag_configure tagconfigure 681 alias tag_configinfo tagconfiginfo 682 alias current_tag_configinfo current_tagconfiginfo 683end 684 685######################## 686 687class Tk::Tile::Treeview::Item < TkObject 688 ItemID_TBL = TkCore::INTERP.create_table 689 690 TkCore::INTERP.init_ip_env{ 691 Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{ 692 Tk::Tile::Treeview::Item::ItemID_TBL.clear 693 } 694 } 695 696 def self.id2obj(tree, id) 697 tpath = tree.path 698 Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{ 699 if Tk::Tile::Treeview::Item::ItemID_TBL[tpath] 700 (Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id])? \ 701 Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id]: id 702 else 703 id 704 end 705 } 706 end 707 708 def self.assign(tree, id) 709 tpath = tree.path 710 obj = nil 711 Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{ 712 if Tk::Tile::Treeview::Item::ItemID_TBL[tpath] && 713 Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id] 714 return Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id] 715 end 716 717 obj = self.allocate 718 obj.instance_eval{ 719 @parent = @t = tree 720 @tpath = tpath 721 @path = @id = id 722 } 723 Tk::Tile::Treeview::Item::ItemID_TBL[tpath] ||= {} 724 Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id] = obj 725 } 726 obj 727 end 728 729 def _insert_item(tree, parent_item, idx, keys={}) 730 keys = _symbolkey2str(keys) 731 id = keys.delete('id') 732 if id 733 num_or_str(tk_call(tree, 'insert', 734 parent_item, idx, '-id', id, *hash_kv(keys))) 735 else 736 num_or_str(tk_call(tree, 'insert', parent_item, idx, *hash_kv(keys))) 737 end 738 end 739 private :_insert_item 740 741 def initialize(tree, parent_item = '', idx = 'end', keys = {}) 742 if parent_item.kind_of?(Hash) 743 keys = parent_item 744 idx = 'end' 745 parent_item = '' 746 elsif idx.kind_of?(Hash) 747 keys = idx 748 idx = 'end' 749 end 750 751 @parent = @t = tree 752 @tpath = tree.path 753 @path = @id = _insert_item(@t, parent_item, idx, keys) 754 Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{ 755 ItemID_TBL[@tpath] = {} unless ItemID_TBL[@tpath] 756 ItemID_TBL[@tpath][@id] = self 757 } 758 end 759 def id 760 @id 761 end 762 763 def cget_tkstring(option) 764 @t.itemcget_tkstring(@id, option) 765 end 766 def cget(option) 767 @t.itemcget(@id, option) 768 end 769 def cget_strict(option) 770 @t.itemcget_strict(@id, option) 771 end 772 773 def configure(key, value=None) 774 @t.itemconfigure(@id, key, value) 775 self 776 end 777 778 def configinfo(key=nil) 779 @t.itemconfiginfo(@id, key) 780 end 781 782 def current_configinfo(key=nil) 783 @t.current_itemconfiginfo(@id, key) 784 end 785 786 def open? 787 cget('open') 788 end 789 def open 790 configure('open', true) 791 self 792 end 793 def close 794 configure('open', false) 795 self 796 end 797 798 def tag_has?(tag) 799 @t.tag_has?(tag, @id) 800 end 801 alias has_tag? tag_has? 802 803 def bbox(column=None) 804 @t.bbox(@id, column) 805 end 806 807 def children 808 @t.children(@id) 809 end 810 def set_children(*items) 811 @t.set_children(@id, *items) 812 self 813 end 814 815 def delete 816 @t.delete(@id) 817 self 818 end 819 820 def detach 821 @t.detach(@id) 822 self 823 end 824 825 def exist? 826 @t.exist?(@id) 827 end 828 829 def focus 830 @t.focus_item(@id) 831 end 832 833 def index 834 @t.index(@id) 835 end 836 837 def insert(idx='end', keys={}) 838 @t.insert(@id, idx, keys) 839 end 840 841 def move(parent, idx) 842 @t.move(@id, parent, idx) 843 self 844 end 845 846 def next_item 847 @t.next_item(@id) 848 end 849 850 def parent_item 851 @t.parent_item(@id) 852 end 853 854 def prev_item 855 @t.prev_item(@id) 856 end 857 858 def see 859 @t.see(@id) 860 self 861 end 862 863 def selection_add 864 @t.selection_add(@id) 865 self 866 end 867 868 def selection_remove 869 @t.selection_remove(@id) 870 self 871 end 872 873 def selection_set 874 @t.selection_set(@id) 875 self 876 end 877 878 def selection_toggle 879 @t.selection_toggle(@id) 880 self 881 end 882 883 def get_directory 884 @t.get_directory(@id) 885 end 886 alias get_dictionary get_directory 887 888 def get(col) 889 @t.get(@id, col) 890 end 891 892 def set(col, value) 893 @t.set(@id, col, value) 894 end 895end 896 897######################## 898 899class Tk::Tile::Treeview::Root < Tk::Tile::Treeview::Item 900 def self.new(tree, keys = {}) 901 tpath = tree.path 902 obj = nil 903 Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{ 904 if Tk::Tile::Treeview::Item::ItemID_TBL[tpath] && 905 Tk::Tile::Treeview::Item::ItemID_TBL[tpath][''] 906 obj = Tk::Tile::Treeview::Item::ItemID_TBL[tpath][''] 907 else 908 #super(tree, keys) 909 (obj = self.allocate).instance_eval{ 910 @parent = @t = tree 911 @tpath = tree.path 912 @path = @id = '' 913 Tk::Tile::Treeview::Item::ItemID_TBL[@tpath] ||= {} 914 Tk::Tile::Treeview::Item::ItemID_TBL[@tpath][@id] = self 915 } 916 end 917 } 918 obj.configure(keys) if keys && ! keys.empty? 919 obj 920 end 921 922 def initialize(tree, keys = {}) 923 # dummy:: not called by 'new' method 924 @parent = @t = tree 925 @tpath = tree.path 926 @path = @id = '' 927 Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{ 928 Tk::Tile::Treeview::Item::ItemID_TBL[@tpath] ||= {} 929 Tk::Tile::Treeview::Item::ItemID_TBL[@tpath][@id] = self 930 } 931 end 932end 933 934######################## 935 936class Tk::Tile::Treeview::Tag < TkObject 937 include TkTreatTagFont 938 939 TagID_TBL = TkCore::INTERP.create_table 940 941 (Tag_ID = ['tile_treeview_tag'.freeze, TkUtil.untrust('00000')]).instance_eval{ 942 @mutex = Mutex.new 943 def mutex; @mutex; end 944 freeze 945 } 946 947 TkCore::INTERP.init_ip_env{ 948 Tk::Tile::Treeview::Tag::TagID_TBL.mutex.synchronize{ 949 Tk::Tile::Treeview::Tag::TagID_TBL.clear 950 } 951 } 952 953 def self.id2obj(tree, id) 954 tpath = tree.path 955 Tk::Tile::Treeview::Tag::TagID_TBL.mutex.synchronize{ 956 if Tk::Tile::Treeview::Tag::TagID_TBL[tpath] 957 (Tk::Tile::Treeview::Tag::TagID_TBL[tpath][id])? \ 958 Tk::Tile::Treeview::Tag::TagID_TBL[tpath][id]: id 959 else 960 id 961 end 962 } 963 end 964 965 def initialize(tree, keys=nil) 966 @parent = @t = tree 967 @tpath = tree.path 968 Tag_ID.mutex.synchronize{ 969 @path = @id = Tag_ID.join(TkCore::INTERP._ip_id_) 970 Tag_ID[1].succ! 971 } 972 TagID_TBL.mutex.synchronize{ 973 TagID_TBL[@tpath] = {} unless TagID_TBL[@tpath] 974 TagID_TBL[@tpath][@id] = self 975 } 976 if keys && keys != None 977 tk_call_without_enc(@tpath, 'tag', 'configure', @id, *hash_kv(keys,true)) 978 end 979 end 980 def id 981 @id 982 end 983 984 def tag_has?(item) 985 @t.tag_has?(@id, item) 986 end 987 alias added? tag_has? 988 989 def bind(seq, *args) 990 if TkComm._callback_entry?(args[0]) || !block_given? 991 cmd = args.shift 992 else 993 cmd = Proc.new 994 end 995 @t.tag_bind(@id, seq, cmd, *args) 996 self 997 end 998 999 def bind_append(seq, *args) 1000 if TkComm._callback_entry?(args[0]) || !block_given? 1001 cmd = args.shift 1002 else 1003 cmd = Proc.new 1004 end 1005 @t.tag_bind_append(@id, seq, cmd, *args) 1006 self 1007 end 1008 1009 def bind_remove(seq) 1010 @t.tag_bind_remove(@id, seq) 1011 self 1012 end 1013 1014 def bindinfo(seq=nil) 1015 @t.tag_bindinfo(@id, seq) 1016 end 1017 1018 def cget_tkstring(option) 1019 @t.tagcget_tkstring(@id, option) 1020 end 1021 def cget(option) 1022 @t.tagcget(@id, option) 1023 end 1024 def cget_strict(option) 1025 @t.tagcget_strict(@id, option) 1026 end 1027 1028 def configure(key, value=None) 1029 @t.tagconfigure(@id, key, value) 1030 self 1031 end 1032 1033 def configinfo(key=nil) 1034 @t.tagconfiginfo(@id, key) 1035 end 1036 1037 def current_configinfo(key=nil) 1038 @t.current_tagconfiginfo(@id, key) 1039 end 1040end 1041 1042######################## 1043 1044class Tk::Tile::Treeview < TkWindow 1045 include Tk::Tile::TileWidget 1046 include Scrollable 1047 1048 include Tk::Tile::TreeviewConfig 1049 1050 if Tk::Tile::USE_TTK_NAMESPACE 1051 TkCommandNames = ['::ttk::treeview'.freeze].freeze 1052 else 1053 TkCommandNames = ['::treeview'.freeze].freeze 1054 end 1055 WidgetClassName = 'Treeview'.freeze 1056 WidgetClassNames[WidgetClassName] ||= self 1057 1058 def __destroy_hook__ 1059 Tk::Tile::Treeview::Item::ItemID_TBL.mutex.synchronize{ 1060 Tk::Tile::Treeview::Item::ItemID_TBL.delete(@path) 1061 } 1062 Tk::Tile::Treeview::Tag::ItemID_TBL.mutex.synchronize{ 1063 Tk::Tile::Treeview::Tag::ItemID_TBL.delete(@path) 1064 } 1065 end 1066 1067 def self.style(*args) 1068 [self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.') 1069 end 1070 1071 def tagid(id) 1072 if id.kind_of?(Tk::Tile::Treeview::Item) || 1073 id.kind_of?(Tk::Tile::Treeview::Tag) 1074 id.id 1075 elsif id.kind_of?(Array) 1076 # size is 2 or 3 1077 id[0..-2] << _get_eval_string(id[-1]) 1078 else 1079 _get_eval_string(id) 1080 end 1081 end 1082 1083 def root 1084 Tk::Tile::Treeview::Root.new(self) 1085 end 1086 1087 def bbox(item, column=None) 1088 list(tk_send('item', 'bbox', item, column)) 1089 end 1090 1091 def children(item) 1092 simplelist(tk_send_without_enc('children', item)).collect{|id| 1093 Tk::Tile::Treeview::Item.id2obj(self, id) 1094 } 1095 end 1096 def set_children(item, *items) 1097 tk_send_without_enc('children', item, 1098 array2tk_list(items.flatten, true)) 1099 self 1100 end 1101 1102 def delete(*items) 1103 tk_send_without_enc('delete', array2tk_list(items.flatten, true)) 1104 self 1105 end 1106 1107 def detach(*items) 1108 tk_send_without_enc('detach', array2tk_list(items.flatten, true)) 1109 self 1110 end 1111 1112 def exist?(item) 1113 bool(tk_send_without_enc('exists', _get_eval_enc_str(item))) 1114 end 1115 1116 def focus_item(item = nil) 1117 if item 1118 tk_send('focus', item) 1119 item 1120 else 1121 id = tk_send('focus') 1122 (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id) 1123 end 1124 end 1125 1126 def identify(x, y) 1127 # tile-0.7.2 or previous 1128 ret = simplelist(tk_send('identify', x, y)) 1129 case ret[0] 1130 when 'heading', 'separator' 1131 ret[-1] = num_or_str(ret[-1]) 1132 when 'cell' 1133 ret[1] = Tk::Tile::Treeview::Item.id2obj(self, ret[1]) 1134 ret[-1] = num_or_str(ret[-1]) 1135 when 'item', 'row' 1136 ret[1] = Tk::Tile::Treeview::Item.id2obj(self, ret[1]) 1137 end 1138 end 1139 1140 def identify_region(x, y) 1141 tk_send('identify', 'region', x, y) 1142 end 1143 1144 def identify_item(x, y) 1145 id = tk_send('identify', 'item', x, y) 1146 (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id) 1147 end 1148 1149 def identify_element(x, y) 1150 tk_send('identify', 'element', x, y) 1151 end 1152 1153 def row_identify(x, y) 1154 id = tk_send('identify', 'row', x, y) 1155 (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id) 1156 end 1157 alias identify_row row_identify 1158 1159 def column_identify(x, y) 1160 tk_send('identify', 'column', x, y) 1161 end 1162 alias identify_column column_identify 1163 1164 def index(item) 1165 number(tk_send('index', item)) 1166 end 1167 1168 # def insert(parent, idx='end', keys={}) 1169 # keys = _symbolkey2str(keys) 1170 # id = keys.delete('id') 1171 # if id 1172 # num_or_str(tk_send('insert', parent, idx, '-id', id, *hash_kv(keys))) 1173 # else 1174 # num_or_str(tk_send('insert', parent, idx, *hash_kv(keys))) 1175 # end 1176 # end 1177 def insert(parent, idx='end', keys={}) 1178 Tk::Tile::Treeview::Item.new(self, parent, idx, keys) 1179 end 1180 1181 # def instate(spec, cmd=Proc.new) 1182 # tk_send('instate', spec, cmd) 1183 # end 1184 # def state(spec=None) 1185 # tk_send('state', spec) 1186 # end 1187 1188 def move(item, parent, idx) 1189 tk_send('move', item, parent, idx) 1190 self 1191 end 1192 1193 def next_item(item) 1194 id = tk_send('next', item) 1195 (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id) 1196 end 1197 1198 def parent_item(item) 1199 if (id = tk_send('parent', item)).empty? 1200 Tk::Tile::Treeview::Root.new(self) 1201 else 1202 Tk::Tile::Treeview::Item.id2obj(self, id) 1203 end 1204 end 1205 1206 def prev_item(item) 1207 id = tk_send('prev', item) 1208 (id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id) 1209 end 1210 1211 def see(item) 1212 tk_send('see', item) 1213 self 1214 end 1215 1216 def selection 1217 simplelist(tk_send('selection')).collect{|id| 1218 Tk::Tile::Treeview::Item.id2obj(self, id) 1219 } 1220 end 1221 alias selection_get selection 1222 1223 def selection_add(*items) 1224 tk_send('selection', 'add', array2tk_list(items.flatten, true)) 1225 self 1226 end 1227 def selection_remove(*items) 1228 tk_send('selection', 'remove', array2tk_list(items.flatten, true)) 1229 self 1230 end 1231 def selection_set(*items) 1232 tk_send('selection', 'set', array2tk_list(items.flatten, true)) 1233 self 1234 end 1235 def selection_toggle(*items) 1236 tk_send('selection', 'toggle', array2tk_list(items.flatten, true)) 1237 self 1238 end 1239 1240 def get_directory(item) 1241 # tile-0.7+ 1242 ret = [] 1243 lst = simplelist(tk_send('set', item)) 1244 until lst.empty? 1245 col = lst.shift 1246 val = lst.shift 1247 ret << [col, val] 1248 end 1249 ret 1250 end 1251 alias get_dictionary get_directory 1252 1253 def get(item, col) 1254 tk_send('set', item, col) 1255 end 1256 def set(item, col, value) 1257 tk_send('set', item, col, value) 1258 self 1259 end 1260 1261 def tag_has?(tag, item) 1262 bool(tk_send('tag', 'has', tagid(tag), tagid(item))) 1263 end 1264 def tag_has(tag) 1265 tk_split_simplelist(tk_send('tag', 'has', tagid(tag))).collect{|id| 1266 Tk::Tile::Treeview::Item.id2obj(self, id) 1267 } 1268 end 1269 1270 def tag_bind(tag, seq, *args) 1271 if TkComm._callback_entry?(args[0]) || !block_given? 1272 cmd = args.shift 1273 else 1274 cmd = Proc.new 1275 end 1276 _bind([@path, 'tag', 'bind', tag], seq, cmd, *args) 1277 self 1278 end 1279 alias tagbind tag_bind 1280 1281 def tag_bind_append(tag, seq, *args) 1282 if TkComm._callback_entry?(args[0]) || !block_given? 1283 cmd = args.shift 1284 else 1285 cmd = Proc.new 1286 end 1287 _bind_append([@path, 'tag', 'bind', tag], seq, cmd, *args) 1288 self 1289 end 1290 alias tagbind_append tag_bind_append 1291 1292 def tag_bind_remove(tag, seq) 1293 _bind_remove([@path, 'tag', 'bind', tag], seq) 1294 self 1295 end 1296 alias tagbind_remove tag_bind_remove 1297 1298 def tag_bindinfo(tag, context=nil) 1299 _bindinfo([@path, 'tag', 'bind', tag], context) 1300 end 1301 alias tagbindinfo tag_bindinfo 1302end 1303 1304#Tk.__set_toplevel_aliases__(:Ttk, Tk::Tile::Treeview, :TkTreeview) 1305Tk.__set_loaded_toplevel_aliases__('tkextlib/tile/treeview.rb', 1306 :Ttk, Tk::Tile::Treeview, :TkTreeview) 1307