# # 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") )