1#
2# Gramps - a GTK+/GNOME based genealogy program
3#
4# Copyright (C) 2000-2007  Donald N. Allingham
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20
21"""
22Provide sorting routines for use in Gramps. Since these functions are
23intended to provide fast sorting, they tend to bypass access methods,
24and directly use class members. For this reason, care needs to be taken
25to make sure these remain in sync with the rest of the design.
26"""
27
28#-------------------------------------------------------------------------
29#
30# Standard python modules
31#
32#-------------------------------------------------------------------------
33
34#-------------------------------------------------------------------------
35#
36# Gramps Modules
37#
38#-------------------------------------------------------------------------
39from .lib import Date
40from .utils.db import get_birth_or_fallback
41from .display.name import displayer as _nd
42from .display.place import displayer as _pd
43from .const import GRAMPS_LOCALE as glocale
44
45#-------------------------------------------------------------------------
46#
47# Constants
48#
49#-------------------------------------------------------------------------
50
51class Sort:
52
53    def __init__(self, database):
54        self.database = database
55
56##    def by_last_name(self, first_id, second_id):
57##        """Sort routine for comparing two last names. If last names are equal,
58##        uses the given name and suffix"""
59##        first = self.database.get_person_from_handle(first_id)
60##        second = self.database.get_person_from_handle(second_id)
61##
62##        name1 = first.get_primary_name()
63##        name2 = second.get_primary_name()
64##
65##        fsn = name1.get_surname()
66##        ssn = name2.get_surname()
67##
68##        if fsn == ssn :
69##            ffn = name1.get_first_name()
70##            sfn = name2.get_first_name()
71##            if ffn == sfn:
72##                return glocale.strcoll(name1.get_suffix(), name2.get_suffix())
73##            else:
74##                return glocale.strcoll(ffn, sfn)
75##        else:
76##            return glocale.strcoll(fsn, ssn)
77
78    def by_last_name_key(self, first_id):
79        """
80        Sort routine for comparing two last names. If last names are equal,
81        uses the given name and suffix
82        """
83        first = self.database.get_person_from_handle(first_id)
84
85        name1 = first.get_primary_name()
86
87        fsn = name1.get_surname()
88        ffn = name1.get_first_name()
89        fsu = name1.get_suffix()
90        return glocale.sort_key(fsn + ffn + fsu)
91
92##    def by_sorted_name(self, first_id, second_id):
93##        """
94##        Sort routine for comparing two displayed names.
95##        """
96##
97##        first = self.database.get_person_from_handle(first_id)
98##        second = self.database.get_person_from_handle(second_id)
99##
100##        name1 = _nd.sorted(first)
101##        name2 = _nd.sorted(second)
102##
103##        return glocale.strcoll(name1, name2)
104
105    def by_sorted_name_key(self, first_id):
106        """
107        Sort routine for comparing two displayed names.
108        """
109
110        first = self.database.get_person_from_handle(first_id)
111
112        name1 = _nd.sorted(first)
113
114        return glocale.sort_key(name1)
115
116##    def by_birthdate(self, first_id, second_id):
117##        """Sort routine for comparing two people by birth dates. If the birth
118##        dates are equal, sorts by name"""
119##        first = self.database.get_person_from_handle(first_id)
120##        second = self.database.get_person_from_handle(second_id)
121##
122##        birth1 = get_birth_or_fallback(self.database, first)
123##        if birth1:
124##            date1 = birth1.get_date_object()
125##        else:
126##            date1 = Date()
127##
128##        birth2 = get_birth_or_fallback(self.database, second)
129##        if birth2:
130##            date2 = birth2.get_date_object()
131##        else:
132##            date2 = Date()
133##
134##        dsv1 = date1.get_sort_value()
135##        dsv2 = date2.get_sort_value()
136##
137##        val = cmp(dsv1, dsv2)
138##        if val == 0:
139##            return self.by_last_name(first_id, second_id)
140##        return val
141
142    def by_birthdate_key(self, first_id):
143        """
144        Sort routine for comparing two people by birth dates. If the birth dates
145        are equal, sorts by name
146        """
147        first = self.database.get_person_from_handle(first_id)
148
149        birth1 = get_birth_or_fallback(self.database, first)
150        if birth1:
151            date1 = birth1.get_date_object()
152        else:
153            date1 = Date()
154
155        dsv1 = date1.get_sort_value()
156        return "%08d" % dsv1 + str(self.by_last_name_key(first_id))
157
158##    def by_date(self, a_id, b_id):
159##        """Sort routine for comparing two events by their dates. """
160##        if not (a_id and b_id):
161##            return 0
162##        a_obj = self.database.get_event_from_handle(a_id)
163##        b_obj = self.database.get_event_from_handle(b_id)
164##        dsv1 = a_obj.get_date_object().get_sort_value()
165##        dsv2 = b_obj.get_date_object().get_sort_value()
166##        return cmp(dsv1, dsv2)
167
168    def by_date_key(self, a_id):
169        """Sort routine for comparing two events by their dates. """
170        if not a_id:
171            return 0
172        a_obj = self.database.get_event_from_handle(a_id)
173        return a_obj.get_date_object().get_sort_value()
174
175##    def by_place_title(self, a_id, b_id):
176##        """Sort routine for comparing two places. """
177##        if not (a_id and b_id):
178##            return 0
179##        a_obj = self.database.get_place_from_handle(a_id)
180##        b_obj = self.database.get_place_from_handle(b_id)
181##        return glocale.strcoll(a_obj.title, b_obj.title)
182
183    def by_place_title_key(self, a_id):
184        """Sort routine for comparing two places. """
185        if not a_id:
186            return 0
187        a_obj = self.database.get_place_from_handle(a_id)
188        title = _pd.display(self.database, a_obj)
189        return glocale.sort_key(title)
190
191##    def by_event_place(self, a_id, b_id):
192##        """Sort routine for comparing two events by their places. """
193##        if not (a_id and b_id):
194##            return 0
195##        evt_a = self.database.get_event_from_handle(a_id)
196##        evt_b = self.database.get_event_from_handle(b_id)
197##        plc_a = self.database.get_place_from_handle(evt_a.get_place_handle())
198##        plc_b = self.database.get_place_from_handle(evt_b.get_place_handle())
199##        plc_a_title = ""
200##        plc_b_title = ""
201##        if plc_a:
202##            plc_a_title = plc_a.title
203##        if plc_b:
204##            plc_b_title = plc_b.title
205##        return glocale.strcoll(plc_a_title, plc_b_title)
206
207    def by_event_place_key(self, a_id):
208        """Sort routine for comparing two events by their places. """
209        if not a_id:
210            return 0
211        evt_a = self.database.get_event_from_handle(a_id)
212        title = _pd.display_event(self.database, evt_a)
213        return glocale.sort_key(title)
214
215##    def by_event_description(self, a_id, b_id):
216##        """Sort routine for comparing two events by their descriptions. """
217##        if not (a_id and b_id):
218##            return 0
219##        evt_a = self.database.get_event_from_handle(a_id)
220##        evt_b = self.database.get_event_from_handle(b_id)
221##        return glocale.strcoll(evt_a.get_description(),
222##                               evt_b.get_description())
223
224    def by_event_description_key(self, a_id):
225        """Sort routine for comparing two events by their descriptions. """
226        if not a_id:
227            return 0
228        evt_a = self.database.get_event_from_handle(a_id)
229        return glocale.sort_key(evt_a.get_description())
230
231##    def by_event_id(self, a_id, b_id):
232##        """Sort routine for comparing two events by their ID. """
233##        if not (a_id and b_id):
234##            return 0
235##        evt_a = self.database.get_event_from_handle(a_id)
236##        evt_b = self.database.get_event_from_handle(b_id)
237##        return glocale.strcoll(evt_a.get_gramps_id(), evt_b.get_gramps_id())
238
239    def by_event_id_key(self, a_id):
240        """Sort routine for comparing two events by their ID. """
241        if not a_id:
242            return 0
243        evt_a = self.database.get_event_from_handle(a_id)
244        return glocale.sort_key(evt_a.get_gramps_id())
245
246##    def by_event_type(self, a_id, b_id):
247##        """Sort routine for comparing two events by their type. """
248##        if not (a_id and b_id):
249##            return 0
250##        evt_a = self.database.get_event_from_handle(a_id)
251##        evt_b = self.database.get_event_from_handle(b_id)
252##        return glocale.strcoll(str(evt_a.get_type()), str(evt_b.get_type()))
253
254    def by_event_type_key(self, a_id):
255        """Sort routine for comparing two events by their type. """
256        if not a_id:
257            return 0
258        evt_a = self.database.get_event_from_handle(a_id)
259        return glocale.sort_key(str(evt_a.get_type()))
260
261##    def by_media_title(self,a_id,b_id):
262##        """Sort routine for comparing two media objects by their title. """
263##        if not (a_id and b_id):
264##            return False
265##        a = self.database.get_media_from_handle(a_id)
266##        b = self.database.get_media_from_handle(b_id)
267##        return glocale.strcoll(a.desc, b.desc)
268
269    def by_media_title_key(self, a_id):
270        """Sort routine for comparing two media objects by their title. """
271        if not a_id:
272            return False
273        obj_a = self.database.get_media_from_handle(a_id)
274        return glocale.sort_key(obj_a.desc)
275