1 ## This file is part of Crapvine.
3 ## Copyright (C) 2007 Andrew Sayman <lorien420@myrealbox.com>
5 ## Crapvine is free software; you can redistribute it and/or modify
6 ## it under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or
8 ## (at your option) any later version.
10 ## Crapvine is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ## GNU General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with this program. If not, see <http://www.gnu.org/licenses/>.
24 from grapevine_xml
import Attributed
, AttributedListModel
25 from attribute
import AttributeBuilder
27 class Experience(AttributedListModel
):
28 number_as_text_attrs
= ['unspent', 'earned']
29 column_attrs
= ['date', 'change', 'type', 'unspent', 'earned', 'reason']
30 column_attr_types
= [ gobject
.TYPE_STRING
, gobject
.TYPE_STRING
, gobject
.TYPE_STRING
, gobject
.TYPE_STRING
, gobject
.TYPE_STRING
, gobject
.TYPE_STRING
]
33 AttributedListModel
.__init
__(self
)
35 self
.entries
= self
.list
37 def add_entry(self
, entry
, calculate_expenditures
= True):
38 print "Appending entry %s" % entry
.get_xml()
39 self
.entries
.append(entry
)
42 path
= (len(self
.list) - 1, )
43 self
.row_inserted(path
, self
.get_iter(path
))
45 # Sort the entries using date
47 old_list
.extend(self
.entries
)
48 self
.entries
.sort(key
=operator
.attrgetter('date'))
50 # Signal the reordering
52 for old_entry
in old_list
:
53 new_indices
.append(self
.entries
.index(old_entry
))
54 self
.rows_reordered((), None, new_indices
)
55 print "After-sort entry %s" % entry
.get_xml()
57 # Calculate new earned/unspent totals
58 if calculate_expenditures
:
59 idx
= self
.entries
.index(entry
)
61 entry
.calculate_expenditures_from(self
.entries
[idx
- 1])
63 entry
.calculate_expenditures()
64 self
.row_changed((idx
,), self
.get_iter((idx
,)))
65 print "After-calc entry %s" % entry
.get_xml()
67 for cascade_idx
in range(idx
+ 1, len(self
.entries
)):
68 self
.entries
[cascade_idx
].calculate_expenditures_from(
69 self
.entries
[cascade_idx
- 1])
71 self
.row_changed(path
, self
.get_iter(path
))
73 self
.__update
_earned
_unspent
()
75 def __update_earned_unspent(self
):
76 if len(self
.entries
) == 0:
81 last_entry
= self
.entries
[-1]
82 self
.earned
= "%s" % last_entry
.earned
83 self
.unspent
= "%s" % last_entry
.unspent
85 def get_xml(self
, indent
=''):
86 end_tag
= ">\n" if len(self
.entries
) > 0 else "/>"
87 ret
= '%s<experience %s%s' % (indent
, self
.get_attrs_xml(), end_tag
)
88 local_indent
= '%s ' % (indent
)
89 ret
+= "\n".join([entry
.get_xml(local_indent
) for entry
in self
.entries
])
90 if len(self
.entries
) > 0:
91 ret
+= '%s%s</experience>' % ("\n", indent
)
96 def on_get_value(self
, index
, column
):
97 """Override display value for type in the tree view"""
98 if self
.column_attrs
[column
] == 'type':
99 if index
> len(self
.list):
101 targ
= self
.list[index
]
102 return ExperienceEntry
.map_type_to_str(targ
['type'])
104 return super(Experience
, self
).on_get_value(index
, column
)
106 class ExperienceEntry(Attributed
):
107 text_attrs
= ['reason']
108 number_as_text_attrs
= ['change', 'type', 'earned', 'unspent']
109 date_attrs
= ['date']
111 def get_xml(self
, indent
=''):
112 return '%s<entry %s/>' % (indent
, self
.get_attrs_xml())
114 return self
.get_xml()
116 def calculate_expenditures(self
):
117 tmp_e
= ExperienceEntry()
120 self
.calculate_expenditures_from(tmp_e
)
121 def calculate_expenditures_from(self
, next_entry
):
123 ne_u
= float(next_entry
.unspent
)
124 ne_e
= float(next_entry
.earned
)
125 s_c
= float(self
.change
)
126 s_u
= float(self
.unspent
)
127 s_e
= float(self
.earned
)
129 self
.unspent
= str(ne_u
- s_c
)
130 self
.earned
= "%s" % next_entry
.earned
132 self
.unspent
= str(ne_u
+ s_c
)
133 self
.earned
= str(ne_e
+ s_c
)
134 elif t
== 4: # Unspend
135 self
.unspent
= str(ne_u
+ s_c
)
136 self
.earned
= "%s" % next_entry
.earned
138 self
.unspent
= "%s" % next_entry
.earned
139 self
.earned
= str(ne_e
- s_c
)
140 elif t
== 2: # Set Earned To
141 self
.unspent
= "%s" % next_entry
.unspent
142 self
.earned
= "%s" % self
.change
143 elif t
== 5: # Set Unspent To
144 self
.unspent
= "%s" % self
.change
145 self
.earned
= "%s" % next_entry
.earned
146 elif t
== 6: # Comment
147 self
.unspent
= "%s" % next_entry
.unspent
148 self
.earned
= "%s" % next_entry
.earned
150 raise ValueError("Type must be an integer between 0 and 6")
153 def map_type_to_str(type_input
):
154 type = str(type_input
)
160 return 'Set Earned To'
166 return 'Set Unspent To'