From 4f07e2ed520c02d4978a8205d1ae044075b96a69 Mon Sep 17 00:00:00 2001 From: Gary Burton Date: Sat, 10 Jan 2009 12:15:54 +0000 Subject: [PATCH] New plugin for sorting events within a database svn: r11599 --- src/Sort.py | 44 ++++++- src/plugins/Makefile.am | 1 + src/plugins/SortEvents.py | 237 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 src/plugins/SortEvents.py diff --git a/src/Sort.py b/src/Sort.py index b603de651..4667f9c26 100644 --- a/src/Sort.py +++ b/src/Sort.py @@ -124,12 +124,52 @@ class Sort: return cmp(a_obj.get_date_object(), b_obj.get_date_object()) def by_place_title(self, a_id, b_id): - """Sort routine for comparing two events by their dates. """ + """Sort routine for comparing two places. """ if not (a_id and b_id): return 0 a_obj = self.database.get_place_from_handle(a_id) b_obj = self.database.get_place_from_handle(b_id) return locale.strcoll(a_obj.title, b_obj.title) + + def by_event_place(self, a_id, b_id): + """Sort routine for comparing two events by their places. """ + if not (a_id and b_id): + return 0 + evt_a = self.database.get_event_from_handle(a_id) + evt_b = self.database.get_event_from_handle(b_id) + plc_a = self.database.get_place_from_handle(evt_a.get_place_handle()) + plc_b = self.database.get_place_from_handle(evt_b.get_place_handle()) + plc_a_title = "" + plc_b_title = "" + if plc_a: + plc_a_title = plc_a.title + if plc_b: + plc_b_title = plc_b.title + return locale.strcoll(plc_a_title, plc_b_title) + + def by_event_description(self, a_id, b_id): + """Sort routine for comparing two events by their descriptions. """ + if not (a_id and b_id): + return 0 + evt_a = self.database.get_event_from_handle(a_id) + evt_b = self.database.get_event_from_handle(b_id) + return locale.strcoll(evt_a.get_description(), evt_b.get_description()) + + def by_event_id(self, a_id, b_id): + """Sort routine for comparing two events by their ID. """ + if not (a_id and b_id): + return 0 + evt_a = self.database.get_event_from_handle(a_id) + evt_b = self.database.get_event_from_handle(b_id) + return locale.strcoll(evt_a.get_gramps_id(), evt_b.get_gramps_id()) + + def by_event_type(self, a_id, b_id): + """Sort routine for comparing two events by their type. """ + if not (a_id and b_id): + return 0 + evt_a = self.database.get_event_from_handle(a_id) + evt_b = self.database.get_event_from_handle(b_id) + return locale.strcoll(str(evt_a.get_type()), str(evt_b.get_type())) def by_media_title(self,a_id,b_id): """Sort routine for comparing two media objects by their title. """ @@ -137,5 +177,5 @@ class Sort: return False a = self.database.get_object_from_handle(a_id) b = self.database.get_object_from_handle(b_id) - return locale.strcoll(a.desc,b.desc) + return locale.strcoll(a.desc, b.desc) diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 8f8db1fa1..b66c47f55 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -96,6 +96,7 @@ pkgdata_PYTHON = \ SameSurnames.py\ siblings.py\ SimpleBookTitle.py\ + SortEvents.py\ SoundGen.py\ StatisticsChart.py\ Summary.py\ diff --git a/src/plugins/SortEvents.py b/src/plugins/SortEvents.py new file mode 100644 index 000000000..b61e80cac --- /dev/null +++ b/src/plugins/SortEvents.py @@ -0,0 +1,237 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2009 Gary Burton +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id$ + +"""Tools/Database Processing/Sort Events""" + +#------------------------------------------------------------------------- +# +# python modules +# +#------------------------------------------------------------------------- +from gettext import gettext as _ + +#------------------------------------------------------------------------- +# +# gramps modules +# +#------------------------------------------------------------------------- +import Sort + +from PluginUtils import Tool, MenuToolOptions, PluginWindows +from ReportBase import ReportUtils +from gen.plug import PluginManager +from gen.plug.menu import FilterOption, PersonOption, \ + EnumeratedListOption, BooleanOption +from gen.utils import set_birth_death_index + +#------------------------------------------------------------------------ +# +# Private Functions +# +#------------------------------------------------------------------------ +def _get_sort_functions(sort): + """ + Define the types of sorting that is available + """ + return [ + (_("Date"), sort.by_date), + (_("Type"), sort.by_event_type), + (_("ID"), sort.by_event_id), + (_("Description"), sort.by_event_description), + (_("Place"), sort.by_event_place),] + +#------------------------------------------------------------------------- +# +# SortEvents +# +#------------------------------------------------------------------------- +class SortEvents(PluginWindows.ToolManagedWindowBatch): + """ + This tool can be used to sort personal and family events by a variety + of event attributes. It is primarily intended for re-organising data + imported from an external source where the events are randomly ordered. + """ + + def get_title(self): + """ + Return the window title. + """ + return _("Sort Events") + + def initial_frame(self): + """ + The name of the initial menu tab. + """ + return _("Options") + + def run(self): + """ + Perform the actual extraction of information. + """ + menu = self.options.menu + self.filter = menu.get_option_by_name('filter').get_filter() + sort_func_num = menu.get_option_by_name('sort_by').get_value() + self.sort_desc = menu.get_option_by_name('sort_desc').get_value() + self.fam_events = menu.get_option_by_name('family_events').get_value() + sort_functions = _get_sort_functions(Sort.Sort(self.db)) + self.sort_name = sort_functions[sort_func_num][0] + self.sort_func = sort_functions[sort_func_num][1] + self.sort = Sort.Sort(self.db) + trans = self.db.transaction_begin("", batch=True) + self.db.disable_signals() + family_handles = self.sort_person_events(trans) + if len(family_handles) > 0: + self.sort_family_events(family_handles, trans) + self.db.transaction_commit(trans, _("Sort event changes")) + self.db.enable_signals() + self.db.request_rebuild() + + def sort_person_events(self, trans): + """ + Sort the personal events associated with the selected people. + """ + people_handles = self.filter.apply(self.db, + self.db.get_person_handles(sort_handles=False)) + self.progress.set_pass(_("Sorting personal events..."), + len(people_handles)) + family_handles = [] + for handle in people_handles: + person = self.db.get_person_from_handle(handle) + self.progress.step() + event_ref_list = person.get_event_ref_list() + event_ref_list.sort(lambda x, y: self.sort_func(x.ref, y.ref)) + if self.sort_desc: + event_ref_list.reverse() + if self.fam_events: + family_handles.extend(person.get_family_handle_list()) + person.set_event_ref_list(event_ref_list) + set_birth_death_index(self.db, person) + self.db.commit_person(person, trans) + self.change = True + return family_handles + + def sort_family_events(self, family_handles, trans): + """ + Sort the family events associated with the selected people. + """ + self.progress.set_pass(_("Sorting family events..."), + len(family_handles)) + for handle in family_handles: + family = self.db.get_family_from_handle(handle) + self.progress.step() + event_ref_list = family.get_event_ref_list() + event_ref_list.sort(lambda x, y: self.sort_func(x.ref, y.ref)) + if self.sort_desc: + event_ref_list.reverse() + family.set_event_ref_list(event_ref_list) + self.db.commit_family(family, trans) + self.change = True + +#------------------------------------------------------------------------ +# +# +# +#------------------------------------------------------------------------ +class SortEventOptions(MenuToolOptions): + """ + Define options and provides handling interface. + """ + + def __init__(self, name, person_id=None, dbstate=None): + self.__db = dbstate.get_database() + MenuToolOptions.__init__(self, name, person_id, dbstate) + + def add_menu_options(self, menu): + """ + Define the options for the menu. + """ + category_name = _("Tool Options") + + self.__filter = FilterOption(_("Filter"), 0) + self.__filter.set_help(_("Select the people to sort")) + menu.add_option(category_name, "filter", self.__filter) + self.__filter.connect('value-changed', self.__filter_changed) + + self.__pid = PersonOption(_("Filter Person")) + self.__pid.set_help(_("The center person for the filter")) + menu.add_option(category_name, "pid", self.__pid) + self.__pid.connect('value-changed', self.__update_filters) + + self.__update_filters() + + sort_by = EnumeratedListOption(_('Sort by'), 0 ) + idx = 0 + for item in _get_sort_functions(Sort.Sort(self.__db)): + sort_by.add_item(idx, item[0]) + idx += 1 + sort_by.set_help( _("Sorting method to use")) + menu.add_option(category_name, "sort_by", sort_by) + + sort_desc = BooleanOption(_("Sort descending"), False) + sort_desc.set_help(_("Set the sort order")) + menu.add_option(category_name, "sort_desc", sort_desc) + + family_events = BooleanOption(_("Include family events"), True) + family_events.set_help(_("Sort family events of the person")) + menu.add_option(category_name, "family_events", family_events) + + def __filter_changed(self): + """ + Handle filter change. If the filter is not specific to a person, + disable the person option + """ + filter_value = self.__filter.get_value() + if filter_value in [1, 2, 3, 4]: + # Filters 1, 2, 3 and 4 rely on the center person + self.__pid.set_available(True) + else: + # The rest don't + self.__pid.set_available(False) + + def __update_filters(self): + """ + Update the filter list based on the selected person + """ + gid = self.__pid.get_value() + person = self.__db.get_person_from_gramps_id(gid) + filter_list = ReportUtils.get_person_filters(person, False) + self.__filter.set_filters(filter_list) + + +#------------------------------------------------------------------------ +# +# +# +#------------------------------------------------------------------------ +pmgr = PluginManager.get_instance() +pmgr.register_tool( + name = 'sortevents', + category = Tool.TOOL_DBPROC, + tool_class = SortEvents, + options_class = SortEventOptions, + modes = PluginManager.TOOL_MODE_GUI, + translated_name = _("Sort Events"), + status = _("Stable"), + author_name = "Gary Burton", + author_email = "gary.burton@zen.co.uk", + description = _("Sorts events") + )