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’).
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 134 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 48 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.
712 713 714 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 712 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.
35 36 37 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 35 def adoptees @adoptees end |
#children ⇒ Object (readonly)
Returns the value of attribute children.
35 36 37 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 35 def children @children end |
#data ⇒ Object (readonly)
Returns the value of attribute data.
38 39 40 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 38 def data @data end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
35 36 37 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 35 def id @id end |
#name ⇒ Object
Returns the value of attribute name.
37 38 39 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 37 def name @name end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
35 36 37 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 35 def parent @parent end |
#project ⇒ Object (readonly)
Returns the value of attribute project.
35 36 37 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 35 def project @project end |
#propertySet ⇒ Object (readonly)
Returns the value of attribute propertySet.
35 36 37 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 35 def propertySet @propertySet end |
#sequenceNo ⇒ Object (readonly)
Returns the value of attribute sequenceNo.
35 36 37 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 35 def sequenceNo @sequenceNo end |
#sourceFileInfo ⇒ Object
Returns the value of attribute sourceFileInfo.
37 38 39 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 37 def sourceFileInfo @sourceFileInfo end |
#subId ⇒ Object (readonly)
Returns the value of attribute subId.
35 36 37 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 35 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.
502 503 504 505 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 502 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.
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 497 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 455 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.
348 349 350 351 352 353 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 348 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.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 154 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.
266 267 268 269 270 271 272 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 266 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.
275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 275 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.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 375 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.
401 402 403 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 401 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().
195 196 197 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 195 def backupAttributes [ @attributes.clone, @scenarioAttributes.clone ] end |
#checkFailsAndWarnings ⇒ Object
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 592 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 549 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.
370 371 372 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 370 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.
139 140 141 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 139 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.
429 430 431 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 429 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.
294 295 296 297 298 299 300 301 302 303 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 294 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.
408 409 410 411 412 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 408 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().
177 178 179 180 181 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 177 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.
419 420 421 422 423 424 425 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 419 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.
322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 322 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.
336 337 338 339 340 341 342 343 344 345 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 336 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.
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 263 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 218 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.
523 524 525 526 527 528 529 530 531 532 533 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 523 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.
356 357 358 359 360 361 362 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 356 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.
184 185 186 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 184 def kids @children + @adoptees end |
#leaf? ⇒ Boolean
Return true if the node is a leaf node (has no children).
365 366 367 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 365 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.
308 309 310 311 312 313 314 315 316 317 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 308 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.
213 214 215 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 213 def levelSeqNo(node) @children.index(node) + 1 end |
#logicalId ⇒ Object
287 288 289 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 287 def logicalId fullId end |
#modified?(attributeId, scenarioIdx = nil) ⇒ Boolean
535 536 537 538 539 540 541 542 543 544 545 546 547 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 535 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.
189 190 191 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 189 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.
509 510 511 512 513 514 515 516 517 518 519 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 509 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.
148 149 150 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 148 def ptn self end |
#query_alert(query) ⇒ Object
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 616 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
633 634 635 636 637 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 633 def (query) journalMessages(@project['journal'].alertEntries(query.end, self, 1, query.start, query), query, true) end |
#query_alertsummaries(query) ⇒ Object
639 640 641 642 643 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 639 def query_alertsummaries(query) journalMessages(@project['journal'].alertEntries(query.end, self, 1, query.start, query), query, false) end |
#query_alerttrend(query) ⇒ Object
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 659 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
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 594 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
612 613 614 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 612 def query_journal(query) @project['journal'].to_rti(query) end |
#query_journalmessages(query) ⇒ Object
645 646 647 648 649 650 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 645 def (query) journalMessages(@project['journal'].currentEntries(query.end, self, 0, query.start, query.hideJournalEntry), query, true) end |
#query_journalsummaries(query) ⇒ Object
652 653 654 655 656 657 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 652 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.
206 207 208 209 210 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 206 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().
201 202 203 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 201 def restoreAttributes(backup) @attributes, @scenarioAttributes = backup end |
#root ⇒ Object
Return the top-level node for this node.
392 393 394 395 396 397 398 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 392 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.
436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 436 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.
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 704 |
# File 'lib/taskjuggler/PropertyTreeNode.rb', line 676 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 |