1# 2# Gramps - a GTK+/GNOME based genealogy program 3# 4# Copyright (C) 2000-2007 Donald N. Allingham 5# Copyright (C) 2010 Nick Hall 6# 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 2 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program; if not, write to the Free Software 19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20# 21 22#------------------------------------------------------------------------- 23# 24# python modules 25# 26#------------------------------------------------------------------------- 27import logging 28log = logging.getLogger(".") 29 30#------------------------------------------------------------------------- 31# 32# GNOME/GTK modules 33# 34#------------------------------------------------------------------------- 35from gi.repository import Gtk 36 37#------------------------------------------------------------------------- 38# 39# Gramps modules 40# 41#------------------------------------------------------------------------- 42from gramps.gen.datehandler import displayer, format_time, get_date_valid 43from gramps.gen.display.name import displayer as name_displayer 44from gramps.gen.lib import EventRoleType, FamilyRelType 45from .flatbasemodel import FlatBaseModel 46from gramps.gen.utils.db import get_marriage_or_fallback 47from gramps.gen.config import config 48from gramps.gen.const import GRAMPS_LOCALE as glocale 49 50invalid_date_format = config.get('preferences.invalid-date-format') 51 52#------------------------------------------------------------------------- 53# 54# FamilyModel 55# 56#------------------------------------------------------------------------- 57class FamilyModel(FlatBaseModel): 58 59 def __init__(self, db, uistate, scol=0, order=Gtk.SortType.ASCENDING, 60 search=None, skip=set(), sort_map=None): 61 self.gen_cursor = db.get_family_cursor 62 self.map = db.get_raw_family_data 63 self.fmap = [ 64 self.column_id, 65 self.column_father, 66 self.column_mother, 67 self.column_type, 68 self.column_marriage, 69 self.column_private, 70 self.column_tags, 71 self.column_change, 72 self.column_tag_color, 73 ] 74 self.smap = [ 75 self.column_id, 76 self.sort_father, 77 self.sort_mother, 78 self.column_type, 79 self.sort_marriage, 80 self.column_private, 81 self.column_tags, 82 self.sort_change, 83 self.column_tag_color, 84 ] 85 FlatBaseModel.__init__(self, db, uistate, scol, order, search=search, 86 skip=skip, sort_map=sort_map) 87 88 def destroy(self): 89 """ 90 Unset all elements that can prevent garbage collection 91 """ 92 self.db = None 93 self.gen_cursor = None 94 self.map = None 95 self.fmap = None 96 self.smap = None 97 FlatBaseModel.destroy(self) 98 99 def color_column(self): 100 """ 101 Return the color column. 102 """ 103 return 8 104 105 def on_get_n_columns(self): 106 return len(self.fmap)+1 107 108 def column_father(self, data): 109 handle = data[0] 110 cached, value = self.get_cached_value(handle, "FATHER") 111 if not cached: 112 if data[2]: 113 person = self.db.get_person_from_handle(data[2]) 114 value = name_displayer.display_name(person.primary_name) 115 else: 116 value = "" 117 self.set_cached_value(handle, "FATHER", value) 118 return value 119 120 def sort_father(self, data): 121 handle = data[0] 122 cached, value = self.get_cached_value(handle, "SORT_FATHER") 123 if not cached: 124 if data[2]: 125 person = self.db.get_person_from_handle(data[2]) 126 value = name_displayer.sorted_name(person.primary_name) 127 else: 128 value = "" 129 self.set_cached_value(handle, "SORT_FATHER", value) 130 return value 131 132 def column_mother(self, data): 133 handle = data[0] 134 cached, value = self.get_cached_value(handle, "MOTHER") 135 if not cached: 136 if data[3]: 137 person = self.db.get_person_from_handle(data[3]) 138 value = name_displayer.display_name(person.primary_name) 139 else: 140 value = "" 141 self.set_cached_value(handle, "MOTHER", value) 142 return value 143 144 def sort_mother(self, data): 145 handle = data[0] 146 cached, value = self.get_cached_value(handle, "SORT_MOTHER") 147 if not cached: 148 if data[3]: 149 person = self.db.get_person_from_handle(data[3]) 150 value = name_displayer.sorted_name(person.primary_name) 151 else: 152 value = "" 153 self.set_cached_value(handle, "SORT_MOTHER", value) 154 return value 155 156 def column_type(self, data): 157 return str(FamilyRelType(data[5])) 158 159 def column_marriage(self, data): 160 handle = data[0] 161 cached, value = self.get_cached_value(handle, "MARRIAGE") 162 if not cached: 163 family = self.db.get_family_from_handle(data[0]) 164 event = get_marriage_or_fallback(self.db, family, "<i>%s</i>") 165 if event: 166 if event.date.format: 167 value = event.date.format % displayer.display(event.date) 168 elif not get_date_valid(event): 169 value = invalid_date_format % displayer.display(event.date) 170 else: 171 value = "%s" % displayer.display(event.date) 172 else: 173 value = '' 174 self.set_cached_value(handle, "MARRIAGE", value) 175 return value 176 177 def sort_marriage(self, data): 178 handle = data[0] 179 cached, value = self.get_cached_value(handle, "SORT_MARRIAGE") 180 if not cached: 181 family = self.db.get_family_from_handle(data[0]) 182 event = get_marriage_or_fallback(self.db, family) 183 if event: 184 value = "%09d" % event.date.get_sort_value() 185 else: 186 value = '' 187 self.set_cached_value(handle, "SORT_MARRIAGE", value) 188 return value 189 190 def column_id(self, data): 191 return data[1] 192 193 def column_private(self, data): 194 if data[14]: 195 return 'gramps-lock' 196 else: 197 # There is a problem returning None here. 198 return '' 199 200 def sort_change(self, data): 201 return "%012x" % data[12] 202 203 def column_change(self, data): 204 return format_time(data[12]) 205 206 def get_tag_name(self, tag_handle): 207 """ 208 Return the tag name from the given tag handle. 209 """ 210 cached, value = self.get_cached_value(tag_handle, "TAG_NAME") 211 if not cached: 212 value = self.db.get_tag_from_handle(tag_handle).get_name() 213 self.set_cached_value(tag_handle, "TAG_NAME", value) 214 return value 215 216 def column_tag_color(self, data): 217 """ 218 Return the tag color. 219 """ 220 tag_handle = data[0] 221 cached, tag_color = self.get_cached_value(tag_handle, "TAG_COLOR") 222 if not cached: 223 tag_color = "" 224 tag_priority = None 225 for handle in data[13]: 226 tag = self.db.get_tag_from_handle(handle) 227 this_priority = tag.get_priority() 228 if tag_priority is None or this_priority < tag_priority: 229 tag_color = tag.get_color() 230 tag_priority = this_priority 231 self.set_cached_value(tag_handle, "TAG_COLOR", tag_color) 232 return tag_color 233 234 def column_tags(self, data): 235 """ 236 Return the sorted list of tags. 237 """ 238 tag_list = list(map(self.get_tag_name, data[13])) 239 # TODO for Arabic, should the next line's comma be translated? 240 return ', '.join(sorted(tag_list, key=glocale.sort_key)) 241