1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 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 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
#!/usr/bin/env ruby -w
# encoding: UTF-8
#
# = AttributeBase.rb -- The TaskJuggler III Project Management Software
#
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2019
# by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
require 'taskjuggler/deep_copy'
class TaskJuggler
# This class is the base for all property attribute types. Each property can
# have multiple attributes of different type. For each type, there must be a
# special Ruby class. Each of these classes must be derived from this class.
# The class holds information like a reference to the property that owns the
# attribute and the type of the attribute.
#
# The class can track wheter the attribute value was provided by the project
# file, inherited from another property or computed during scheduling.
#
# Attributes that are of an inherited type will be copied from a parent
# property or the global scope.
class AttributeBase
attr_reader :property, :type, :provided, :inherited
# The mode is flag that controls how value assignments affect the flags.
@@mode = 0
# Create a new AttributeBase object. _type_ specifies the specific type of
# the object. _property_ is the PropertyTreeNode object this attribute
# belongs to.
def initialize(property, type, container)
@type = type
@property = property
@container = container
reset
end
# Reset the attribute value to the default value.
def reset
@inherited = false
# Flag that marks whether the value of this attribute was provided by the
# user (in contrast to being calculated).
@provided = false
# If type is an AttributeDefinition, create the initial value according
# to the specified default for this type. Otherwise type is the initial
# value.
if @type.is_a?(AttributeDefinition)
@container.instance_variable_set(('@' + type.id).intern,
@type.default.deep_clone)
else
@container.instance_variable_set(('@' + type.id).intern, @type)
end
end
# Call this function to inherit _value_ from the parent property. It is
# very important that the values are deep copied as they may be modified
# later on.
def inherit(value)
@inherited = true
@container.instance_variable_set(('@' + type.id).intern, value.deep_clone)
end
# Return the current attribute setting mode.
def AttributeBase.mode
@@mode
end
# Change the @@mode. 0 means values are provided, 1 means values are
# inherited, any other value means calculated.
def AttributeBase.setMode(mode)
@@mode = mode
end
# Return the ID of the attribute.
def id
type.id
end
# Return the name of the attribute.
def name
type.name
end
# Set the value of the attribute. Depending on the mode we are in, the flags
# are updated accordingly.
def set(value)
case @@mode
when 0
@provided = true
when 1
@inherited = true
end
# Store the value in an instance variable in the PropertyTreeNode or
# ScenarioData object referred to by @container.
@container.instance_variable_set(('@' + type.id).intern, value)
end
# Return the attribute value.
def get
@container.instance_variable_get(('@' + type.id).intern)
end
# For legacy purposes we provide another name for get().
alias value get
# Check whether the value is uninitialized or nil.
def nil?
if (v = get).is_a?(Array)
v.empty?
else
v.nil?
end
end
def isList?
false
end
# We overwrite this for ListAttributeBase.
def AttributeBase::isList?
false
end
# Return the value as String.
def to_s(query = nil)
get.to_s
end
def to_num
v = get
if v.is_a?(Integer) || v.is_a?(Float)
v
else
nil
end
end
def to_sort
v = get
if v.is_a?(Integer) || v.is_a?(Float)
v
elsif v.respond_to?('to_s')
if v.respond_to?('join')
# If the attribute is an Array we convert it to a comma separated
# list.
v.join(', ')
else
v.to_s
end
else
nil
end
end
def to_rti(query)
get.is_a?(RichTextIntermediate) ? !value : nil
end
# Return the value in TJP file syntax.
def to_tjp
@type.id + " " + get.to_s
end
private
def quotedString(str)
if str.include?("\n")
"-8<-\n#{str}\n->8-"
else
"\"#{str.gsub("\"", '\"')}\""
end
end
end
# The ListAttributeBase is a specialized form of AttributeBase for a list of
# values instead of a single value. It will be used as a base class for all
# attributes that hold lists.
class ListAttributeBase < AttributeBase
def initialize(property, type, container)
super
end
def to_s
get.join(', ')
end
def isList?
true
end
# We overwrite this for ListAttributeBase.
def ListAttributeBase::isList?
true
end
end
class AttributeOverwrite < ArgumentError
end
end
|