Class: TaskJuggler::PropertyList
- Includes:
- MessageHandler
- Defined in:
- lib/taskjuggler/PropertyList.rb
Overview
The PropertyList is a utility class that can be used to hold a list of properties. It’s derived from an Array, so it can hold the properties in a well defined order. The order can be determined by an arbitrary number of sorting levels. A sorting level specifies an attribute who’s value should be used for sorting, a scenario index if necessary and the sorting direction (up/down). All nodes in the PropertyList must belong to the same PropertySet.
Instance Attribute Summary collapse
-
#propertySet ⇒ Object
readonly
Returns the value of attribute propertySet.
-
#query ⇒ Object
Returns the value of attribute query.
-
#scenarioIdx ⇒ Object
readonly
Returns the value of attribute scenarioIdx.
-
#sortingCriteria ⇒ Object
readonly
Returns the value of attribute sortingCriteria.
-
#sortingLevels ⇒ Object
readonly
Returns the value of attribute sortingLevels.
-
#sortingUp ⇒ Object
readonly
Returns the value of attribute sortingUp.
Instance Method Summary collapse
- #[](node) ⇒ Object
-
#append(list) ⇒ Object
Append another Array of PropertyTreeNodes or a PropertyList to this.
-
#checkForDuplicates(sourceFileInfo) ⇒ Object
Make sure that the list does not contain the same PropertyTreeNode more than once.
-
#include?(node) ⇒ Boolean
Specialized version of Array::include? that also matches adopted tasks.
- #includeAdopted ⇒ Object
-
#index ⇒ Object
This function sets the index attribute of all the properties in the list.
-
#initialize(arg, copyItems = true) ⇒ PropertyList
constructor
A PropertyList is always bound to a certain PropertySet.
-
#itemIndex(item) ⇒ Object
Return the Array index of item or nil.
-
#method_missing(func, *args, &block) ⇒ Object
This class should be a derived class of Array.
-
#resetSorting ⇒ Object
Clear all sorting levels.
-
#setSorting(modes) ⇒ Object
Set all sorting levels as Array of triplets.
-
#sort! ⇒ Object
Sort the properties according to the currently defined sorting criteria.
- #to_ary ⇒ Object
-
#to_s ⇒ Object
Turn the list into a String.
-
#treeMode? ⇒ Boolean
If the first sorting level is ‘tree’ the breakdown structure of the list is preserved.
Methods included from MessageHandler
#critical, #debug, #error, #fatal, #info, #warning
Constructor Details
#initialize(arg, copyItems = true) ⇒ PropertyList
A PropertyList is always bound to a certain PropertySet. All properties in the list must be of that set.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/taskjuggler/PropertyList.rb', line 37 def initialize(arg, copyItems = true) @items = copyItems ? arg.to_ary : [] if arg.is_a?(PropertySet) # Create a PropertyList from the given PropertySet. @propertySet = arg # To keep the list sorted, we may have to access Property attributes. # Pre-scheduling, we can only use static attributes. Post-scheduling, # we can include dynamic attributes as well. This query template will # be used to query attributes when it has been set. Otherwise the list # can only be sorted by static attributes. @query = nil resetSorting addSortingCriteria('seqno', true, -1) sort! else # Create a PropertyList from a given other PropertyList. @propertySet = arg.propertySet @query = arg.query ? arg.query.dup : nil @sortingLevels = arg.sortingLevels @sortingCriteria = arg.sortingCriteria.dup @sortingUp = arg.sortingUp.dup @scenarioIdx = arg.scenarioIdx.dup end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(func, *args, &block) ⇒ Object
This class should be a derived class of Array. But since it re-defines sort!() and still needs to call Array::sort!() I took a different route. All missing methods will be propagated to the @items Array.
65 66 67 |
# File 'lib/taskjuggler/PropertyList.rb', line 65 def method_missing(func, *args, &block) @items.method(func).call(*args, &block) end |
Instance Attribute Details
#propertySet ⇒ Object (readonly)
Returns the value of attribute propertySet.
32 33 34 |
# File 'lib/taskjuggler/PropertyList.rb', line 32 def propertySet @propertySet end |
#query ⇒ Object
Returns the value of attribute query.
32 33 34 |
# File 'lib/taskjuggler/PropertyList.rb', line 32 def query @query end |
#scenarioIdx ⇒ Object (readonly)
Returns the value of attribute scenarioIdx.
32 33 34 |
# File 'lib/taskjuggler/PropertyList.rb', line 32 def scenarioIdx @scenarioIdx end |
#sortingCriteria ⇒ Object (readonly)
Returns the value of attribute sortingCriteria.
32 33 34 |
# File 'lib/taskjuggler/PropertyList.rb', line 32 def sortingCriteria @sortingCriteria end |
#sortingLevels ⇒ Object (readonly)
Returns the value of attribute sortingLevels.
32 33 34 |
# File 'lib/taskjuggler/PropertyList.rb', line 32 def sortingLevels @sortingLevels end |
#sortingUp ⇒ Object (readonly)
Returns the value of attribute sortingUp.
32 33 34 |
# File 'lib/taskjuggler/PropertyList.rb', line 32 def sortingUp @sortingUp end |
Instance Method Details
#[](node) ⇒ Object
103 104 105 |
# File 'lib/taskjuggler/PropertyList.rb', line 103 def [](node) @items.find { |n| n.ptn == node.ptn } end |
#append(list) ⇒ Object
Append another Array of PropertyTreeNodes or a PropertyList to this. The list will be sorted again.
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/taskjuggler/PropertyList.rb', line 129 def append(list) if $DEBUG list.each do |node| unless node.propertySet == @propertySet raise "Fatal Error: All nodes must belong to the same PropertySet." end end end @items.concat(list) raise "Duplicate items" if @items != @items.uniq sort! end |
#checkForDuplicates(sourceFileInfo) ⇒ Object
Make sure that the list does not contain the same PropertyTreeNode more than once. This could happen for adopted tasks. If you use includeAdopted(), you should call this method after filtering to see if the filter was strict enough.
83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/taskjuggler/PropertyList.rb', line 83 def checkForDuplicates(sourceFileInfo) ptns = {} @items.each do |i| if ptns.include?(i.ptn) error('proplist_duplicate', "An adopted property is included as #{i.logicalId} and " + "as #{ptns[i.ptn].logicalId}. Please use stronger filtering " + 'to avoid including the property more than once!', sourceFileInfo) end ptns[i.ptn] = i end end |
#include?(node) ⇒ Boolean
Specialized version of Array::include? that also matches adopted tasks.
99 100 101 |
# File 'lib/taskjuggler/PropertyList.rb', line 99 def include?(node) !@items.find { |p| p.ptn == node.ptn }.nil? end |
#includeAdopted ⇒ Object
69 70 71 72 73 74 75 76 77 |
# File 'lib/taskjuggler/PropertyList.rb', line 69 def includeAdopted adopted = [] @items.each do |p| p.adoptees.each do |ap| adopted += includeAdoptedR(ap, p) end end append(adopted) end |
#index ⇒ Object
This function sets the index attribute of all the properties in the list. The index starts with 0 and increases for each property.
192 193 194 195 196 197 |
# File 'lib/taskjuggler/PropertyList.rb', line 192 def index i = 0 @items.each do |p| p.force('index', i += 1) end end |
#itemIndex(item) ⇒ Object
Return the Array index of item or nil.
186 187 188 |
# File 'lib/taskjuggler/PropertyList.rb', line 186 def itemIndex(item) @items.index(item) end |
#resetSorting ⇒ Object
Clear all sorting levels.
120 121 122 123 124 125 |
# File 'lib/taskjuggler/PropertyList.rb', line 120 def resetSorting @sortingLevels = 0 @sortingCriteria = [] @sortingUp = [] @scenarioIdx = [] end |
#setSorting(modes) ⇒ Object
Set all sorting levels as Array of triplets.
112 113 114 115 116 117 |
# File 'lib/taskjuggler/PropertyList.rb', line 112 def setSorting(modes) resetSorting modes.each do |mode| addSortingCriteria(*mode) end end |
#sort! ⇒ Object
Sort the properties according to the currently defined sorting criteria.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/taskjuggler/PropertyList.rb', line 151 def sort! if treeMode? # Tree sorting is somewhat complex. It will be based on the 'tree' # attribute of the PropertyTreeNodes but we have to update them first # based on the other sorting criteria. # Remove the tree sorting mode first. sc = @sortingCriteria.delete_at(0) su = @sortingUp.delete_at(0) si = @scenarioIdx.delete_at(0) @sortingLevels -= 1 # Sort the list based on the rest of the modes. sortInternal # The update the 'index' attributes of the PropertyTreeNodes. index # An then the 'tree' attributes. indexTree # Restore the 'tree' sorting mode again. @sortingCriteria.insert(0, sc) @sortingUp.insert(0, su) @scenarioIdx.insert(0, si) @sortingLevels += 1 # Sort again, now based on the updated 'tree' attributes. sortInternal else sortInternal end # Update indexes. index end |
#to_ary ⇒ Object
107 108 109 |
# File 'lib/taskjuggler/PropertyList.rb', line 107 def to_ary @items.dup end |
#to_s ⇒ Object
Turn the list into a String. This is only used for debugging.
200 201 202 203 204 205 206 207 208 209 |
# File 'lib/taskjuggler/PropertyList.rb', line 200 def to_s # :nodoc: res = "Sorting: " @sortingLevels.times do |i| res += "#{@sortingCriteria[i]}/#{@sortingUp[i] ? 'up' : 'down'}/" + "#{@scenarioIdx[i]}, " end res += "\n#{@items.length} properties:" @items.each { |i| res += "#{i.get('id')}: #{i.get('name')}\n" } res end |
#treeMode? ⇒ Boolean
If the first sorting level is ‘tree’ the breakdown structure of the list is preserved. This is a somewhat special mode and this function returns true if the mode is set.
146 147 148 |
# File 'lib/taskjuggler/PropertyList.rb', line 146 def treeMode? @sortingLevels > 0 && @sortingCriteria[0] == 'tree' end |