# Author:: Nicolas Despres . # Copyright:: Copyright (c) 2004, 2005 Uttk team. All rights reserved. # License:: LGPL # $Id: /w/fey/uttk/trunk/lib/uttk/logger/section_node.rb 8778 2005-09-26T04:34:48.103938Z ertai $ module Uttk class Logger # Implement a tree of section. A section node has a name and a `active' # flag that say if the section node is on/off. A section tree verifies the # following property: # # a node is active iff at least one of its sub nodes is active # # Obviously, when activating a node, all its sub nodes are also activated. class SectionNode def initialize(name, *sub_sections) self.name = name @sub_sections = {} sub_sections.each { |s| self << s } @active = false end attr_reader :name def name=(new_name) @name = new_name.to_s end def sub_sections @sub_sections.values end def [](name) @sub_sections[name] end def []=(name, sub_section) check_sub_section_type(sub_section) sub_section.name = name @sub_sections[sub_section.name] = sub_section end def <<(sub_section) check_sub_section_type(sub_section) @sub_sections[sub_section.name] = sub_section end def push(*sub_sections) sub_sections.each { |ss| self << ss } end def active=(new_active) active_tree(new_active) @active end def active? @active end def active_tree(new_active) accu = [] active_tree_rec(new_active, accu) unless new_active == @active accu end def active_tree_rec(new_active, accu) @active = new_active accu << @name @sub_sections.each_value { |s| s.active_tree_rec(new_active, accu) } end protected :active_tree_rec # Active the given section name in the tree. Return an array of all the # section name that have been activated. The returned array is empty if # the section name doesn't exists in the tree. def active_section(section_name) accu = [] active_section_rec(section_name, accu) accu end def active_section_rec(section_name, accu) if @name == section_name accu.concat(active_tree(true)) true else ret = false @sub_sections.each_value do |s| if s.active_section_rec(section_name, accu) @active = true accu << @name ret = true break end end ret end end protected :active_section_rec # Unactive the given section name in the tree. Return an array of all the # section name that have been unactivated. The returned array is empty if # the section name doesn't exists in the tree or if none section have # been unactivated. def unactive_section(section_name) accu = [] unactive_section_rec(section_name, accu) accu end def unactive_section_rec(section_name, accu) if @name == section_name accu.concat(active_tree(false)) true else not_unactivable = ret = false @sub_sections.each_value do |s| ret ||= s.unactive_section_rec(section_name, accu) not_unactivable ||= s.active? end if ret and (not not_unactivable) @active = false accu << @name true else false end end end protected :unactive_section_rec def set_active_section(active, *section_names) section = [] section_names.each do |s| section.concat(active ? active_section(s) : unactive_section(s)) end section.uniq! section end def each(&block) @sub_sections.each(&block) end alias :each_pair :each def each_section(&block) @sub_sections.each_value(&block) end alias :each_value :each_section def each_label(&block) @sub_sections.each_key(&block) end alias :each_key :each_label def delete(name) @sub_sections.delete(name) end def clear(name) @sub_sections.clear end def nb_sub_sections @sub_sections.size end alias :size :nb_sub_sections alias :length :nb_sub_sections def leaf? @sub_sections.empty? end def pre_depth_first(&block) block[self] @sub_sections.each_value { |s| s.pre_depth_first(&block) } nil end def find(name) if @name == name self else @sub_sections.each_value do |s| ret = s.find(name) return ret unless ret.nil? end nil end end protected def check_sub_section_type(sub_section) unless sub_section.is_a?(self.class) raise(TypeError, "`#{sub_section}' - must be a #{self.class}") end end end # class SectionNode end # class Logger end # module Uttk