Class: TaskJuggler::PropertyTreeNode
- Includes:
- MessageHandler
- Defined in:
- lib/taskjuggler/PropertyTreeNode.rb
Overview
This class is the base object for all Project properties. A Project property is a e. g. a Task, a Resource or other objects. Such properties can be arranged in tree form by assigning child properties to an existing property. The parent object needs to exist at object creation time. The PropertyTreeNode class holds all data and methods that are common to the different types of properties. Each property can have a set of predifined attributes. The PropertySet class holds collections of the same PropertyTreeNode objects and the defined attributes. Each PropertySet has a predefined set of attributes, but the attribute set can be extended by the user. E.g. a task has the predefined attribute ‘start’ and ‘end’ date. The user can extend tasks with a user defined attribute like an URL that contains more details about the task.
Instance Attribute Summary collapse
-
#adoptees ⇒ Object
readonly
Returns the value of attribute adoptees.
-
#children ⇒ Object
readonly
Returns the value of attribute children.
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#name ⇒ Object
Returns the value of attribute name.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#project ⇒ Object
readonly
Returns the value of attribute project.
-
#propertySet ⇒ Object
readonly
Returns the value of attribute propertySet.
-
#sequenceNo ⇒ Object
readonly
Returns the value of attribute sequenceNo.
-
#sourceFileInfo ⇒ Object
Returns the value of attribute sourceFileInfo.
-
#subId ⇒ Object
readonly
Returns the value of attribute subId.
Instance Method Summary collapse
-
#[](attributeId, scenario) ⇒ Object
Return the value of the attribute with ID attributeId.
-
#[]=(attributeId, scenario, value) ⇒ Object
Set the scenario specific attribute with ID attributeId for the scenario with index scenario to value.
-
#addChild(child) ⇒ Object
Add child node as child to this node.
-
#adopt(property) ⇒ Object
Adopt property as a step child.
-
#all ⇒ Object
Returns a list of this node and all transient sub nodes.
-
#allLeaves(withoutSelf = false) ⇒ Object
Return a list of all leaf nodes of this node.
-
#ancestors(includeStepParents = false) ⇒ Object
Return a list with all parent nodes of this node.
-
#attributeDefinition(attributeId) ⇒ Object
Return the type of the attribute with ID attributeId.
-
#backupAttributes ⇒ Object
This method creates a shallow copy of all attributes and returns them as an Array that can be used with restoreAttributes().
- #checkFailsAndWarnings ⇒ Object
-
#container? ⇒ Boolean
Return true if the node has children.
-
#deep_clone ⇒ Object
We only use deep_clone for attributes, never for properties.
-
#force(attributeId, value) ⇒ Object
Set the non-scenario-specific attribute with ID attributeId to value.
-
#fullId ⇒ Object
Return the full id of this node.
-
#get(attributeId) ⇒ Object
Return the value of the non-scenario-specific attribute with ID attributeId.
-
#getAdopted(property) ⇒ Object
Get adopted by property.
-
#getAttribute(attributeId, scenarioIdx = nil) ⇒ Object
Return the value of the attribute with ID attributeId.
-
#getBSIndicies ⇒ Object
Return the hierarchical index of this node.
-
#getIndicies ⇒ Object
Return the ‘index’ attributes of this property, prefixed by the ‘index’ attributes of all its parents.
-
#inheritAttributes ⇒ Object
Inherit values for the attributes from the parent node or the Project.
-
#inherited(attributeId, scenarioIdx = nil) ⇒ Object
Returns true if the value of the attribute attributeId (in scenario scenarioIdx) has been inherited from a parent node or scenario.
-
#initialize(propertySet, id, name, parent) ⇒ PropertyTreeNode
constructor
Create a new PropertyTreeNode object.
-
#isChildOf?(ancestor) ⇒ Boolean
Find out if this property is a direct or indirect child of ancestor.
-
#kids ⇒ Object
Return a list of all children including adopted kids.
-
#leaf? ⇒ Boolean
Return true if the node is a leaf node (has no children).
-
#level ⇒ Object
Returns the level that this property is on.
-
#levelSeqNo(node) ⇒ Object
Return the index of the child node.
- #logicalId ⇒ Object
-
#method_missing(func, scenarioIdx = 0, *args, &block) ⇒ Object
Many PropertyTreeNode functions are scenario specific.
- #modified?(attributeId, scenarioIdx = nil) ⇒ Boolean
-
#parents ⇒ Object
Return a list of all parents including step parents.
-
#provided(attributeId, scenarioIdx = nil) ⇒ Object
Returns true if the value of the attribute attributeId (in scenario scenarioIdx) has been provided by the user.
-
#ptn ⇒ Object
We often use PTNProxy objects to represent PropertyTreeNode objects.
- #query_alert(query) ⇒ Object
- #query_alertmessages(query) ⇒ Object
- #query_alertsummaries(query) ⇒ Object
- #query_alerttrend(query) ⇒ Object
- #query_children(query) ⇒ Object
- #query_journal(query) ⇒ Object
- #query_journalmessages(query) ⇒ Object
- #query_journalsummaries(query) ⇒ Object
-
#removeReferences(property) ⇒ Object
Remove any references in the stored data that references the property.
-
#restoreAttributes(backup) ⇒ Object
Restore the attributes to a previously saved state.
-
#root ⇒ Object
Return the top-level node for this node.
-
#set(attributeId, value) ⇒ Object
Set the non-scenario-specific attribute with ID attributeId to value.
-
#to_s ⇒ Object
(also: #to_str)
Dump the class data in human readable form.
Methods included from MessageHandler
#critical, #debug, #error, #fatal, #info, #warning
Constructor Details
#initialize(propertySet, id, name, parent) ⇒ PropertyTreeNode
Create a new PropertyTreeNode object. propertySet is the PropertySet that this PropertyTreeNode object belongs to. The PropertySet determines the attributes that are common to all Nodes in the set. id is a String that is unique in the namespace of the set. name is a user readable, short description of the object. parent is the PropertyTreeNode that sits above this node in the object hierachy. A root object has a parent of nil. For sets with hierachical name spaces, parent can be nil and specified by a hierachical id (e. g. ‘father.son’).
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 47 def initialize(propertySet, id, name, parent) @propertySet = propertySet @project = propertySet.project @parent = parent # Scenario specific data @data = nil # Attributes are created on-demand. We need to be careful that a pure # check for existance does not create them unecessarily. @attributes = Hash.new do |hash, attributeId| unless (aType = attributeDefinition(attributeId)) raise ArgumentError, "Unknown attribute '#{attributeId}' requested for " + "#{self.class.to_s.sub(/TaskJuggler::/, '')} '#{fullId}'" end unless aType.scenarioSpecific hash[attributeId] = aType.objClass.new(@propertySet, aType, self) else raise ArgumentError, "Attribute '#{attributeId}' is scenario specific" end end @scenarioAttributes = Array.new(@project.scenarioCount) do |scenarioIdx| Hash.new do |hash, attributeId| unless (aType = attributeDefinition(attributeId)) raise ArgumentError, "Unknown attribute '#{attributeId}' requested for " + "#{self.class.to_s.sub(/TaskJuggler::/, '')} '#{fullId}'" end if aType.scenarioSpecific hash[attributeId] = aType.objClass.new(@propertySet, aType, @data[scenarioIdx]) else raise ArgumentError, "Attribute '#{attributeId}' is not scenario specific" end end end # If _id_ is still nil, we generate a unique id. unless id tag = self.class.to_s.gsub(/TaskJuggler::/, '') id = '_' + tag + '_' + (propertySet.items + 1).to_s id = parent.fullId + '.' + id if !@propertySet.flatNamespace && parent end if !@propertySet.flatNamespace && id.include?('.') parentId = id[0..(id.rindex('.') - 1)] # Set parent to the parent property if it's still nil. @parent = @propertySet[parentId] unless @parent if $DEBUG if !@parent || !@propertySet[@parent.fullId] raise "Fatal Error: parent must be member of same property set" end if parentId != @parent.fullId raise "Fatal Error: parent (#{@parent.fullId}) and parent ID " + "(#{@parentId}) don't match" end end @subId = id[(id.rindex('.') + 1).. -1] else @subId = id end # The attribute 'id' is either the short ID or the full hierarchical ID. set('id', fullId) # The name of the property. @name = name set('name', name) @level = -1 @sourceFileInfo = nil @sequenceNo = @propertySet.items + 1 set('seqno', @sequenceNo) # This is a list of the real sub nodes of this PropertyTreeNode. @children = [] # This is a list of the adopted sub nodes of this PropertyTreeNode. @adoptees = [] # In case we have a parent object, we register this object as child of # the parent. if (@parent) @parent.addChild(self) end # This is a list of the PropertyTreeNode objects that have adopted this # node. @stepParents = [] end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(func, scenarioIdx = 0, *args, &block) ⇒ Object
Many PropertyTreeNode functions are scenario specific. These functions are provided by the class *Scenario classes. In case we can’t find a function called for the base class we try to find it in corresponding *Scenario class.
711 712 713 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 711 def method_missing(func, scenarioIdx = 0, *args, &block) @data[scenarioIdx].send(func, *args, &block) end |
Instance Attribute Details
#adoptees ⇒ Object (readonly)
Returns the value of attribute adoptees.
34 35 36 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 34 def adoptees @adoptees end |
#children ⇒ Object (readonly)
Returns the value of attribute children.
34 35 36 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 34 def children @children end |
#data ⇒ Object (readonly)
Returns the value of attribute data.
37 38 39 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 37 def data @data end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
34 35 36 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 34 def id @id end |
#name ⇒ Object
Returns the value of attribute name.
36 37 38 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 36 def name @name end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
34 35 36 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 34 def parent @parent end |
#project ⇒ Object (readonly)
Returns the value of attribute project.
34 35 36 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 34 def project @project end |
#propertySet ⇒ Object (readonly)
Returns the value of attribute propertySet.
34 35 36 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 34 def propertySet @propertySet end |
#sequenceNo ⇒ Object (readonly)
Returns the value of attribute sequenceNo.
34 35 36 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 34 def sequenceNo @sequenceNo end |
#sourceFileInfo ⇒ Object
Returns the value of attribute sourceFileInfo.
36 37 38 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 36 def sourceFileInfo @sourceFileInfo end |
#subId ⇒ Object (readonly)
Returns the value of attribute subId.
34 35 36 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 34 def subId @subId end |
Instance Method Details
#[](attributeId, scenario) ⇒ Object
Return the value of the attribute with ID attributeId. For scenario-specific attributes, scenario must indicate the index of the Scenario.
501 502 503 504 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 501 def [](attributeId, scenario) @scenarioAttributes[scenario][attributeId] @data[scenario].instance_variable_get(('@' + attributeId).intern) end |
#[]=(attributeId, scenario, value) ⇒ Object
Set the scenario specific attribute with ID attributeId for the scenario with index scenario to value. If scenario is nil, the attribute must not be scenario specific. In case the attribute does not exist, an exception is raised.
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 454 def []=(attributeId, scenario, value) overwrite = false if scenario if AttributeBase.mode == 0 # If we get values in 'provided' mode, we copy them immedidately to # all derived scenarios. @project.scenario(scenario).all.each do |sc| scenarioIdx = @project.scenarioIdx(sc) attr = @scenarioAttributes[scenarioIdx][attributeId] if attr.provided && !attr.isList? # Assignments to list attributes always append. We don't # consider this an overwrite. overwrite = true end if scenarioIdx == scenario attr.set(value) else attr.inherit(value) end end else attr = @scenarioAttributes[scenario][attributeId] overwrite = attr.provided && !attr.isList? attr.set(value) end else attr = @attributes[attributeId] overwrite = attr.provided && !attr.isList? attr.set(value) end # We only raise the overwrite error after all scenarios have been # set. For some attributes the overwrite is actually allowed. if overwrite raise AttributeOverwrite, "Overwriting a previously provided value for attribute " + "#{attributeId}" end end |
#addChild(child) ⇒ Object
Add child node as child to this node.
347 348 349 350 351 352 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 347 def addChild(child) if $DEBUG && child.propertySet != @propertySet raise "Child nodes must belong to the same property set as the parent" end @children.push(child) end |
#adopt(property) ⇒ Object
Adopt property as a step child. Also register the new relationship with the child.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 153 def adopt(property) # A property cannot adopt itself. if self == property error('adopt_self', 'A property cannot adopt itself') end # A top level task must never contain the same leaf task more then once! allOfRoot = root.all property.allLeaves.each do |adoptee| if allOfRoot.include?(adoptee) error('adopt_duplicate_child', "The task '#{adoptee.fullId}' has already been adopted by " + "property '#{root.fullId}' or any of its sub-properties.") end end @adoptees << property property.getAdopted(self) end |
#all ⇒ Object
Returns a list of this node and all transient sub nodes.
265 266 267 268 269 270 271 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 265 def all res = [ self ] kids.each do |c| res = res.concat(c.all) end res end |
#allLeaves(withoutSelf = false) ⇒ Object
Return a list of all leaf nodes of this node.
274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 274 def allLeaves(withoutSelf = false) res = [] if leaf? res << self unless withoutSelf else kids.each do |c| res += c.allLeaves end end res end |
#ancestors(includeStepParents = false) ⇒ Object
Return a list with all parent nodes of this node.
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 374 def ancestors(includeStepParents = false) nodes = [] if includeStepParents parents.each do |parent| nodes << parent nodes += parent.ancestors(true) end else n = self while n.parent nodes << (n = n.parent) end end nodes end |
#attributeDefinition(attributeId) ⇒ Object
Return the type of the attribute with ID attributeId.
400 401 402 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 400 def attributeDefinition(attributeId) @propertySet.attributeDefinitions[attributeId] end |
#backupAttributes ⇒ Object
This method creates a shallow copy of all attributes and returns them as an Array that can be used with restoreAttributes().
194 195 196 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 194 def backupAttributes [ @attributes.clone, @scenarioAttributes.clone ] end |
#checkFailsAndWarnings ⇒ Object
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 548 def checkFailsAndWarnings if @attributes.has_key?('fail') || @attributes.has_key?('warn') propertyType = case self when Task 'task' when Resource 'resource' else 'unknown' end queryAttrs = { 'project' => @project, 'property' => self, 'scopeProperty' => nil, 'start' => @project['start'], 'end' => @project['end'], 'loadUnit' => :days, 'numberFormat' => @project['numberFormat'], 'timeFormat' => nil, 'currencyFormat' => @project['currencyFormat'] } query = Query.new(queryAttrs) if @attributes['fail'] @attributes['fail'].get.each do |expr| if expr.eval(query) error("#{propertyType}_fail_check", "User defined check failed for #{propertyType} " + "#{fullId} \n" + "Condition: #{expr.to_s}\n" + "Result: #{expr.to_s(query)}") end end end if @attributes['warn'] @attributes['warn'].get.each do |expr| if expr.eval(query) warning("#{propertyType}_warn_check", "User defined warning triggered for #{propertyType} " + "#{fullId} \n" + "Condition: #{expr.to_s}\n" + "Result: #{expr.to_s(query)}") end end end end end |
#container? ⇒ Boolean
Return true if the node has children.
369 370 371 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 369 def container? !@children.empty? || !@adoptees.empty? end |
#deep_clone ⇒ Object
We only use deep_clone for attributes, never for properties. Since attributes may reference properties these references should remain references.
138 139 140 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 138 def deep_clone self end |
#force(attributeId, value) ⇒ Object
Set the non-scenario-specific attribute with ID attributeId to value. No further checks are done.
428 429 430 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 428 def force(attributeId, value) @attributes[attributeId].set(value) end |
#fullId ⇒ Object
Return the full id of this node. For PropertySet objects with a flat namespace, this is just the ID. Otherwise, the full ID is composed of all IDs from the root node to this node, separating the IDs by a dot.
293 294 295 296 297 298 299 300 301 302 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 293 def fullId res = @subId unless @propertySet.flatNamespace t = self until (t = t.parent).nil? res = t.subId + "." + res end end res end |
#get(attributeId) ⇒ Object
Return the value of the non-scenario-specific attribute with ID attributeId. This method works for built-in attributes as well. In case the attribute does not exist, an exception is raised.
407 408 409 410 411 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 407 def get(attributeId) # Make sure the attribute gets created if it doesn't exist already. @attributes[attributeId] instance_variable_get(('@' + attributeId).intern) end |
#getAdopted(property) ⇒ Object
Get adopted by property. Also register the new relationship with the step parent. This method is for internal use only. Other classes should alway use PropertyTreeNode::adopt().
176 177 178 179 180 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 176 def getAdopted(property) # :nodoc: return if @stepParents.include?(property) @stepParents << property end |
#getAttribute(attributeId, scenarioIdx = nil) ⇒ Object
Return the value of the attribute with ID attributeId. This method works for built-in attributes as well. In case this is a scenario-specific attribute, the scenario index needs to be provided by scenarioIdx, otherwise it must be nil. In case the attribute does not exist, an exception is raised.
418 419 420 421 422 423 424 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 418 def getAttribute(attributeId, scenarioIdx = nil) if scenarioIdx @scenarioAttributes[scenarioIdx][attributeId] else @attributes[attributeId] end end |
#getBSIndicies ⇒ Object
Return the hierarchical index of this node. In project management lingo this is called the Breakdown Structure Index (BSI). The result is an Array with an index for each level from the root to this node.
321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 321 def getBSIndicies idcs = [] p = self begin parent = p.parent idcs.insert(0, parent ? parent.levelSeqNo(p) : @propertySet.levelSeqNo(p)) p = parent end while p idcs end |
#getIndicies ⇒ Object
Return the ‘index’ attributes of this property, prefixed by the ‘index’ attributes of all its parents. The result is an Array of Integers.
335 336 337 338 339 340 341 342 343 344 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 335 def getIndicies idcs = [] p = self begin parent = p.parent idcs.insert(0, p.get('index')) p = parent end while p idcs end |
#inheritAttributes ⇒ Object
Inherit values for the attributes from the parent node or the Project.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 217 def inheritAttributes # Inherit non-scenario-specific values @propertySet.eachAttributeDefinition do |attrDef| next if attrDef.scenarioSpecific || !attrDef.inheritedFromParent aId = attrDef.id if parent # Inherit values from parent property if parent.provided(aId) || parent.inherited(aId) @attributes[aId].inherit(parent.get(aId)) end else # Inherit selected values from project if top-level property if attrDef.inheritedFromProject if @project[aId] @attributes[aId].inherit(@project[aId]) end end end end # Inherit scenario-specific values @propertySet.eachAttributeDefinition do |attrDef| next if !attrDef.scenarioSpecific || !attrDef.inheritedFromParent @project.scenarioCount.times do |scenarioIdx| if parent # Inherit scenario specific values from parent property if parent.provided(attrDef.id, scenarioIdx) || parent.inherited(attrDef.id, scenarioIdx) @scenarioAttributes[scenarioIdx][attrDef.id].inherit( parent[attrDef.id, scenarioIdx]) end else # Inherit selected values from project if top-level property if attrDef.inheritedFromProject if @project[attrDef.id] && @scenarioAttributes[scenarioIdx][attrDef.id] @scenarioAttributes[scenarioIdx][attrDef.id].inherit( @project[attrDef.id]) end end end end end end |
#inherited(attributeId, scenarioIdx = nil) ⇒ Object
Returns true if the value of the attribute attributeId (in scenario scenarioIdx) has been inherited from a parent node or scenario.
522 523 524 525 526 527 528 529 530 531 532 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 522 def inherited(attributeId, scenarioIdx = nil) if scenarioIdx unless @scenarioAttributes[scenarioIdx].has_key?(attributeId) return false end @scenarioAttributes[scenarioIdx][attributeId].inherited else return false unless @attributes.has_key?(attributeId) @attributes[attributeId].inherited end end |
#isChildOf?(ancestor) ⇒ Boolean
Find out if this property is a direct or indirect child of ancestor.
355 356 357 358 359 360 361 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 355 def isChildOf?(ancestor) parent = self while parent = parent.parent return true if (parent == ancestor) end false end |
#kids ⇒ Object
Return a list of all children including adopted kids.
183 184 185 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 183 def kids @children + @adoptees end |
#leaf? ⇒ Boolean
Return true if the node is a leaf node (has no children).
364 365 366 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 364 def leaf? @children.empty? && @adoptees.empty? end |
#level ⇒ Object
Returns the level that this property is on. Top-level properties return 0, their children 1 and so on. This value is cached internally, so it does not have to be calculated each time the function is called.
307 308 309 310 311 312 313 314 315 316 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 307 def level return @level if @level >= 0 t = self @level = 0 until (t = t.parent).nil? @level += 1 end @level end |
#levelSeqNo(node) ⇒ Object
Return the index of the child node.
212 213 214 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 212 def levelSeqNo(node) @children.index(node) + 1 end |
#logicalId ⇒ Object
286 287 288 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 286 def logicalId fullId end |
#modified?(attributeId, scenarioIdx = nil) ⇒ Boolean
534 535 536 537 538 539 540 541 542 543 544 545 546 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 534 def modified?(attributeId, scenarioIdx = nil) if scenarioIdx unless @scenarioAttributes[scenarioIdx].has_key?(attributeId) return false end @scenarioAttributes[scenarioIdx][attributeId].provided || @scenarioAttributes[scenarioIdx][attributeId].inherited else return false unless @attributes.has_key?(attributeId) @attributes[attributeId].provided || @attributes[attributeId].inherited end end |
#parents ⇒ Object
Return a list of all parents including step parents.
188 189 190 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 188 def parents (@parent ? [ @parent ] : []) + @stepParents end |
#provided(attributeId, scenarioIdx = nil) ⇒ Object
Returns true if the value of the attribute attributeId (in scenario scenarioIdx) has been provided by the user.
508 509 510 511 512 513 514 515 516 517 518 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 508 def provided(attributeId, scenarioIdx = nil) if scenarioIdx unless @scenarioAttributes[scenarioIdx].has_key?(attributeId) return false end @scenarioAttributes[scenarioIdx][attributeId].provided else return false unless @attributes.has_key?(attributeId) @attributes[attributeId].provided end end |
#ptn ⇒ Object
We often use PTNProxy objects to represent PropertyTreeNode objects. The proxy usually does a good job acting like a PropertyTreeNode. But in some situations, we want to make sure to operate on the PropertyTreeNode and not the PTNProxy. Both classes provide a ptn() method that always return the PropertyTreeNode.
147 148 149 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 147 def ptn self end |
#query_alert(query) ⇒ Object
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 615 def query_alert(query) journal = @project['journal'] query.sortable = query.numerical = alert = journal.alertLevel(query.end, self, query) alertLevel = @project['alertLevels'][alert] query.string = alertLevel.name rText = "<fcol:#{alertLevel.color}><nowiki>#{alertLevel.name}" + "</nowiki></fcol>" unless (rti = RichText.new(rText, RTFHandlers.create(@project)). generateIntermediateFormat) warning('ptn_journal', "Syntax error in journal message") return nil end rti.blockMode = false query.rti = rti end |
#query_alertmessages(query) ⇒ Object
632 633 634 635 636 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 632 def (query) journalMessages(@project['journal'].alertEntries(query.end, self, 1, query.start, query), query, true) end |
#query_alertsummaries(query) ⇒ Object
638 639 640 641 642 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 638 def query_alertsummaries(query) journalMessages(@project['journal'].alertEntries(query.end, self, 1, query.start, query), query, false) end |
#query_alerttrend(query) ⇒ Object
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 658 def query_alerttrend(query) journal = @project['journal'] startAlert = journal.alertLevel(query.start, self, query) endAlert = journal.alertLevel(query.end, self, query) if startAlert < endAlert query.sortable = 0 query.string = 'Up' elsif startAlert > endAlert query.sortable = 2 query.string = 'Down' else query.sortable = 1 query.string = 'Flat' end end |
#query_children(query) ⇒ Object
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 593 def query_children(query) list = [] kids.each do |property| if query.listItem rti = RichText.new(query.listItem, RTFHandlers.create(@project)). generateIntermediateFormat q = query.dup q.property = property rti.setQuery(q) list << "<nowiki>#{rti.to_s}</nowiki>" else list << "<nowiki>#{property.name} (#{property.fullId})</nowiki>" end end query.assignList(list) end |
#query_journal(query) ⇒ Object
611 612 613 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 611 def query_journal(query) @project['journal'].to_rti(query) end |
#query_journalmessages(query) ⇒ Object
644 645 646 647 648 649 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 644 def (query) journalMessages(@project['journal'].currentEntries(query.end, self, 0, query.start, query.hideJournalEntry), query, true) end |
#query_journalsummaries(query) ⇒ Object
651 652 653 654 655 656 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 651 def query_journalsummaries(query) journalMessages(@project['journal'].currentEntries(query.end, self, 0, query.start, query.hideJournalEntry), query, false) end |
#removeReferences(property) ⇒ Object
Remove any references in the stored data that references the property.
205 206 207 208 209 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 205 def removeReferences(property) @children.delete(property) @adoptees.delete(property) @stepParents.delete(property) end |
#restoreAttributes(backup) ⇒ Object
Restore the attributes to a previously saved state. backup is an Array generated by backupAttributes().
200 201 202 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 200 def restoreAttributes(backup) @attributes, @scenarioAttributes = backup end |
#root ⇒ Object
Return the top-level node for this node.
391 392 393 394 395 396 397 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 391 def root n = self while n.parent n = n.parent end n end |
#set(attributeId, value) ⇒ Object
Set the non-scenario-specific attribute with ID attributeId to value. In case an already provided value is overwritten again, an exeception is raised.
435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 435 def set(attributeId, value) attr = @attributes[attributeId] # Assignments to list attributes always append. We don't # consider this an overwrite. overwrite = attr.provided && !attr.isList? attr.set(value) # We only raise the overwrite error after the value has been set. if overwrite raise AttributeOverwrite, "Overwriting a previously provided value for attribute " + "#{attributeId}" end end |
#to_s ⇒ Object Also known as: to_str
Dump the class data in human readable form. Used for debugging only.
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 675 def to_s # :nodoc: res = "#{self.class} #{fullId} \"#{@name}\"\n" + " Sequence No: #{@sequenceNo}\n" res += " Parent: #{@parent.fullId}\n" if @parent children = "" @children.each do |c| children += ', ' unless children.empty? children += c.fullId end res += ' Children: ' + children + "\n" unless children.empty? @attributes.sort.each do |key, attr| res += indent(" #{key}: ", attr.to_s) end unless @scenarioAttributes.empty? project.scenarioCount.times do |sc| break if @scenarioAttributes[sc].nil? headerShown = false @scenarioAttributes[sc].sort.each do |key, attr| unless headerShown res += " Scenario #{project.scenario(sc).get('id')} (#{sc})\n" headerShown = true end res += indent(" #{key}: ", attr.to_s) end end end res += '-' * 75 + "\n" end |