@@ -23,12 +23,12 @@ class HouseTimelineGramplet(Gramplet):
23
23
def init (self ):
24
24
self .house_width = 40
25
25
self .set_tooltip (_ ("Double-click name for details" ))
26
+ # self.set_text(_("No Family Tree loaded."))
26
27
27
28
def on_load (self ):
28
29
self .no_wrap ()
29
30
tag = self .gui .buffer .create_tag ("fixed" )
30
31
tag .set_property ("font" , "Courier 8" )
31
- # set default house icon style.
32
32
if len (self .gui .data ) != 1 :
33
33
self .gui .data [:] = ["001" , None ]
34
34
@@ -38,14 +38,13 @@ def db_changed(self):
38
38
self .connect (self .dbstate .db ,'person-delete' , self .update )
39
39
40
40
def save_update_options (self , widget = None ):
41
- # saves a specific house icon style.
42
41
style = self .get_option (_ ("House Icon Style" ))
43
42
self .gui .data [:] = [style .get_value ()]
44
43
self .update ()
45
44
46
45
def build_options (self ):
47
- # builds a menu dropdown list of options.
48
46
from gramps .gen .plug .menu import EnumeratedListOption
47
+ # Add types:
49
48
style_list = EnumeratedListOption (_ ("House Icon Style" ), self .gui .data [0 ])
50
49
for item in [("001" , _ ("Standard" )),
51
50
("002" , _ ("Small" )),
@@ -58,11 +57,10 @@ def build_options(self):
58
57
def main (self ):
59
58
self .set_text (_ ("Processing..." ) + "\n " )
60
59
yield True
61
- self .count_dict = defaultdict (int )
62
- self .residents = {}
63
60
self .sorted_residents = {}
64
61
self .clear_text ()
65
62
address_count = 0
63
+ self .residents_range = []
66
64
# get details of people dbhandle, name, address
67
65
for p in self .dbstate .db .iter_people ():
68
66
person_handle = p .handle
@@ -74,9 +72,9 @@ def main(self):
74
72
for item in person_addr :
75
73
# address format from db is:
76
74
# [0] street, [1] locality, [2] city, [3] pcode, [4] state/county, [5] country, [6] phone
77
- location = item .get_text_data_list ()
75
+ address = item .get_text_data_list ()
78
76
date = item .get_date_object ()
79
- self .build_parent_address_dict (location ,date ,person_handle ,person_name )
77
+ self .build_parent_address_dict (address ,date ,person_handle ,person_name )
80
78
81
79
if address_count == 0 :
82
80
self .set_text (_ ("There are no individuals with Address data. Please add Address data to people." ))
@@ -88,17 +86,20 @@ def main(self):
88
86
89
87
def build_parent_address_dict (self , address , date , person_handle , person_name ):
90
88
"""
91
- Builds self.residents , The address + person_handle object.
92
- The collection is Address keyed (distinct )
89
+ Builds self.sorted_residents , The address + person_handle object.
90
+ The collection is grouped by locality/city (group_key) and sub key (address_key )
93
91
"""
94
- # TODO: group addresses by locality or city
92
+ # group key represents a group of similar locality/city.
93
+ group_key = address [1 ] + address [2 ]
94
+ # address key is the actual property address.
95
95
address_key = self .format_address_key (address )
96
- # set resident to index key
97
- if address_key not in self .residents :
98
- self .residents [address_key ] = {self .count_dict [address_key ]: {'address' :address ,'date' :date .get_ymd (),'handle' :person_handle ,'pname' : person_name }}
99
- elif address_key in self .residents :
100
- self .residents [address_key ][self .count_dict [address_key ]] = {'address' :address ,'date' :date .get_ymd (),'handle' :person_handle ,'pname' : person_name }
101
- self .count_dict [address_key ] += 1
96
+ if group_key not in self .sorted_residents :
97
+ self .sorted_residents [group_key ] = {address_key : [[date .get_ymd (),person_handle ,person_name ]]}
98
+ elif group_key in self .sorted_residents :
99
+ if address_key not in self .sorted_residents [group_key ]:
100
+ self .sorted_residents [group_key ][address_key ] = [[date .get_ymd (),person_handle ,person_name ]]
101
+ elif address_key in self .sorted_residents [group_key ]:
102
+ self .sorted_residents [group_key ][address_key ] += [[date .get_ymd (),person_handle ,person_name ]]
102
103
103
104
def format_address_key (self , address ):
104
105
"""
@@ -112,7 +113,7 @@ def format_address_key(self, address):
112
113
113
114
def build_house (self ):
114
115
"""
115
- Outputs sorted details from self.residents .
116
+ Outputs sorted details from self.sorted_residents .
116
117
"""
117
118
gl_location = _ ("Location" )
118
119
gl_time = _ ("Time In Family" )
@@ -121,29 +122,44 @@ def build_house(self):
121
122
gl_timeline = _ ("Timeline" )
122
123
gl_unknown = _ ("Unknown" )
123
124
gl_total_residents = _ ("Total Known Residents" )
124
- for resident in self .residents .items ():
125
- # sort residents by date.
126
- sorted_dates = sorted (resident [1 ].items (),key = lambda k : k [1 ]['date' ])
127
- first_year = 0
128
- last_year = int (sorted_dates [- 1 ][1 ]['date' ][0 ])
129
- for years in sorted_dates :
130
- date = years [1 ]['date' ][0 ]
131
- first_year = date if date != 0 and first_year == 0 else first_year
132
- time_in_family = last_year - first_year if first_year != 0 else gl_unknown
133
- self .append_text ("=========================\n " )
134
- self .render_house (self .gui .data [0 ])
135
- self .append_text ("{0}: {1}\n " .format (gl_location ,resident [0 ]) +
136
- ("{0}: {1} years\n " .format (gl_time ,time_in_family )) +
137
- ("{0}: {1} - {2}\n " .format (gl_first_resident ,sorted_dates [0 ][1 ]['date' ][0 ],sorted_dates [0 ][1 ]['pname' ])) +
138
- ("{0}: {1} - {2}\n " .format (gl_last_resident ,sorted_dates [- 1 ][1 ]['date' ][0 ],sorted_dates [- 1 ][1 ]['pname' ])) +
139
- ("{0}: {1}\n " .format (gl_total_residents ,len (sorted_dates ))) +
140
- " \n " )
141
- self .append_text ("{0}:\n " .format (gl_timeline ))
142
- # TODO: if duplicate person handles exist, denote as time period of person.
143
- for item in sorted_dates :
144
- self .append_text ("{0} - " .format (item [1 ]['date' ][0 ]))
145
- self .link (item [1 ]['pname' ],"Person" ,item [1 ]['handle' ])
146
- self .append_text ("\n " )
125
+
126
+ for resident in self .sorted_residents .items ():
127
+ # sort by house number
128
+ for item in sorted (resident [1 ].items ()):
129
+ # sort residents of an address by date.
130
+ sorted_dates = sorted (item [1 ],key = lambda k : k [0 ][0 ])
131
+ residents_reversed = sorted (sorted_dates , reverse = True )
132
+ # we need a list of distinct handles to get the correct resident count per address.
133
+ distinct_handles = []
134
+ for h in sorted_dates :
135
+ if h [1 ] not in distinct_handles :
136
+ distinct_handles .append (h [1 ])
137
+ first_year = int (sorted_dates [0 ][0 ][0 ])
138
+ last_year = int (sorted_dates [- 1 ][0 ][0 ])
139
+ time_in_family = last_year - first_year if first_year != 0 else gl_unknown
140
+ self .append_text ("=========================\n " )
141
+ self .render_house (self .gui .data [0 ])
142
+ self .append_text ("{0}: {1}\n " .format (gl_location ,item [0 ]) +
143
+ ("{0}: {1} years\n " .format (gl_time ,time_in_family )) +
144
+ ("{0}: {1} - {2}\n " .format (gl_first_resident ,sorted_dates [0 ][0 ][0 ],sorted_dates [0 ][2 ])) +
145
+ ("{0}: {1} - {2}\n " .format (gl_last_resident ,sorted_dates [- 1 ][0 ][0 ],sorted_dates [- 1 ][2 ])) +
146
+ ("{0}: {1}\n " .format (gl_total_residents ,len (distinct_handles ))) +
147
+ " \n " )
148
+ self .append_text ("{0}:\n " .format (gl_timeline ))
149
+ # for each person that is a resident, display the date and name with link.
150
+ for detail in sorted_dates :
151
+ # if a person has two address details, display the person living there as a range between two dates.
152
+ first_handle = detail
153
+ last_handle = next (handle for handle in residents_reversed if handle [1 ] == first_handle [1 ])
154
+ if (detail [0 ][0 ] != last_handle [0 ][0 ] and detail [1 ] not in self .residents_range ):
155
+ self .append_text ("{0} -> {1} - " .format (first_handle [0 ][0 ],last_handle [0 ][0 ]))
156
+ self .link (detail [2 ],"Person" ,detail [1 ])
157
+ self .append_text ("\n " )
158
+ self .residents_range .append (first_handle [1 ])
159
+ elif detail [1 ] not in self .residents_range :
160
+ self .append_text ("{0} - " .format (detail [0 ][0 ]))
161
+ self .link (detail [2 ],"Person" ,detail [1 ])
162
+ self .append_text ("\n " )
147
163
148
164
def render_house (self ,house_type ):
149
165
"""
0 commit comments