From 543fda3d5d2cab93f4fca6c2b04bdbe1d471c50e Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 3 Oct 2013 18:06:50 +0000 Subject: [PATCH] Add new ancestor and descendant gramplets svn: r23244 --- gramps/plugins/gramplet/ancestor.py | 161 ++++++++++++++++++++ gramps/plugins/gramplet/descendant.py | 156 +++++++++++++++++++ gramps/plugins/gramplet/descendgramplet.py | 166 --------------------- gramps/plugins/gramplet/gramplet.gpr.py | 21 ++- gramps/plugins/tool/desbrowser.glade | 131 ---------------- gramps/plugins/tool/desbrowser.py | 149 ------------------ gramps/plugins/tool/tools.gpr.py | 23 --- 7 files changed, 336 insertions(+), 471 deletions(-) create mode 100644 gramps/plugins/gramplet/ancestor.py create mode 100644 gramps/plugins/gramplet/descendant.py delete mode 100644 gramps/plugins/gramplet/descendgramplet.py delete mode 100644 gramps/plugins/tool/desbrowser.glade delete mode 100644 gramps/plugins/tool/desbrowser.py diff --git a/gramps/plugins/gramplet/ancestor.py b/gramps/plugins/gramplet/ancestor.py new file mode 100644 index 000000000..f2751a7d5 --- /dev/null +++ b/gramps/plugins/gramplet/ancestor.py @@ -0,0 +1,161 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2013 Nick Hall +# +# 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$ + +"""Descendant Gramplet""" + +#------------------------------------------------------------------------ +# +# Python modules +# +#------------------------------------------------------------------------ +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext + +#------------------------------------------------------------------------- +# +# GTK modules +# +#------------------------------------------------------------------------- +from gi.repository import Gtk + +#------------------------------------------------------------------------ +# +# Gramps modules +# +#------------------------------------------------------------------------ +from gramps.gen.plug import Gramplet +from gramps.gui.listmodel import ListModel, NOSORT +from gramps.gui.editors import EditPerson +from gramps.gen.errors import WindowActiveError +from gramps.gen.display.name import displayer as name_displayer +from gramps.gen.datehandler import get_date +from gramps.gen.utils.db import get_birth_or_fallback, get_death_or_fallback + +class Ancestor(Gramplet): + + def init(self): + self.gui.WIDGET = self.build_gui() + self.gui.get_container_widget().remove(self.gui.textview) + self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET) + self.gui.WIDGET.show() + + def build_gui(self): + """ + Build the GUI interface. + """ + self.view = Gtk.TreeView() + self.view.set_tooltip_column(3) + titles = [(_('Name'), 0, 230), + (_('Birth'), 2, 100), + ('', NOSORT, 1), + ('', NOSORT, 1), # tooltip + ('', NOSORT, 100)] # handle + self.model = ListModel(self.view, titles, list_mode="tree", + event_func=self.cb_double_click) + return self.view + + def get_has_data(self, active_handle): + """ + Return True if the gramplet has data, else return False. + """ + if active_handle is None: + return False + person = self.dbstate.db.get_person_from_handle(active_handle) + family_handle = person.get_main_parents_family_handle() + family = self.dbstate.db.get_family_from_handle(family_handle) + if family and (family.get_father_handle() or + family.get_mother_handle()): + return True + return False + + def cb_double_click(self, treeview): + """ + Handle double click on treeview. + """ + (model, iter_) = treeview.get_selection().get_selected() + if not iter_: + return + + try: + handle = model.get_value(iter_, 4) + person = self.dbstate.db.get_person_from_handle(handle) + EditPerson(self.dbstate, self.uistate, [], person) + except WindowActiveError: + pass + + def db_changed(self): + self.update() + + def active_changed(self, handle): + self.update() + + def update_has_data(self): + active_handle = self.get_active('Person') + self.set_has_data(self.get_has_data(active_handle)) + + def main(self): + active_handle = self.get_active('Person') + self.model.clear() + if active_handle: + self.add_to_tree(None, active_handle) + self.view.expand_all() + self.set_has_data(self.get_has_data(active_handle)) + else: + self.set_has_data(False) + + def add_to_tree(self, parent_id, person_handle): + person = self.dbstate.db.get_person_from_handle(person_handle) + name = name_displayer.display(person) + + birth = get_birth_or_fallback(self.dbstate.db, person) + death = get_death_or_fallback(self.dbstate.db, person) + + birth_text = birth_date = birth_sort = '' + if birth: + birth_date = get_date(birth) + birth_sort = '%012d' % birth.get_date_object().get_sort_value() + birth_text = _('%(abbr)s %(date)s') % \ + {'abbr': birth.type.get_abbreviation(), + 'date': birth_date} + + death_date = death_sort = death_text = '' + if death: + death_date = get_date(death) + death_sort = '%012d' % death.get_date_object().get_sort_value() + death_text = _('%(abbr)s %(date)s') % \ + {'abbr': death.type.get_abbreviation(), + 'date': death_date} + + tooltip = name + '\n' + birth_text + '\n' + death_text + + item_id = self.model.add([name, birth_date, birth_sort, + tooltip, person_handle], node=parent_id) + + family_handle = person.get_main_parents_family_handle() + family = self.dbstate.db.get_family_from_handle(family_handle) + if family: + if family.get_father_handle(): + self.add_to_tree(item_id, family.get_father_handle()) + if family.get_mother_handle(): + self.add_to_tree(item_id, family.get_mother_handle()) + + return item_id diff --git a/gramps/plugins/gramplet/descendant.py b/gramps/plugins/gramplet/descendant.py new file mode 100644 index 000000000..f2e18b211 --- /dev/null +++ b/gramps/plugins/gramplet/descendant.py @@ -0,0 +1,156 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2013 Nick Hall +# +# 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$ + +"""Descendant Gramplet""" + +#------------------------------------------------------------------------ +# +# Python modules +# +#------------------------------------------------------------------------ +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext + +#------------------------------------------------------------------------- +# +# GTK modules +# +#------------------------------------------------------------------------- +from gi.repository import Gtk + +#------------------------------------------------------------------------ +# +# Gramps modules +# +#------------------------------------------------------------------------ +from gramps.gen.plug import Gramplet +from gramps.gui.listmodel import ListModel, NOSORT +from gramps.gui.editors import EditPerson +from gramps.gen.errors import WindowActiveError +from gramps.gen.display.name import displayer as name_displayer +from gramps.gen.datehandler import get_date +from gramps.gen.utils.db import get_birth_or_fallback, get_death_or_fallback + +class Descendant(Gramplet): + + def init(self): + self.gui.WIDGET = self.build_gui() + self.gui.get_container_widget().remove(self.gui.textview) + self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET) + self.gui.WIDGET.show() + + def build_gui(self): + """ + Build the GUI interface. + """ + self.view = Gtk.TreeView() + self.view.set_tooltip_column(3) + titles = [(_('Name'), 0, 230), + (_('Birth'), 2, 100), + ('', NOSORT, 1), + ('', NOSORT, 1), # tooltip + ('', NOSORT, 100)] # handle + self.model = ListModel(self.view, titles, list_mode="tree", + event_func=self.cb_double_click) + return self.view + + def get_has_data(self, active_handle): + """ + Return True if the gramplet has data, else return False. + """ + if active_handle is None: + return False + person = self.dbstate.db.get_person_from_handle(active_handle) + for family_handle in person.get_family_handle_list(): + family = self.dbstate.db.get_family_from_handle(family_handle) + for child_ref in family.get_child_ref_list(): + return True + return False + + def cb_double_click(self, treeview): + """ + Handle double click on treeview. + """ + (model, iter_) = treeview.get_selection().get_selected() + if not iter_: + return + + try: + handle = model.get_value(iter_, 4) + person = self.dbstate.db.get_person_from_handle(handle) + EditPerson(self.dbstate, self.uistate, [], person) + except WindowActiveError: + pass + + def db_changed(self): + self.update() + + def active_changed(self, handle): + self.update() + + def update_has_data(self): + active_handle = self.get_active('Person') + self.set_has_data(self.get_has_data(active_handle)) + + def main(self): + active_handle = self.get_active('Person') + self.model.clear() + if active_handle: + self.add_to_tree(None, active_handle) + self.view.expand_all() + self.set_has_data(self.get_has_data(active_handle)) + else: + self.set_has_data(False) + + def add_to_tree(self, parent_id, person_handle): + person = self.dbstate.db.get_person_from_handle(person_handle) + name = name_displayer.display(person) + + birth = get_birth_or_fallback(self.dbstate.db, person) + death = get_death_or_fallback(self.dbstate.db, person) + + birth_text = birth_date = birth_sort = '' + if birth: + birth_date = get_date(birth) + birth_sort = '%012d' % birth.get_date_object().get_sort_value() + birth_text = _('%(abbr)s %(date)s') % \ + {'abbr': birth.type.get_abbreviation(), + 'date': birth_date} + + death_date = death_sort = death_text = '' + if death: + death_date = get_date(death) + death_sort = '%012d' % death.get_date_object().get_sort_value() + death_text = _('%(abbr)s %(date)s') % \ + {'abbr': death.type.get_abbreviation(), + 'date': death_date} + + tooltip = name + '\n' + birth_text + '\n' + death_text + + item_id = self.model.add([name, birth_date, birth_sort, + tooltip, person_handle], node=parent_id) + + for family_handle in person.get_family_handle_list(): + family = self.dbstate.db.get_family_from_handle(family_handle) + for child_ref in family.get_child_ref_list(): + self.add_to_tree(item_id, child_ref.ref) + return item_id diff --git a/gramps/plugins/gramplet/descendgramplet.py b/gramps/plugins/gramplet/descendgramplet.py deleted file mode 100644 index a97307703..000000000 --- a/gramps/plugins/gramplet/descendgramplet.py +++ /dev/null @@ -1,166 +0,0 @@ -# -# Gramps - a GTK+/GNOME based genealogy program -# -# Copyright (C) 2000-2007 Donald N. Allingham -# Copyright (C) 2007-2008 Brian G. Matherly -# Copyright (C) 2008 Douglas S. Blank -# Copyright (C) 2010 Jakim Friant -# -# 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$ - -"""Descendant Gramplet""" - -#------------------------------------------------------------------------ -# -# standard python modules -# -#------------------------------------------------------------------------ -from gramps.gen.const import GRAMPS_LOCALE as glocale -_ = glocale.translation.gettext - -#------------------------------------------------------------------------ -# -# GRAMPS modules -# -#------------------------------------------------------------------------ -from gramps.gen.plug import Gramplet -from gramps.gen.plug.report import utils as ReportUtils -from gramps.gen.display.name import displayer as name_displayer -from gramps.gen.datehandler import get_date -from gramps.gen.utils.db import get_birth_or_fallback, get_death_or_fallback - -class DescendantGramplet(Gramplet): - def init(self): - self.set_text(_("No Family Tree loaded.")) - self.set_tooltip(_("Move mouse over links for options")) - self.set_use_markup(True) - self.no_wrap() - self.max_generations = 100 - - def db_changed(self): - self.update() - - def active_changed(self, handle): - self.update() - - def main(self): - active_handle = self.get_active('Person') - if not active_handle: - self.set_text(_("No Active Person selected.")) - return - self.set_text("") - self.center_person = self.dbstate.db.get_person_from_handle(active_handle) - if self.center_person is None: - return - name = name_displayer.display(self.center_person) - # feature request 2356: avoid genitive form - title = _("Descendants of %s") % name - self.append_text(title) - self.append_text("\n\n") - self.dump(1,self.center_person) - self.append_text("", scroll_to="begin") - - def dump_dates(self, person): - birth = get_birth_or_fallback(self.dbstate.db, person) - death = get_death_or_fallback(self.dbstate.db, person) - - if birth: - birth_date = get_date(birth) - - if death: - death_date = get_date(death) - - if birth or death: - self.append_text(' (') - - birth_place = "" - if birth: - bplace_handle = birth.get_place_handle() - if bplace_handle: - birth_place = self.dbstate.db.get_place_from_handle( - bplace_handle).get_title() - - death_place = "" - if death: - dplace_handle = death.get_place_handle() - if dplace_handle: - death_place = self.dbstate.db.get_place_from_handle( - dplace_handle).get_title() - - if birth: - if birth_place: - self.append_text("%(event_abbrev)s %(birth_date)s - %(place)s" % { - 'event_abbrev': birth.type.get_abbreviation(), - 'birth_date' : birth_date, - 'place' : birth_place, - }) - else: - self.append_text("%(event_abbrev)s %(birth_date)s" % { - 'event_abbrev': birth.type.get_abbreviation(), - 'birth_date' : birth_date - }) - - if death: - if birth: - self.append_text(', ') - if death_place: - self.append_text("%(event_abbrev)s %(death_date)s - %(place)s" % { - 'event_abbrev': death.type.get_abbreviation(), - 'death_date' : death_date, - 'place' : death_place, - }) - else: - self.append_text("%(event_abbrev)s %(death_date)s" % { - 'event_abbrev': death.type.get_abbreviation(), - 'death_date' : death_date - }) - - self.append_text(')') - - def dump(self,level,person): - self.append_text(" " * (level - 1)) - self.append_text("%s. " % level) - self.link(name_displayer.display_name(person.get_primary_name()), - 'Person', person.handle, - tooltip=_("Click to make active\n") + \ - _("Right-click to edit")) - self.dump_dates(person) - self.append_text("\n") - - if level >= self.max_generations: - return - - for family_handle in person.get_family_handle_list(): - family = self.dbstate.db.get_family_from_handle(family_handle) - - spouse_handle = ReportUtils.find_spouse(person,family) - if spouse_handle: - spouse = self.dbstate.db.get_person_from_handle(spouse_handle) - self.append_text(" " * (level - 1)) - self.append_text(_(" sp. ")) - self.link(name_displayer.display_name(spouse.get_primary_name()), - 'Person', spouse.handle, - tooltip=_("Click to make active\n") + \ - _("Right-click to edit")) - self.dump_dates(spouse) - self.append_text("\n") - - childlist = family.get_child_ref_list()[:] - for child_ref in childlist: - child = self.dbstate.db.get_person_from_handle(child_ref.ref) - self.dump(level+1,child) diff --git a/gramps/plugins/gramplet/gramplet.gpr.py b/gramps/plugins/gramplet/gramplet.gpr.py index eb1a7bb3b..b31b199a2 100644 --- a/gramps/plugins/gramplet/gramplet.gpr.py +++ b/gramps/plugins/gramplet/gramplet.gpr.py @@ -84,10 +84,10 @@ register(GRAMPLET, name=_("Descendant"), description = _("Gramplet showing active person's descendants"), status = STABLE, - fname="descendgramplet.py", + fname="descendant.py", height=100, expand=True, - gramplet = 'DescendantGramplet', + gramplet = 'Descendant', gramplet_title=_("Descendants"), detached_width = 500, detached_height = 500, @@ -96,6 +96,23 @@ register(GRAMPLET, navtypes=["Person"], ) +register(GRAMPLET, + id = "Ancestor", + name=_("Ancestor"), + description = _("Gramplet showing active person's ancestors"), + status = STABLE, + fname="ancestor.py", + height=100, + expand=True, + gramplet = 'Ancestor', + gramplet_title=_("Ancestors"), + detached_width = 500, + detached_height = 500, + version="1.0.0", + gramps_target_version="4.1", + navtypes=["Person"], + ) + register(GRAMPLET, id= "Fan Chart", name=_("Fan Chart"), diff --git a/gramps/plugins/tool/desbrowser.glade b/gramps/plugins/tool/desbrowser.glade deleted file mode 100644 index b162dac11..000000000 --- a/gramps/plugins/tool/desbrowser.glade +++ /dev/null @@ -1,131 +0,0 @@ - - - - - True - False - 450 - 400 - dialog - - - - True - False - - - True - False - end - - - gtk-close - False - True - True - True - False - False - True - - - - False - False - 0 - - - - - gtk-help - False - True - True - True - False - False - True - - - - False - False - 1 - - - - - False - True - end - 0 - - - - - True - False - - - True - False - center - - - False - False - 10 - 0 - - - - - True - False - in - - - True - False - - - - - - - - True - True - 1 - - - - - True - False - Double-click on the row to edit personal information - - - - - - False - False - 2 - - - - - False - True - 1 - - - - - - button1 - button2 - - - diff --git a/gramps/plugins/tool/desbrowser.py b/gramps/plugins/tool/desbrowser.py deleted file mode 100644 index ded1da3fe..000000000 --- a/gramps/plugins/tool/desbrowser.py +++ /dev/null @@ -1,149 +0,0 @@ -# -# Gramps - a GTK+/GNOME based genealogy program -# -# Copyright (C) 2000-2007 Donald N. Allingham -# Copyright (C) 2008 Brian G. Matherly -# Copyright (C) 2010 Jakim Friant -# -# 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/Analysis and Exploration/Interactive Descendant Browser""" - -#------------------------------------------------------------------------ -# -# GTK/GNOME modules -# -#------------------------------------------------------------------------ -from gi.repository import Gdk -from gi.repository import Gtk - -#------------------------------------------------------------------------ -# -# GRAMPS modules -# -#------------------------------------------------------------------------ -from gramps.gen.const import URL_MANUAL_PAGE -from gramps.gen.display.name import displayer as name_displayer -from gramps.gui.plug import tool -from gramps.gui.display import display_help -from gramps.gui.managedwindow import ManagedWindow -from gramps.gen.const import GRAMPS_LOCALE as glocale -_ = glocale.translation.sgettext -from gramps.gui.glade import Glade -from gramps.gui.editors import EditPerson - -#------------------------------------------------------------------------ -# -# Constants -# -#------------------------------------------------------------------------ -WIKI_HELP_PAGE = '%s_-_Tools' % URL_MANUAL_PAGE -WIKI_HELP_SEC = _('manual|Interactive_Descendant_Browser...') - -class DesBrowse(tool.ActivePersonTool, ManagedWindow): - - def __init__(self, dbstate, user, options_class, name, callback=None): - uistate = user.uistate - - tool.ActivePersonTool.__init__(self, dbstate, uistate, options_class, - name) - if self.fail: - return - - self.dbstate = dbstate - active_handle = uistate.get_active('Person') - self.active = dbstate.db.get_person_from_handle(active_handle) - self.callback = callback - self.active_name = _("Descendant Browser: %s") % ( - name_displayer.display(self.active) - ) - - ManagedWindow.__init__(self, uistate, [], self) - - self.glade = Glade() - self.glade.connect_signals({ - "destroy_passed_object" : self.close, - "on_help_clicked" : self.on_help_clicked, - "on_delete_event" : self.close, - }) - - window = self.glade.toplevel - self.set_window(window,self.glade.get_object('title'), - self.active_name) - - self.tree = self.glade.get_object("tree1") - col = Gtk.TreeViewColumn('',Gtk.CellRendererText(),text=0) - self.tree.append_column(col) - self.tree.set_rules_hint(True) - self.tree.set_headers_visible(False) - self.tree.connect('button-press-event', self.button_press_event) - self.make_new_model() - - self.show() - - def build_menu_names(self, obj): - return (self.active_name,_("Descendant Browser tool")) - - def make_new_model(self): - self.model = Gtk.TreeStore(str, object) - self.tree.set_model(self.model) - self.add_to_tree(None, None, self.active.get_handle()) - self.tree.expand_all() - - def on_help_clicked(self, obj): - """Display the relevant portion of GRAMPS manual""" - display_help(webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC) - - def add_to_tree(self, parent_id, sib_id, person_handle): - item_id = self.model.insert_after(parent_id, sib_id) - person = self.db.get_person_from_handle(person_handle) - - self.model.set(item_id, 0, name_displayer.display(person)) - self.model.set(item_id, 1, person_handle) - prev_id = None - for family_handle in person.get_family_handle_list(): - family = self.db.get_family_from_handle(family_handle) - for child_ref in family.get_child_ref_list(): - prev_id = self.add_to_tree(item_id, prev_id, child_ref.ref) - return item_id - - def button_press_event(self, obj, event): - if event.type == Gdk.EventType._2BUTTON_PRESS and event.button == 1: - store, node = self.tree.get_selection().get_selected() - if node: - person_handle = store.get_value(node, 1) - person = self.db.get_person_from_handle(person_handle) - EditPerson(self.dbstate, self.uistate, self.track, person, - self.this_callback) - - def this_callback(self, obj): - self.callback() - self.make_new_model() - -#------------------------------------------------------------------------ -# -# -# -#------------------------------------------------------------------------ -class DesBrowseOptions(tool.ToolOptions): - """ - Defines options and provides handling interface. - """ - - def __init__(self, name,person_id=None): - tool.ToolOptions.__init__(self, name,person_id) diff --git a/gramps/plugins/tool/tools.gpr.py b/gramps/plugins/tool/tools.gpr.py index 310ee17c3..d7bb35586 100644 --- a/gramps/plugins/tool/tools.gpr.py +++ b/gramps/plugins/tool/tools.gpr.py @@ -93,29 +93,6 @@ optionclass = 'CheckOptions', tool_modes = [TOOL_MODE_GUI, TOOL_MODE_CLI] ) -#------------------------------------------------------------------------ -# -# Interactive Descendant Browser -# -#------------------------------------------------------------------------ - -register(TOOL, -id = 'dbrowse', -name = _("Interactive Descendant Browser"), -description = _("Provides a browsable hierarchy based on the active person"), -version = '1.0', -gramps_target_version = '4.1', -status = STABLE, -fname = 'desbrowser.py', -authors = ["Donald N. Allingham"], -authors_email = ["don@gramps-project.org"], -category = TOOL_ANAL, -toolclass = 'DesBrowse', -optionclass = 'DesBrowseOptions', -tool_modes = [TOOL_MODE_GUI] - ) - - #------------------------------------------------------------------------ # # Compare Individual Events