1#
2# Gramps - a GTK+/GNOME based genealogy program
3#
4# Copyright (C) 2000-2006  Donald N. Allingham
5# Copyright (C) 2011       Tim G L Lyons, 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"""
23CitationBaseModel classes for Gramps.
24"""
25
26#-------------------------------------------------------------------------
27#
28# python modules
29#
30#-------------------------------------------------------------------------
31from html import escape
32import logging
33log = logging.getLogger(".")
34LOG = logging.getLogger(".citation")
35
36#-------------------------------------------------------------------------
37#
38# Gramps modules
39#
40#-------------------------------------------------------------------------
41from gramps.gen.const import GRAMPS_LOCALE as glocale
42_ = glocale.translation.gettext
43from gramps.gen.datehandler import format_time, get_date, get_date_valid
44from gramps.gen.lib import Citation
45from gramps.gen.utils.string import conf_strings
46from gramps.gen.config import config
47
48#-------------------------------------------------------------------------
49#
50# COLUMN constants
51#
52#-------------------------------------------------------------------------
53# These are the column numbers in the serialize/unserialize interfaces in
54# the Citation object
55COLUMN_HANDLE = 0
56COLUMN_ID = 1
57COLUMN_DATE = 2
58COLUMN_PAGE = 3
59COLUMN_CONFIDENCE = 4
60COLUMN_SOURCE = 5
61COLUMN_CHANGE = 9
62COLUMN_TAGS = 10
63COLUMN_PRIV = 11
64
65# Data for the Source object
66COLUMN2_HANDLE = 0
67COLUMN2_ID = 1
68COLUMN2_TITLE = 2
69COLUMN2_AUTHOR = 3
70COLUMN2_PUBINFO = 4
71COLUMN2_ABBREV = 7
72COLUMN2_CHANGE = 8
73COLUMN2_TAGS = 11
74COLUMN2_PRIV = 12
75
76INVALID_DATE_FORMAT = config.get('preferences.invalid-date-format')
77
78#-------------------------------------------------------------------------
79#
80# CitationModel
81#
82#-------------------------------------------------------------------------
83class CitationBaseModel:
84
85# Fields access when 'data' is a Citation
86
87    def citation_date(self, data):
88        if data[COLUMN_DATE]:
89            citation = Citation()
90            citation.unserialize(data)
91            date_str = get_date(citation)
92            if date_str != "":
93                retval = escape(date_str)
94            if not get_date_valid(citation):
95                return INVALID_DATE_FORMAT % retval
96            else:
97                return retval
98        return ''
99
100    def citation_sort_date(self, data):
101        if data[COLUMN_DATE]:
102            citation = Citation()
103            citation.unserialize(data)
104            retval = "%09d" % citation.get_date_object().get_sort_value()
105            if not get_date_valid(citation):
106                return INVALID_DATE_FORMAT % retval
107            else:
108                return retval
109        return ''
110
111    def citation_id(self, data):
112        return data[COLUMN_ID]
113
114    def citation_page(self, data):
115        return data[COLUMN_PAGE]
116
117    def citation_sort_confidence(self, data):
118        if data[COLUMN_CONFIDENCE]:
119            return str(data[COLUMN_CONFIDENCE])
120        return ''
121
122    def citation_confidence(self, data):
123        return _(conf_strings[data[COLUMN_CONFIDENCE]])
124
125    def citation_private(self, data):
126        if data[COLUMN_PRIV]:
127            return 'gramps-lock'
128        else:
129            # There is a problem returning None here.
130            return ''
131
132    def citation_tags(self, data):
133        """
134        Return the sorted list of tags.
135        """
136        tag_list = list(map(self.get_tag_name, data[COLUMN_TAGS]))
137        # TODO for Arabic, should the next line's comma be translated?
138        return ', '.join(sorted(tag_list, key=glocale.sort_key))
139
140    def citation_tag_color(self, data):
141        """
142        Return the tag color.
143        """
144        tag_handle = data[0]
145        cached, tag_color = self.get_cached_value(tag_handle, "TAG_COLOR")
146        if not cached:
147            tag_color = ""
148            tag_priority = None
149            for handle in data[COLUMN_TAGS]:
150                tag = self.db.get_tag_from_handle(handle)
151                this_priority = tag.get_priority()
152                if tag_priority is None or this_priority < tag_priority:
153                    tag_color = tag.get_color()
154                    tag_priority = this_priority
155            self.set_cached_value(tag_handle, "TAG_COLOR", tag_color)
156        return tag_color
157
158    def citation_change(self, data):
159        return format_time(data[COLUMN_CHANGE])
160
161    def citation_sort_change(self, data):
162        return "%012x" % data[COLUMN_CHANGE]
163
164    def citation_source(self, data):
165        return data[COLUMN_SOURCE]
166
167    def citation_src_title(self, data):
168        source_handle = data[COLUMN_SOURCE]
169        cached, value = self.get_cached_value(source_handle, "SRC_TITLE")
170        if not cached:
171            try:
172                source = self.db.get_source_from_handle(source_handle)
173                value = source.get_title()
174            except:
175                value = ''
176            self.set_cached_value(source_handle, "SRC_TITLE", value)
177        return value
178
179    def citation_src_id(self, data):
180        source_handle = data[COLUMN_SOURCE]
181        cached, value = self.get_cached_value(source_handle, "SRC_ID")
182        if not cached:
183            try:
184                source = self.db.get_source_from_handle(source_handle)
185                value = source.gramps_id
186            except:
187                value = ''
188            self.set_cached_value(source_handle, "SRC_ID", value)
189        return value
190
191    def citation_src_auth(self, data):
192        source_handle = data[COLUMN_SOURCE]
193        cached, value = self.get_cached_value(source_handle, "SRC_AUTH")
194        if not cached:
195            try:
196                source = self.db.get_source_from_handle(source_handle)
197                value = source.get_author()
198            except:
199                value = ''
200            self.set_cached_value(source_handle, "SRC_AUTH", value)
201        return value
202
203    def citation_src_abbr(self, data):
204        source_handle = data[COLUMN_SOURCE]
205        cached, value = self.get_cached_value(source_handle, "SRC_ABBR")
206        if not cached:
207            try:
208                source = self.db.get_source_from_handle(source_handle)
209                value = source.get_abbreviation()
210            except:
211                value = ''
212            self.set_cached_value(source_handle, "SRC_ABBR", value)
213        return value
214
215    def citation_src_pinfo(self, data):
216        source_handle = data[COLUMN_SOURCE]
217        cached, value = self.get_cached_value(source_handle, "SRC_PINFO")
218        if not cached:
219            try:
220                source = self.db.get_source_from_handle(source_handle)
221                value = source.get_publication_info()
222            except:
223                value = ''
224            self.set_cached_value(source_handle, "SRC_PINFO", value)
225        return value
226
227    def citation_src_private(self, data):
228        source_handle = data[COLUMN_SOURCE]
229        cached, value = self.get_cached_value(source_handle, "SRC_PRIVATE")
230        if not cached:
231            try:
232                source = self.db.get_source_from_handle(source_handle)
233                if source.get_privacy():
234                    value = 'gramps-lock'
235                else:
236                    # There is a problem returning None here.
237                    value = ''
238            except:
239                value = ''
240            self.set_cached_value(source_handle, "SRC_PRIVATE", value)
241        return value
242
243    def citation_src_tags(self, data):
244        source_handle = data[COLUMN_SOURCE]
245        cached, value = self.get_cached_value(source_handle, "SRC_TAGS")
246        if not cached:
247            try:
248                source = self.db.get_source_from_handle(source_handle)
249                tag_list = list(map(self.get_tag_name, source.get_tag_list()))
250                # TODO for Arabic, should the next line's comma be translated?
251                value = ', '.join(sorted(tag_list, key=glocale.sort_key))
252            except:
253                value = ''
254            self.set_cached_value(source_handle, "SRC_TAGS", value)
255        return value
256
257    def citation_src_chan(self, data):
258        source_handle = data[COLUMN_SOURCE]
259        cached, value = self.get_cached_value(source_handle, "SRC_CHAN")
260        if not cached:
261            try:
262                source = self.db.get_source_from_handle(source_handle)
263                value = format_time(source.change)
264            except:
265                value = ''
266            self.set_cached_value(source_handle, "SRC_CHAN", value)
267        return value
268
269    def citation_src_sort_change(self, data):
270        source_handle = data[COLUMN_SOURCE]
271        cached, value = self.get_cached_value(source_handle, "SRC_CHAN")
272        if not cached:
273            try:
274                source = self.db.get_source_from_handle(source_handle)
275                value = "%012x" % source.change
276            except:
277                value = ''
278            self.set_cached_value(source_handle, "SRC_CHAN", value)
279        return value
280
281# Fields access when 'data' is a Source
282
283    def source_src_title(self, data):
284        return data[COLUMN2_TITLE]
285
286    def source_src_id(self, data):
287        return data[COLUMN2_ID]
288
289    def source_src_auth(self, data):
290        return data[COLUMN2_AUTHOR]
291
292    def source_src_abbr(self, data):
293        return data[COLUMN2_ABBREV]
294
295    def source_src_pinfo(self, data):
296        return data[COLUMN2_PUBINFO]
297
298    def source_src_private(self, data):
299        if data[COLUMN2_PRIV]:
300            return 'gramps-lock'
301        else:
302            # There is a problem returning None here.
303            return ''
304
305    def source_src_tags(self, data):
306        """
307        Return the sorted list of tags.
308        """
309        tag_list = list(map(self.get_tag_name, data[COLUMN2_TAGS]))
310        # TODO for Arabic, should the next line's comma be translated?
311        return ', '.join(sorted(tag_list, key=glocale.sort_key))
312
313    def source_src_tag_color(self, data):
314        """
315        Return the tag color.
316        """
317        tag_handle = data[0]
318        cached, tag_color = self.get_cached_value(tag_handle, "TAG_COLOR")
319        if not cached:
320            tag_color = ""
321            tag_priority = None
322            for handle in data[COLUMN2_TAGS]:
323                tag = self.db.get_tag_from_handle(handle)
324                this_priority = tag.get_priority()
325                if tag_priority is None or this_priority < tag_priority:
326                    tag_color = tag.get_color()
327                    tag_priority = this_priority
328            self.set_cached_value(tag_handle, "TAG_COLOR", tag_color)
329        return tag_color
330
331    def source_src_chan(self, data):
332        return format_time(data[COLUMN2_CHANGE])
333
334    def source_sort2_change(self, data):
335        return "%012x" % data[COLUMN2_CHANGE]
336
337    def dummy_sort_key(self, data):
338        # dummy sort key for columns that don't have data
339        return None
340
341    def get_tag_name(self, tag_handle):
342        """
343        Return the tag name from the given tag handle.
344        """
345        cached, value = self.get_cached_value(tag_handle, "TAG_NAME")
346        if not cached:
347            value = self.db.get_tag_from_handle(tag_handle).get_name()
348            self.set_cached_value(tag_handle, "TAG_NAME", value)
349        return value
350