1# 2# tkextlib/blt/tree.rb 3# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) 4# 5 6require 'tk' 7require 'tkextlib/blt.rb' 8 9module Tk::BLT 10 class Tree < TkObject 11 TkCommandNames = ['::blt::tree'.freeze].freeze 12 13 ################################### 14 15 class Node < TkObject 16 TreeNodeID_TBL = TkCore::INTERP.create_table 17 18 TkCore::INTERP.init_ip_env{ 19 TreeNodeID_TBL.mutex.synchronize{ TreeNodeID_TBL.clear } 20 } 21 22 def self.id2obj(tree, id) 23 tpath = tree.path 24 TreeNodeID_TBL.mutex.synchronize{ 25 if TreeNodeID_TBL[tpath] 26 if TreeNodeID_TBL[tpath][id] 27 TreeNodeID_TBL[tpath][id] 28 else 29 begin 30 # self.new(tree, nil, 'node'=>Integer(id)) 31 id = Integer(id) 32 if bool(tk_call(@tpath, 'exists', id)) 33 (obj = self.allocate).instance_eval{ 34 @parent = @tree = tree 35 @tpath = tpath 36 @path = @id = id 37 TreeNodeID_TBL[@tpath] = {} unless TreeNodeID_TBL[@tpath] 38 TreeNodeID_TBL[@tpath][@id] = self 39 } 40 obj 41 else 42 id 43 end 44 rescue 45 id 46 end 47 end 48 else 49 id 50 end 51 } 52 end 53 54 def self.new(tree, parent, keys={}) 55 keys = _symbolkey2str(keys) 56 tpath = tree.path 57 58 TreeNodeID_TBL.mutex.synchronize{ 59 TreeNodeID_TBL[tpath] ||= {} 60 if (id = keys['node']) && (obj = TreeNodeID_TBL[tpath][id]) 61 keys.delete('node') 62 tk_call(tree.path, 'move', id, parent, keys) if parent 63 return obj 64 end 65 66 (obj = self.allocate).instance_eval{ 67 initialize(tree, parent, keys) 68 TreeNodeID_TBL[tpath][@id] = self 69 } 70 obj 71 } 72 end 73 74 def initialize(tree, parent, keys={}) 75 @parent = @tree = tree 76 @tpath = @parent.path 77 78 if (id = keys['node']) && bool(tk_call(@tpath, 'exists', id)) 79 @path = @id = id 80 keys.delete('node') 81 tk_call(@tpath, 'move', @id, parent, keys) if parent 82 else 83 parent = tk_call(@tpath, 'root') unless parent 84 @path = @id = tk_call(@tpath, 'insert', parent, keys) 85 end 86 end 87 88 def id 89 @id 90 end 91 92 def apply(keys={}) 93 @tree.apply(@id, keys) 94 self 95 end 96 97 def children() 98 @tree.children(@id) 99 end 100 101 def copy(parent, keys={}) 102 @tree.copy(@id, parent, keys) 103 end 104 def copy_to(dest_tree, parent, keys={}) 105 @tree.copy_to(@id, dest_tree, parent, keys) 106 end 107 108 def degree() 109 @tree.degree(@id) 110 end 111 112 def delete() 113 @tree.delete(@id) 114 self 115 end 116 117 def depth() 118 @tree.depth(@id) 119 end 120 121 def dump() 122 @tree.dump(@id) 123 end 124 125 def dump_to_file(file) 126 @tree.dump_to_file(@id, file) 127 self 128 end 129 130 def exist?(keys={}) 131 @tree.exist?(@id, keys) 132 end 133 134 def find(keys={}) 135 @tree.find(@id, keys) 136 end 137 138 def find_child(label) 139 @tree.find_child(@id, label) 140 end 141 142 def first_child() 143 @tree.first_child(@id) 144 end 145 146 def get() 147 @tree.get(@id) 148 end 149 def get_value(key, default_val=None) 150 @tree.get_value(@id, key, default_val) 151 end 152 153 def index() 154 @tree.index(@id) 155 end 156 157 def leaf?() 158 @tree.leaf?(@id) 159 end 160 def link?() 161 @tree.link?(@id) 162 end 163 def root?() 164 @tree.root?(@id) 165 end 166 167 def keys() 168 @tree.keys(@id) 169 end 170 171 def label(text = nil) 172 @tree.label(@id, nil) 173 end 174 def label=(text) 175 @tree.label(@id, text) 176 end 177 178 def last_child() 179 @tree.last_child(@id) 180 end 181 182 def move(dest, keys={}) 183 @tree.keys(@id, dest, keys) 184 self 185 end 186 187 def next() 188 @tree.next(@id) 189 end 190 191 def next_sibling() 192 @tree.next_sibling(@id) 193 end 194 195 def parent() 196 @tree.parent(@id) 197 end 198 199 def fullpath() 200 @tree.fullpath(@id) 201 end 202 203 def position() 204 @tree.position(@id) 205 end 206 207 def previous() 208 @tree.previous(@id) 209 end 210 211 def prev_sibling() 212 @tree.prev_sibling(@id) 213 end 214 215 def restore(str, keys={}) 216 @tree.restore(@id, str, keys) 217 self 218 end 219 def restore_overwrite(str, keys={}) 220 @tree.restore_overwrite(@id, str, keys) 221 self 222 end 223 224 def restore_from_file(file, keys={}) 225 @tree.restore_from_file(@id, file, keys) 226 self 227 end 228 def restore_overwrite_from_file(file, keys={}) 229 @tree.restore_overwrite_from_file(@id, file, keys) 230 self 231 end 232 233 def root() 234 @tree.root(@id) 235 self 236 end 237 238 def set(data) 239 @tree.set(@id, data) 240 self 241 end 242 243 def size() 244 @tree.size(@id) 245 end 246 247 def sort(keys={}) 248 @tree.sort(@id, keys) 249 self 250 end 251 252 def type(key) 253 @tree.type(@id, key) 254 end 255 256 def unset(*keys) 257 @tree.unset(@id, *keys) 258 self 259 end 260 261 def values(key=None) 262 @tree.values(@id, key) 263 end 264 end 265 266 ################################### 267 268 class Tag < TkObject 269 TreeTagID_TBL = TkCore::INTERP.create_table 270 271 TkCore::INTERP.init_ip_env{ 272 TreeTagID_TBL.mutex.synchronize{ TreeTagID_TBL.clear } 273 } 274 275 (TreeTag_ID = ['blt_tree_tag'.freeze, TkUtil.untrust('00000')]).instance_eval{ 276 @mutex = Mutex.new 277 def mutex; @mutex; end 278 freeze 279 } 280 281 def self.id2obj(tree, id) 282 tpath = tree.path 283 TreeTagID_TBL.mutex.synchronize{ 284 if TreeTagID_TBL[tpath] 285 if TreeTagID_TBL[tpath][id] 286 TreeTagID_TBL[tpath][id] 287 else 288 begin 289 # self.new(tree, id) 290 (obj = self.allocate).instance_eval{ 291 @parent = @tree = tree 292 @tpath = @parent.path 293 @path = @id = id.dup.freeze if id 294 TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath] 295 TreeTagID_TBL[@tpath][@id] = self 296 } 297 obj 298 rescue 299 id 300 end 301 end 302 else 303 id 304 end 305 } 306 end 307 308 def initialize(tree, tag_str = nil) 309 @parent = @tree = tree 310 @tpath = @parent.path 311 312 if tag_str 313 @path = @id = tag_str.dup.freeze 314 else 315 TreeTag_ID.mutex.synchronize{ 316 @path = @id = TreeTag_ID.join(TkCore::INTERP._ip_id_) 317 TreeTag_ID[1].succ! 318 } 319 end 320 TreeTagID_TBL.mutex.synchronize{ 321 TreeTagID_TBL[@tpath] = {} unless TreeTagID_TBL[@tpath] 322 TreeTagID_TBL[@tpath][@id] = self 323 } 324 end 325 326 def id 327 @id 328 end 329 330 def add(*nodes) 331 tk_call(@tpath, 'tag', 'add', @id, *nodes) 332 self 333 end 334 335 def delete(*nodes) 336 tk_call(@tpath, 'tag', 'delete', @id, *nodes) 337 self 338 end 339 340 def forget() 341 tk_call(@tpath, 'tag', 'forget', @id) 342 TreeTagID_TBL.mutex.synchronize{ 343 TreeTagID_TBL[@tpath].delete(@id) 344 } 345 self 346 end 347 348 def nodes() 349 simplelist(tk_call(@tpath, 'tag', 'nodes', @id)).collect{|node| 350 Tk::BLT::Tree::Node.id2obj(@path, node) 351 } 352 end 353 354 def set(node) 355 tk_call(@tpath, 'tag', 'set', node, @id) 356 self 357 end 358 359 def unset(node) 360 tk_call(@tpath, 'tag', 'unset', node, @id) 361 self 362 end 363 end 364 365 ################################### 366 367 class Notify < TkObject 368 NotifyID_TBL = TkCore::INTERP.create_table 369 370 TkCore::INTERP.init_ip_env{ 371 NotifyID_TBL.mutex.synchronize{ NotifyID_TBL.clear } 372 } 373 374 def self.id2obj(tree, id) 375 tpath = tree.path 376 NotifyID_TBL.mutex.synchronize{ 377 if NotifyID_TBL[tpath] 378 if NotifyID_TBL[tpath][id] 379 NotifyID_TBL[tpath][id] 380 else 381 (obj = self.allocate).instance_eval{ 382 @parent = @tree = tree 383 @tpath = @parent.path 384 @path = @id = id 385 NotifyID_TBL[@tpath] ||= {} 386 NotifyID_TBL[@tpath][@id] = self 387 } 388 obj 389 end 390 else 391 return id 392 end 393 } 394 end 395 396 def self.new(tree, *args, &b) 397 NotifyID_TBL.mutex.synchronize{ 398 if tree.kind_of?(Array) 399 # not create 400 tpath = tree[0].path 401 NotifyID_TBL[tpath] ||= {} 402 unless (obj = NotifyID_TBL[tpath][tree[1]]) 403 (NotifyID_TBL[tpath][tree[1]] = 404 obj = self.allocate).instance_eval{ 405 @parent = @tree = tree[0] 406 @tpath = @parent.path 407 @path = @id = tree[1] 408 } 409 end 410 return obj 411 end 412 413 (obj = self.allocate).instance_eval{ 414 initialize(tree, *args, &b) 415 NotifyID_TBL[@tpath] ||= {} 416 NotifyID_TBL[@tpath][@id] = self 417 } 418 return obj 419 } 420 end 421 422 def initialize(tree, *args, &b) 423 @parent = @tree = tree 424 @tpath = @parent.path 425 426 # if args[0].kind_of?(Proc) || args[0].kind_of?(Method) 427 if TkComm._callback_entry?(args[0]) 428 cmd = args.shift 429 # elsif args[-1].kind_of?(Proc) || args[-1].kind_of?(Method) 430 elsif TkComm._callback_entry?(args[-1]) 431 cmd = args.pop 432 elsif b 433 cmd = Proc.new(&b) 434 else 435 fail ArgumentError, "lack of 'command' argument" 436 end 437 438 args = args.collect{|arg| '-' << arg.to_s} 439 440 args << proc{|id, type| 441 cmd.call(Tk::BLT::Tree::Node.id2obj(@tree, id), 442 ((type[0] == ?-)? type[1..-1]: type)) 443 } 444 445 @path = @id = tk_call(@tpath, 'notify', 'create', *args) 446 end 447 448 def id 449 @id 450 end 451 452 def delete() 453 tk_call(@tpath, 'notify', 'delete', @id) 454 NotifyID_TBL.mutex.synchronize{ 455 NotifyID_TBL[@tpath].delete(@id) 456 } 457 self 458 end 459 460 def info() 461 lst = simplelist(tk_call(@tpath, 'notify', 'info', id)) 462 lst[0] = Tk::BLT::Tree::Notify.id2obj(@tree, lst[0]) 463 lst[1] = simplelist(lst[1]).collect{|flag| flag[1..-1]} 464 lst[2] = tk_tcl2ruby(lst[2]) 465 lst 466 end 467 end 468 469 ################################### 470 471 class Trace < TkObject 472 TraceID_TBL = TkCore::INTERP.create_table 473 474 TkCore::INTERP.init_ip_env{ 475 TraceID_TBL.mutex.synchronize{ TraceID_TBL.clear } 476 } 477 478 def self.id2obj(tree, id) 479 tpath = tree.path 480 TraceID_TBL.mutex.synchronize{ 481 if TraceID_TBL[tpath] 482 if TraceID_TBL[tpath][id] 483 TraceID_TBL[tpath][id] 484 else 485 begin 486 # self.new([tree, id]) 487 (obj = self.allocate).instance_eval{ 488 @parent = @tree = tree 489 @tpath = @parent.path 490 @path = @id = node # == traceID 491 TraceID_TBL[@tpath] ||= {} 492 TraceID_TBL[@tpath][@id] = self 493 } 494 obj 495 rescue 496 id 497 end 498 end 499 else 500 id 501 end 502 } 503 end 504 505 def self.new(tree, *args, &b) 506 TraceID_TBL.mutex.synchronize{ 507 if tree.kind_of?(Array) 508 # not create 509 tpath = tree[0].path 510 TraceID_TBL[tpath] ||= {} 511 unless (obj = TraceID_TBL[tpath][tree[1]]) 512 (TraceID_TBL[tpath][tree[1]] = 513 obj = self.allocate).instance_eval{ 514 @parent = @tree = tree 515 @tpath = @parent.path 516 @path = @id = tree[1] # == traceID 517 } 518 end 519 return obj 520 end 521 522 # super(true, tree, *args, &b) 523 (obj = self.allocate).instance_eval{ 524 initialize(tree, *args, &b) 525 TraceID_TBL[@tpath] ||= {} 526 TraceID_TBL[@tpath][@id] = self 527 } 528 return obj 529 } 530 end 531 532 def initialize(tree, node, key, opts, cmd=nil, &b) 533 @parent = @tree = tree 534 @tpath = @parent.path 535 536 if !cmd 537 if b 538 cmd = Proc.new(&b) 539 else 540 fail ArgumentError, "lack of 'command' argument" 541 end 542 end 543 544 @path = @id = tk_call(@tpath, 'trace', 'create', node, key, opts, 545 proc{|t, id, k, ops| 546 tobj = Tk::BLT::Tree.id2obj(t) 547 if tobj.kind_of?(Tk::BLT::Tree) 548 nobj = Tk::BLT::Tree::Node.id2obj(tobj, id) 549 else 550 nobj = id 551 end 552 cmd.call(tobj, nobj, k, ops) 553 }) 554 end 555 556 def id 557 @id 558 end 559 560 def delete() 561 tk_call(@tpath, 'trace', 'delete', @id) 562 TraceID_TBL.mutex.synchronize{ 563 TraceID_TBL[tpath].delete(@id) 564 } 565 self 566 end 567 568 def info() 569 lst = simplelist(tk_call(@tpath, 'trace', 'info', id)) 570 lst[0] = Tk::BLT::Tree::Trace.id2obj(@tree, lst[0]) 571 lst[2] = simplelist(lst[2]) 572 lst[3] = tk_tcl2ruby(lst[3]) 573 lst 574 end 575 end 576 577 ################################### 578 579 TreeID_TBL = TkCore::INTERP.create_table 580 581 (Tree_ID = ['blt_tree'.freeze, TkUtil.untrust('00000')]).instance_eval{ 582 @mutex = Mutex.new 583 def mutex; @mutex; end 584 freeze 585 } 586 587 def __keyonly_optkeys 588 { 589 # apply / find command 590 'invert'=>nil, 'leafonly'=>nil, 'nocase'=>nil, 591 592 # apply / find / sort command 593 'path'=>nil, 594 595 # copy / restore / restorefile command 596 'overwrite'=>nil, 597 598 # copy command 599 'recurse'=>nil, 'tags'=>nil, 600 601 # sort command 602 'ascii'=>nil, 'decreasing'=>nil, 'disctionary'=>nil, 603 'integer'=>nil, 'real'=>nil, 'recurse'=>nil, 'reorder'=>nil, 604 } 605 end 606 607 def self.id2obj(id) 608 TreeID_TBL.mutex.synchronize{ 609 TreeID_TBL[id]? TreeID_TBL[id]: id 610 } 611 end 612 613 def self.names(pat = None) 614 simplelist(tk_call('::blt::tree', 'names', pat)).collect{|name| 615 id2obj(name) 616 } 617 end 618 619 def self.destroy(*names) 620 tk_call('::blt::tree', 'destroy', 621 *(names.collect{|n| (n.kind_of?(Tk::BLT::Tree))? n.id: n }) ) 622 end 623 624 def self.new(name = nil) 625 TreeID_TBL.mutex.synchronize{ 626 if name && TreeID_TBL[name] 627 TreeID_TBL[name] 628 else 629 (obj = self.allocate).instance_eval{ 630 initialize(name) 631 TreeID_TBL[@id] = self 632 } 633 obj 634 end 635 } 636 end 637 638 def initialzie(name = nil) 639 if name 640 @path = @id = name 641 else 642 Tree_ID.mutex.synchronize{ 643 @path = @id = Tree_ID.join(TkCore::INTERP._ip_id_) 644 Tree_ID[1].succ! 645 } 646 end 647 648 tk_call('::blt::tree', 'create', @id) 649 end 650 651 def __destroy_hook__ 652 Tk::BLT::Tree::Node::TreeNodeID_TBL.mutex.synchronize{ 653 Tk::BLT::Tree::Node::TreeNodeID_TBL.delete(@path) 654 } 655 Tk::BLT::Tree::Tag::TreeTagID_TBL.mutex.synchronize{ 656 Tk::BLT::Tree::Tag::TreeTagID_TBL.delete(@path) 657 } 658 Tk::BLT::Tree::Notify::NotifyID_TBL.mutex.synchronize{ 659 Tk::BLT::Tree::Notify::NotifyID_TBL.delete(@path) 660 } 661 Tk::BLT::Tree::Trace::TraceID_TBL.mutex.synchronize{ 662 Tk::BLT::Tree::Trace::TraceID_TBL.delete(@path) 663 } 664 end 665 666 def tagid(tag) 667 if tag.kind_of?(Tk::BLT::Tree::Node) || 668 tag.kind_of?(Tk::BLT::Tree::Tag) || 669 tag.kind_of?(Tk::BLT::Tree::Notify) || 670 tag.kind_of?(Tk::BLT::Tree::Trace) 671 tag.id 672 else 673 tag # maybe an Array of configure paramters 674 end 675 end 676 677 def destroy() 678 tk_call('::blt::tree', 'destroy', @id) 679 self 680 end 681 682 def ancestor(node1, node2) 683 Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'ancestor', 684 tagid(node1), tagid(node2))) 685 end 686 687 def apply(node, keys={}) 688 tk_call('::blt::tree', 'apply', tagid(node), __conv_keyonly_opts(keys)) 689 self 690 end 691 692 def attach(tree_obj) 693 tk_call('::blt::tree', 'attach', tree_obj) 694 self 695 end 696 697 def children(node) 698 simplelist(tk_call('::blt::tree', 'children', tagid(node))).collect{|n| 699 Tk::BLT::Tree::Node.id2obj(self, n) 700 } 701 end 702 703 def copy(src, parent, keys={}) 704 id = tk_call('::blt::tree', 'copy', tagid(src), tagid(parent), 705 __conv_keyonly_opts(keys)) 706 Tk::BLT::Tree::Node.new(self, nil, 'node'=>id) 707 end 708 def copy_to(src, dest_tree, parent, keys={}) 709 return copy(src, parent, keys={}) unless dest_tree 710 711 id = tk_call('::blt::tree', 'copy', tagid(src), dest_tree, 712 tagid(parent), __conv_keyonly_opts(keys)) 713 Tk::BLT::Tree::Node.new(dest_tree, nil, 'node'=>id) 714 end 715 716 def degree(node) 717 number(tk_call('::blt::tree', 'degree', tagid(node))) 718 end 719 720 def delete(*nodes) 721 tk_call('::blt::tree', 'delete', *(nodes.collect{|node| tagid(node)})) 722 Tk::BLT::Tree::Node::TreeNodeID_TBL.mutex.synchronize{ 723 nodes.each{|node| 724 if node.kind_of?(Tk::BLT::Tree::Node) 725 Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.id) 726 else 727 Tk::BLT::Tree::Node::TreeNodeID_TBL[@path].delete(node.to_s) 728 end 729 } 730 } 731 self 732 end 733 734 def depth(node) 735 number(tk_call('::blt::tree', 'depth', tagid(node))) 736 end 737 738 def dump(node) 739 simplelist(tk_call('::blt::tree', 'dump', tagid(node))).collect{|n| 740 simplelist(n) 741 } 742 end 743 744 def dump_to_file(node, file) 745 tk_call('::blt::tree', 'dumpfile', tagid(node), file) 746 self 747 end 748 749 def exist?(node, key=None) 750 bool(tk_call('::blt::tree', 'exists', tagid(node), key)) 751 end 752 753 def find(node, keys={}) 754 simplelist(tk_call('::blt::tree', 'find', tagid(node), 755 __conv_keyonly_opts(keys))).collect{|n| 756 Tk::BLT::Tree::Node.id2obj(self, n) 757 } 758 end 759 760 def find_child(node, label) 761 ret = tk_call('::blt::tree', 'findchild', tagid(node), label) 762 (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) 763 end 764 765 def first_child(node) 766 ret = tk_call('::blt::tree', 'firstchild', tagid(node)) 767 (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) 768 end 769 770 def get(node) 771 Hash[*simplelist(tk_call('::blt::tree', 'get', tagid(node)))] 772 end 773 def get_value(node, key, default_val=None) 774 tk_call('::blt::tree', 'get', tagid(node), key, default_val) 775 end 776 777 def index(node) 778 Tk::BLT::Tree::Node.id2obj(self, 779 tk_call('::blt::tree', 'index', tagid(node))) 780 end 781 782 def insert(parent, keys={}) 783 id = tk_call('::blt::tree', 'insert', tagid(parent), keys) 784 Tk::BLT::Tree::Node.new(self, nil, 'node'=>id) 785 end 786 787 def ancestor?(node1, node2) 788 bool(tk_call('::blt::tree', 'is', 'ancestor', 789 tagid(node1), tagid(node2))) 790 end 791 def before?(node1, node2) 792 bool(tk_call('::blt::tree', 'is', 'before', 793 tagid(node1), tagid(node2))) 794 end 795 def leaf?(node) 796 bool(tk_call('::blt::tree', 'is', 'leaf', tagid(node))) 797 end 798 def link?(node) 799 bool(tk_call('::blt::tree', 'is', 'link', tagid(node))) 800 end 801 def root?(node) 802 bool(tk_call('::blt::tree', 'is', 'root', tagid(node))) 803 end 804 805 def keys(node, *nodes) 806 if nodes.empty? 807 simplelist(tk_call('blt::tree', 'keys', tagid(node))) 808 else 809 simplelist(tk_call('blt::tree', 'keys', tagid(node), 810 *(nodes.collect{|n| tagid(n)}))).collect{|lst| 811 simplelist(lst) 812 } 813 end 814 end 815 816 def label(node, text=nil) 817 if text 818 tk_call('::blt::tree', 'label', tagid(node), text) 819 text 820 else 821 tk_call('::blt::tree', 'label', tagid(node)) 822 end 823 end 824 825 def last_child(node) 826 ret = tk_call('::blt::tree', 'lastchild', tagid(node)) 827 (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) 828 end 829 830 def link(parent, node, keys={}) 831 ret = tk_call('::blt::tree', 'link', tagid(parent), tagid(node), 832 __conv_keyonly_opts(keys)) 833 (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) 834 end 835 836 def move(node, dest, keys={}) 837 tk_call('::blt::tree', 'move', tagid(node), tagid(dest), keys) 838 self 839 end 840 841 def next(node) 842 ret = tk_call('::blt::tree', 'next', tagid(node)) 843 (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) 844 end 845 846 def next_sibling(node) 847 ret = tk_call('::blt::tree', 'nextsibling', tagid(node)) 848 (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) 849 end 850 851 def notify_create(*args, &b) 852 Tk::BLT::Tree::Notify.new(self, *args, &b) 853 end 854 855 def notify_delete(id) 856 if id.kind_of?(Tk::BLT::Tree::Notify) 857 id.delete 858 else 859 tk_call(@path, 'notify', 'delete', id) 860 Tk::BLT::Tree::Notify::NotifyID_TBL.mutex.synchronize{ 861 Tk::BLT::Tree::Notify::NotifyID_TBL[@path].delete(id.to_s) 862 } 863 end 864 self 865 end 866 867 def notify_info(id) 868 lst = simplelist(tk_call(@path, 'notify', 'info', tagid(id))) 869 lst[0] = Tk::BLT::Tree::Notify.id2obj(self, lst[0]) 870 lst[1] = simplelist(lst[1]).collect{|flag| flag[1..-1]} 871 lst[2] = tk_tcl2ruby(lst[2]) 872 lst 873 end 874 875 def notify_names() 876 tk_call(@path, 'notify', 'names').collect{|id| 877 Tk::BLT::Tree::Notify.id2obj(self, id) 878 } 879 end 880 881 def parent(node) 882 ret = tk_call('::blt::tree', 'parent', tagid(node)) 883 (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) 884 end 885 886 def fullpath(node) 887 tk_call('::blt::tree', 'path', tagid(node)) 888 end 889 890 def position(node) 891 number(tk_call('::blt::tree', 'position', tagid(node))) 892 end 893 894 def previous(node) 895 ret = tk_call('::blt::tree', 'previous', tagid(node)) 896 (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) 897 end 898 899 def prev_sibling(node) 900 ret = tk_call('::blt::tree', 'prevsibling', tagid(node)) 901 (ret == '-1')? nil: Tk::BLT::Tree::Node.id2obj(self, ret) 902 end 903 904 def restore(node, str, keys={}) 905 tk_call('::blt::tree', 'restore', tagid(node), str, 906 __conv_keyonly_opts(keys)) 907 self 908 end 909 def restore_overwrite(node, str, keys={}) 910 keys = __conv_keyonly_opts(keys) 911 keys.delete('overwrite') 912 keys.delete(:overwrite) 913 tk_call('::blt::tree', 'restore', tagid(node), str, '-overwrite', keys) 914 self 915 end 916 917 def restore_from_file(node, file, keys={}) 918 tk_call('::blt::tree', 'restorefile', tagid(node), file, 919 __conv_keyonly_opts(keys)) 920 self 921 end 922 def restore_overwrite_from_file(node, file, keys={}) 923 keys = __conv_keyonly_opts(keys) 924 keys.delete('overwrite') 925 keys.delete(:overwrite) 926 tk_call('::blt::tree', 'restorefile', tagid(node), file, 927 '-overwrite', keys) 928 self 929 end 930 931 def root(node=None) 932 Tk::BLT::Tree::Node.id2obj(self, tk_call('::blt::tree', 'root', 933 tagid(node))) 934 end 935 936 def set(node, data) 937 unless data.kind_of?(Hash) 938 fail ArgumentError, 'Hash is expected for data' 939 end 940 args = [] 941 data.each{|k, v| args << k << v} 942 tk_call('::blt::tree', 'set', tagid(node), *args) 943 self 944 end 945 946 def size(node) 947 number(tk_call('::blt::tree', 'size', tagid(node))) 948 end 949 950 def sort(node, keys={}) 951 tk_call('::blt::tree', 'sort', tagid(node), __conv_keyonly_opts(keys)) 952 self 953 end 954 955 def tag_add(tag, *nodes) 956 tk_call(@path, 'tag', 'add', tagid(tag), *(nodes.collect{|n| tagid(n)})) 957 self 958 end 959 960 def tag_delete(tag, *nodes) 961 tk_call(@path, 'tag', 'delete', tagid(tag), 962 *(nodes.collect{|n| tagid(n)})) 963 self 964 end 965 966 def tag_forget(tag) 967 tag = tag.id if tag.kind_of?(Tk::BLT::Tree::Tag) 968 tk_call(@path, 'tag', 'forget', tag) 969 TreeTagID_TBL.mutex.synchronize{ 970 TreeTagID_TBL[@path].delete(tag) 971 } 972 self 973 end 974 975 def tag_get(node, *patterns) 976 simplelist(tk_call(@tpath, 'tag', 'get', tagid(node), 977 *(patterns.collect{|pat| tagid(pat)}))).collect{|str| 978 Tk::BLT::Tree::Tag.id2obj(self, str) 979 } 980 end 981 982 def tag_names(node = None) 983 simplelist(tk_call(@tpath, 'tag', 'names', tagid(node))).collect{|str| 984 Tk::BLT::Tree::Tag.id2obj(self, str) 985 } 986 end 987 988 def tag_nodes(tag) 989 simplelist(tk_call(@tpath, 'tag', 'nodes', tagid(tag))).collect{|node| 990 Tk::BLT::Tree::Node.id2obj(self, node) 991 } 992 end 993 994 def tag_set(node, *tags) 995 tk_call(@path, 'tag', 'set', tagid(node), *(tags.collect{|t| tagid(t)})) 996 self 997 end 998 999 def tag_unset(node, *tags) 1000 tk_call(@path, 'tag', 'unset', tagid(node), 1001 *(tags.collect{|t| tagid(t)})) 1002 self 1003 end 1004 1005 def trace_create(*args, &b) 1006 Tk::BLT::Tree::Trace.new(self, *args, &b) 1007 end 1008 1009=begin 1010 def trace_delete(*args) 1011 args.each{|id| 1012 if id.kind_of?(Tk::BLT::Tree::Trace) 1013 id.delete 1014 else 1015 tk_call(@path, 'trace', 'delete', id) 1016 Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s) 1017 end 1018 self 1019 } 1020 end 1021=end 1022 def trace_delete(*args) 1023 args = args.collect{|id| tagid(id)} 1024 tk_call(@path, 'trace', 'delete', *args) 1025 Tk::BLT::Tree::Trace::TraceID_TBL.mutex.synchronize{ 1026 args.each{|id| Tk::BLT::Tree::Trace::TraceID_TBL[@path].delete(id.to_s)} 1027 } 1028 self 1029 end 1030 1031 def trace_info(id) 1032 lst = simplelist(tk_call(@path, 'trace', 'info', tagid(id))) 1033 lst[0] = Tk::BLT::Tree::Trace.id2obj(self, lst[0]) 1034 lst[2] = simplelist(lst[2]) 1035 lst[3] = tk_tcl2ruby(lst[3]) 1036 lst 1037 end 1038 1039 def trace_names() 1040 tk_call(@path, 'trace', 'names').collect{|id| 1041 Tk::BLT::Tree::Trace.id2obj(self, id) 1042 } 1043 end 1044 1045 def type(node, key) 1046 tk_call('::blt::tree', 'type', tagid(node), key) 1047 end 1048 1049 def unset(node, *keys) 1050 tk_call('::blt::tree', 'unset', tagid(node), *keys) 1051 self 1052 end 1053 1054 def values(node, key=None) 1055 simplelist(tk_call('::blt::tree', 'values', tagid(node), key)) 1056 end 1057 end 1058end 1059