gramps/gramps2/src/PedView.py

923 lines
34 KiB
Python
Raw Normal View History

2002-10-20 19:55:16 +05:30
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2001-2005 Donald N. Allingham
2002-10-20 19:55:16 +05:30
#
# 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$
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gobject
2002-10-20 19:55:16 +05:30
import gtk
import gtk.gdk
#-------------------------------------------------------------------------
#
# Gramps Modules
#
#-------------------------------------------------------------------------
2005-08-09 20:52:21 +05:30
import RelLib
import PageView
2005-08-09 20:52:21 +05:30
import EditPerson
2005-01-01 09:57:15 +05:30
import NameDisplay
2005-06-04 04:08:14 +05:30
import Utils
import DateHandler
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
2004-01-03 01:56:30 +05:30
_PERSON = "p"
2003-05-24 09:10:58 +05:30
_BORN = _('b.')
_DIED = _('d.')
_BAPT = _('bap.')
_CHRI = _('chr.')
_BURI = _('bur.')
_CREM = _('crem.')
2003-05-24 09:10:58 +05:30
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# PedigreeView
#
#-------------------------------------------------------------------------
class PedView(PageView.PageView):
def __init__(self,state):
PageView.PageView.__init__(self,'Pedigree View',state)
self.inactive = False
state.connect('database-changed',self.change_db)
state.connect('active-changed',self.goto_active_person)
self.force_size = 0 # Automatic resize
def build_widget(self):
self.notebook = gtk.Notebook()
self.notebook.connect("button-press-event", self.on_show_option_menu_cb)
2005-08-09 20:52:21 +05:30
self.bootstrap_handler = self.notebook.connect("expose-event", self.init_parent_signals_cb)
self.notebook.set_show_border(False)
self.notebook.set_show_tabs(False)
self.table_2 = gtk.Table(1,1,False)
self.table_2.connect("button-press-event", self.on_show_option_menu_cb)
self.add_table_to_notebook( self.table_2)
self.table_3 = gtk.Table(1,1,False)
self.table_3.connect("button-press-event", self.on_show_option_menu_cb)
self.add_table_to_notebook( self.table_3)
self.table_4 = gtk.Table(1,1,False)
self.table_4.connect("button-press-event", self.on_show_option_menu_cb)
self.add_table_to_notebook( self.table_4)
self.table_5 = gtk.Table(1,1,False)
self.table_5.connect("button-press-event", self.on_show_option_menu_cb)
self.add_table_to_notebook( self.table_5)
self.rebuild_trees(None)
return self.notebook
2002-10-20 19:55:16 +05:30
2005-08-09 20:52:21 +05:30
def init_parent_signals_cb(self, widget, event):
print "PedView.init_parent_signals_cb"
self.notebook.disconnect(self.bootstrap_handler)
self.notebook.parent.connect("size-allocate", self.size_request_cb)
self.size_request_cb(widget.parent,event)
def add_table_to_notebook( self, table):
frame = gtk.ScrolledWindow(None,None)
frame.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
frame.add_with_viewport(table)
try:
self.notebook.append_page(frame,None)
except:
# for PyGtk < 2.4
self.notebook.append_page(frame,gtk.Label(""))
def define_actions(self):
#self.add_action('Add', gtk.STOCK_ADD, "_Add", callback=self.add)
#self.add_action('Edit', gtk.STOCK_EDIT, "_Edit", callback=self.edit)
#self.add_action('Remove', gtk.STOCK_REMOVE, "_Remove", callback=self.remove)
self.add_action('Forward',gtk.STOCK_GO_FORWARD,"_Forward", callback=self.home)#callback=self.fwd_clicked)
self.add_action('Back', gtk.STOCK_GO_BACK, "_Back", callback=self.home)#callback=self.back_clicked)
self.add_action('HomePerson', gtk.STOCK_HOME, "_Home", callback=self.home)
#self.add_toggle_action('Filter', None, '_Filter', callback=self.filter_toggle)
# add the Forward action group to handle the Forward button
self.fwd_action = gtk.ActionGroup(self.title + '/Forward')
self.fwd_action.add_actions([
('Forward',gtk.STOCK_GO_FORWARD,"_Forward", None, None, self.home)#callback=self.fwd_clicked)
])
# add the Backward action group to handle the Forward button
self.back_action = gtk.ActionGroup(self.title + '/Backward')
self.back_action.add_actions([
('Back',gtk.STOCK_GO_BACK,"_Back", None, None, self.home)#callback=self.back_clicked)
])
self.add_action_group(self.back_action)
self.add_action_group(self.fwd_action)
def disable_action_group(self):
"""
Normally, this would not be overridden from the base class. However,
in this case, we have additional action groups that need to be
handled correctly.
"""
PageView.PageView.disable_action_group(self)
self.fwd_action.set_visible(False)
self.back_action.set_visible(False)
def enable_action_group(self,obj):
"""
Normally, this would not be overridden from the base class. However,
in this case, we have additional action groups that need to be
handled correctly.
"""
PageView.PageView.enable_action_group(self,obj)
self.fwd_action.set_visible(True)
self.back_action.set_visible(True)
hobj = self.state.phistory
self.fwd_action.set_sensitive(not hobj.at_end())
self.back_action.set_sensitive(not hobj.at_front())
def ui_definition(self):
return '''<ui>
<menubar name="MenuBar">
<menu action="GoMenu">
<placeholder name="CommonGo">
<menuitem action="HomePerson"/>
</placeholder>
</menu>
</menubar>
<toolbar name="ToolBar">
<placeholder name="CommonNavigation">
<toolitem action="Back"/>
<toolitem action="Forward"/>
<toolitem action="HomePerson"/>
</placeholder>
</toolbar>
</ui>'''
def get_stock(self):
return 'gramps-pedigree'
def change_db(self,db):
# Reconnect signals
self.db = db
db.connect('person-add', self.person_updated_cb)
db.connect('person-update', self.person_updated_cb)
db.connect('person-delete', self.person_updated_cb)
db.connect('person-rebuild', self.person_rebuild)
self.rebuild_trees(None)
def person_updated_cb(self,handle_list):
print "PedView.person_updated_cb"
self.rebuild_trees(self.state.active)
def person_rebuild(self):
print "PedView.person_rebuild"
self.rebuild_trees(self.state.active)
def person_edited_cb(self, p1=None, p2=None):
print "PedView.person_edited_cb"
def goto_active_person(self,handle):
print "PedView.goto_active_person"
if handle:
self.rebuild_trees(self.db.get_person_from_handle(handle))
else:
self.rebuild_trees(None)
def request_resize(self):
print "PedView.request_resize"
self.size_request_cb(self.notebook.parent,None,None)
2002-10-20 19:55:16 +05:30
def size_request_cb(self, widget, event, data=None):
2005-08-09 20:52:21 +05:30
print "PedView.size_request_cb"
if self.force_size == 0:
v = widget.get_allocation()
page_list = range(0,self.notebook.get_n_pages())
page_list.reverse()
for n in page_list:
p = self.notebook.get_nth_page(n).get_child().get_child().get_allocation()
if v.width >= p.width and v.height > p.height:
self.notebook.set_current_page(n)
break;
else:
self.notebook.set_current_page(self.force_size-2)
def rebuild_trees(self,person):
pos_2 =((0,3,3,(3,4,5)),
(2,0,3,None),
(2,10,3,None))
pos_3 =((0,4,5,(3,6,3)),
(2,1,3,(5,2,3)),
(2,9,3,(5,10,3)),
(4,0,1,None),
(4,4,1,None),
(4,8,1,None),
(4,12,1,None))
pos_4 =((0, 5,5,(3, 7,5)),
(2, 2,3,(5, 3,3)),
(2,10,3,(5,11,3)),
(4, 1,1,(7,1,1)),
(4, 5,1,(7,5,1)),
(4, 9,1,(7,9,1)),
(4,13,1,(7,13,1)),
(6, 0,1,None),
(6, 2,1,None),
(6, 4,1,None),
(6, 6,1,None),
(6, 8,1,None),
(6,10,1,None),
(6,12,1,None),
(6,14,1,None),)
pos_5 =((0,10,11,(3,15,3)),
(2, 5,5,(5, 7,1)),
(2,21,5,(5,23,1)),
(4, 2,3,(7,3,1)),
(4,10,3,(7,11,1)),
(4,18,3,(7,19,1)),
(4,26,3,(7,27,1)),
(6, 1,1,(9,1,1)),
(6, 5,1,(9,5,1)),
(6, 9,1,(9,9,1)),
(6,13,1,(9,13,1)),
(6,17,1,(9,17,1)),
(6,21,1,(9,21,1)),
(6,25,1,(9,25,1)),
(6,29,1,(9,29,1)),
(8, 0,1,None),
(8, 2,1,None),
(8, 4,1,None),
(8, 6,1,None),
(8, 8,1,None),
(8,10,1,None),
(8,12,1,None),
(8,14,1,None),
(8,16,1,None),
(8,18,1,None),
(8,20,1,None),
(8,22,1,None),
(8,24,1,None),
(8,26,1,None),
(8,28,1,None),
(8,30,1,None),)
self.rebuild( self.table_2, pos_2, person)
self.rebuild( self.table_3, pos_3, person)
self.rebuild( self.table_4, pos_4, person)
self.rebuild( self.table_5, pos_5, person)
#gobject.idle_add(self.request_resize)
def rebuild( self, table_widget, positions, active_person):
print "PedView.rebuild"
# Build ancestor tree
lst = [None]*31
self.find_tree(active_person,0,1,lst)
2002-10-20 19:55:16 +05:30
# Purge current table content
for child in table_widget.get_children():
child.destroy()
table_widget.resize(1,1)
2002-10-20 19:55:16 +05:30
tooltip = gtk.Tooltips()
debug = False
if debug:
xmax = 0
ymax = 0
for field in positions:
x = field[0]+3
if x > xmax:
xmax = x
y = field[1]+field[2]
if y > ymax:
ymax = y
for x in range(0,xmax):
for y in range(0,ymax):
label=gtk.Label("%d,%d"%(x,y))
frame = gtk.ScrolledWindow(None,None)
frame.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
frame.set_policy(gtk.POLICY_NEVER,gtk.POLICY_NEVER)
frame.add(label)
table_widget.attach(frame,x,x+1,y,y+1,0,0,0,0)
2002-10-20 19:55:16 +05:30
for i in range(0,31):
try:
# Table placement for person data
x = positions[i][0]
y = positions[i][1]
w = 3
h = positions[i][2]
if not lst[i]:
# No person -> show empty box
label = gtk.Label(" ")
frame = gtk.ScrolledWindow(None,None)
frame.set_shadow_type(gtk.SHADOW_OUT)
frame.set_policy(gtk.POLICY_NEVER,gtk.POLICY_NEVER)
frame.add_with_viewport(label)
if positions[i][2] > 1:
table_widget.attach(frame,x,x+w,y,y+h,gtk.EXPAND|gtk.FILL,gtk.EXPAND|gtk.FILL,0,0)
else:
table_widget.attach(frame,x,x+w,y,y+h,gtk.EXPAND|gtk.FILL,gtk.FILL,0,0)
else:
text = gtk.Button(self.format_person(lst[i][0], positions[i][2]))
if i > 0 and positions[i][2] < 3:
tooltip.set_tip(text, self.format_person(lst[i][0], 11))
text.set_alignment(0.0,0.0)
gender = lst[i][0].get_gender()
if gender == RelLib.Person.MALE:
text.modify_bg( gtk.STATE_NORMAL, text.get_colormap().alloc_color("#F5FFFF"))
elif gender == RelLib.Person.FEMALE:
text.modify_bg( gtk.STATE_NORMAL, text.get_colormap().alloc_color("#FFF5FF"))
else:
text.modify_bg( gtk.STATE_NORMAL, text.get_colormap().alloc_color("#FFFFF5"))
white = text.get_colormap().alloc_color("white")
text.modify_bg( gtk.STATE_ACTIVE, white)
text.modify_bg( gtk.STATE_PRELIGHT, white)
text.modify_bg( gtk.STATE_SELECTED, white)
text.set_data(_PERSON,lst[i][0].get_handle())
text.connect("button-press-event", self.build_full_nav_menu_cb)
if positions[i][2] > 1:
table_widget.attach(text,x,x+w,y,y+h,gtk.EXPAND|gtk.FILL,gtk.EXPAND|gtk.FILL,0,0)
else:
table_widget.attach(text,x,x+w,y,y+h,gtk.EXPAND|gtk.FILL,gtk.FILL,0,0)
# Connection lines
if i > 0:
x = positions[i][0]-1
y = positions[i][1]
w = 1
h = positions[i][2]
line = gtk.DrawingArea()
line.connect("expose-event", self.line_expose_cb)
line.set_data("idx", i)
line.set_data("rela", lst[i][1])
table_widget.attach(line,x,x+w,y,y+h,gtk.FILL,gtk.FILL,0,0)
# Marriage data
if positions[i][3]:
# An empty label is used as fallback, to allow it to EXPAND.
# This gives a nicer layout
text = " "
try:
if lst[i] and lst[i][2]:
text = self.format_relation( lst[i][2], positions[i][3][2])
except IndexError:
pass
label = gtk.Label(text)
label.set_justify(gtk.JUSTIFY_LEFT)
label.set_line_wrap(True)
label.set_alignment(0.1,0.0)
x = positions[i][3][0]
y = positions[i][3][1]
w = 2
h = 1
if positions[i][3][2] > 1:
table_widget.attach(label,x,x+w,y,y+h,gtk.EXPAND|gtk.FILL,gtk.EXPAND|gtk.FILL,0,0)
else:
table_widget.attach(label,x,x+w,y,y+h,gtk.EXPAND|gtk.FILL,gtk.FILL,0,0)
except IndexError:
pass
table_widget.show_all()
def line_expose_cb(self, area, event):
style = area.get_style()
gc = style.fg_gc[gtk.STATE_NORMAL]
alloc = area.get_allocation()
idx = area.get_data("idx")
rela = area.get_data("rela")
if rela:
gc.line_style = gtk.gdk.LINE_ON_OFF_DASH
else:
gc.line_style = gtk.gdk.LINE_SOLID
gc.line_width = 3
if idx %2 == 0:
area.window.draw_line(gc, alloc.width, alloc.height/2, alloc.width/2, 0)
else:
area.window.draw_line(gc, alloc.width, alloc.height/2, alloc.width/2, alloc.height)
def home(self,obj):
print "PedView.home"
defperson = self.state.db.get_default_person()
if defperson:
self.state.change_active_person(defperson)
def edit_person_cb(self,obj):
person_handle = obj.get_data(_PERSON)
person = self.db.get_person_from_handle(person_handle)
if person:
EditPerson.EditPerson(self.state, person, self.person_edited_cb)
return True
2005-08-09 20:52:21 +05:30
return False
def on_show_option_menu_cb(self,obj,data=None):
myMenu = gtk.Menu()
self.add_settings_to_menu(myMenu)
myMenu.popup(None,None,None,0,0)
return(True);
2002-10-20 19:55:16 +05:30
def on_show_child_menu(self,obj):
"""User clicked button to move to child of active person"""
if self.state.active:
2002-10-20 19:55:16 +05:30
# Build and display the menu attached to the left pointing arrow
# button. The menu consists of the children of the current root
# person of the tree. Attach a child to each menu item.
childlist = find_children(self.db,self.state.active)
if len(childlist) == 1:
child = self.db.get_person_from_handle(childlist[0])
if child:
self.state.change_active_person(child)
elif len(childlist) > 1:
myMenu = gtk.Menu()
for child_handle in childlist:
child = self.db.get_person_from_handle(child_handle)
2005-01-01 09:57:15 +05:30
cname = NameDisplay.displayer.display(child)
menuitem = gtk.MenuItem(None)
if find_children(self.db,child):
label = gtk.Label('<b><i>%s</i></b>' % cname)
else:
label = gtk.Label(cname)
label.set_use_markup(True)
label.show()
label.set_alignment(0,0)
menuitem.add(label)
2002-10-20 19:55:16 +05:30
myMenu.append(menuitem)
menuitem.set_data(_PERSON,child_handle)
2002-10-20 19:55:16 +05:30
menuitem.connect("activate",self.on_childmenu_changed)
menuitem.show()
myMenu.popup(None,None,None,0,0)
return 1
return 0
2002-10-20 19:55:16 +05:30
def on_childmenu_changed(self,obj):
"""Callback for the pulldown menu selection, changing to the person
attached with menu item."""
person_handle = obj.get_data(_PERSON)
if person_handle:
self.state.change_active_handle(person_handle)
return True
return False
2002-10-20 19:55:16 +05:30
def change_force_size_cb(self,event,data):
if data in [0,2,3,4,5]:
self.force_size = data
self.size_request_cb(self.notebook.parent,None) # switch to matching size
def find_tree(self,person,index,depth,lst,val=0):
2002-10-20 19:55:16 +05:30
"""Recursively build a list of ancestors"""
if depth > 5 or person == None:
return
lst[index] = (person,val,None)
parent_families = person.get_parent_family_handle_list()
if parent_families:
(family_handle,m,f) = parent_families[0]
else:
return
if family_handle:
mrel = m != RelLib.Person.CHILD_BIRTH
frel = f != RelLib.Person.CHILD_BIRTH
family = self.db.get_family_from_handle(family_handle)
2002-10-20 19:55:16 +05:30
if family != None:
lst[index] = (person,val,family)
father_handle = family.get_father_handle()
if father_handle != None:
father = self.db.get_person_from_handle(father_handle)
self.find_tree(father,(2*index)+1,depth+1,lst,frel)
mother_handle = family.get_mother_handle()
if mother_handle != None:
mother = self.db.get_person_from_handle(mother_handle)
self.find_tree(mother,(2*index)+2,depth+1,lst,mrel)
2002-10-20 19:55:16 +05:30
2004-06-22 02:53:35 +05:30
def add_nav_portion_to_menu(self,menu):
"""
This function adds a common history-navigation portion
to the context menu. Used by both build_nav_menu() and
build_full_nav_menu() methods.
"""
#back_sensitivity = self.parent.hindex > 0
#fwd_sensitivity = self.parent.hindex + 1 < len(self.parent.history)
2004-06-22 01:29:48 +05:30
entries = [
#(gtk.STOCK_GO_BACK,self.parent.back_clicked,back_sensitivity),
#(gtk.STOCK_GO_FORWARD,self.parent.fwd_clicked,fwd_sensitivity),
2004-06-22 01:29:48 +05:30
#FIXME: revert to stock item when German gtk translation is fixed
#(gtk.STOCK_HOME,self.parent.on_home_clicked,1),
(_("Home"),self.home,1),
2004-06-22 01:29:48 +05:30
(None,None,0),
#(_("Set anchor"),self.on_anchor_set,1),
#(_("Remove anchor"),self.on_anchor_removed,1),
2004-06-22 01:29:48 +05:30
]
for stock_id,callback,sensitivity in entries:
item = gtk.ImageMenuItem(stock_id)
#FIXME: remove when German gtk translation is fixed
if stock_id == _("Home"):
im = gtk.image_new_from_stock(gtk.STOCK_HOME,gtk.ICON_SIZE_MENU)
im.show()
item.set_image(im)
if callback:
item.connect("activate",callback)
item.set_sensitive(sensitivity)
item.show()
menu.append(item)
2004-06-22 02:53:35 +05:30
def add_settings_to_menu(self,menu):
item = gtk.MenuItem(_("Tree size"))
item.set_submenu(gtk.Menu())
size_menu = item.get_submenu()
current_image = gtk.image_new_from_stock(gtk.STOCK_APPLY,gtk.ICON_SIZE_MENU)
current_image.show()
entry = gtk.ImageMenuItem(_("Automatic"))
entry.connect("activate", self.change_force_size_cb,0)
if self.force_size == 0:
entry.set_image(current_image)
entry.show()
size_menu.append(entry)
for n in range(2,6):
entry = gtk.ImageMenuItem(_("%d generations") % n)
if self.force_size == n:
entry.set_image(current_image)
entry.connect("activate", self.change_force_size_cb,n)
entry.show()
size_menu.append(entry)
size_menu.show()
item.show()
menu.append(item)
2004-06-22 01:29:48 +05:30
def build_full_nav_menu_cb(self,obj,event):
2004-06-22 01:29:48 +05:30
"""
2004-06-22 02:53:35 +05:30
Builds the full menu (including Siblings, Spouses, Children,
and Parents) with navigation.
2004-06-22 01:29:48 +05:30
"""
menu = gtk.Menu()
menu.set_title(_('People Menu'))
person_handle = obj.get_data(_PERSON)
person = self.db.get_person_from_handle(person_handle)
if not person:
return 0
go_image = gtk.image_new_from_stock(gtk.STOCK_JUMP_TO,gtk.ICON_SIZE_MENU)
go_image.show()
go_item = gtk.ImageMenuItem(NameDisplay.displayer.display(person))
go_item.set_image(go_image)
go_item.set_data(_PERSON,person_handle)
go_item.connect("activate",self.on_childmenu_changed)
go_item.show()
menu.append(go_item)
#edit_image = gtk.image_new_from_stock(gtk.STOCK_JUMP_TO,gtk.ICON_SIZE_MENU)
#edit_image.show()
edit_item = gtk.ImageMenuItem(gtk.STOCK_EDIT)
#edit_item.set_image(edit_image)
edit_item.set_data(_PERSON,person_handle)
edit_item.connect("activate",self.edit_person_cb)
edit_item.show()
menu.append(edit_item)
# Go over spouses and build their menu
item = gtk.MenuItem(_("Spouses"))
fam_list = person.get_family_handle_list()
no_spouses = 1
for fam_id in fam_list:
family = self.db.get_family_from_handle(fam_id)
if family.get_father_handle() == person.get_handle():
sp_id = family.get_mother_handle()
else:
sp_id = family.get_father_handle()
spouse = self.db.get_person_from_handle(sp_id)
if not spouse:
continue
if no_spouses:
no_spouses = 0
item.set_submenu(gtk.Menu())
sp_menu = item.get_submenu()
go_image = gtk.image_new_from_stock(gtk.STOCK_JUMP_TO,gtk.ICON_SIZE_MENU)
go_image.show()
sp_item = gtk.ImageMenuItem(NameDisplay.displayer.display(spouse))
sp_item.set_image(go_image)
sp_item.set_data(_PERSON,sp_id)
sp_item.connect("activate",self.on_childmenu_changed)
sp_item.show()
sp_menu.append(sp_item)
if no_spouses:
item.set_sensitive(0)
item.show()
menu.append(item)
# Go over siblings and build their menu
item = gtk.MenuItem(_("Siblings"))
pfam_list = person.get_parent_family_handle_list()
no_siblings = 1
for (f,mrel,frel) in pfam_list:
fam = self.db.get_family_from_handle(f)
sib_list = fam.get_child_handle_list()
for sib_id in sib_list:
if sib_id == person.get_handle():
continue
sib = self.db.get_person_from_handle(sib_id)
if not sib:
continue
if no_siblings:
no_siblings = 0
item.set_submenu(gtk.Menu())
sib_menu = item.get_submenu()
go_image = gtk.image_new_from_stock(gtk.STOCK_JUMP_TO,gtk.ICON_SIZE_MENU)
go_image.show()
sib_item = gtk.ImageMenuItem(NameDisplay.displayer.display(sib))
sib_item.set_image(go_image)
sib_item.set_data(_PERSON,sib_id)
sib_item.connect("activate",self.on_childmenu_changed)
sib_item.show()
sib_menu.append(sib_item)
if no_siblings:
item.set_sensitive(0)
item.show()
menu.append(item)
2004-06-22 02:53:35 +05:30
# Go over children and build their menu
item = gtk.MenuItem(_("Children"))
no_children = 1
childlist = find_children(self.db,person)
for child_handle in childlist:
child = self.db.get_person_from_handle(child_handle)
2004-06-22 02:53:35 +05:30
if not child:
continue
if no_children:
no_children = 0
item.set_submenu(gtk.Menu())
child_menu = item.get_submenu()
if find_children(self.db,child):
2005-01-01 09:57:15 +05:30
label = gtk.Label('<b><i>%s</i></b>' % NameDisplay.displayer.display(child))
2004-06-22 02:53:35 +05:30
else:
2005-01-01 09:57:15 +05:30
label = gtk.Label(NameDisplay.displayer.display(child))
2004-06-22 02:53:35 +05:30
go_image = gtk.image_new_from_stock(gtk.STOCK_JUMP_TO,gtk.ICON_SIZE_MENU)
go_image.show()
child_item = gtk.ImageMenuItem(None)
child_item.set_image(go_image)
label.set_use_markup(True)
2004-06-22 02:53:35 +05:30
label.show()
label.set_alignment(0,0)
child_item.add(label)
child_item.set_data(_PERSON,child_handle)
2004-06-22 02:53:35 +05:30
child_item.connect("activate",self.on_childmenu_changed)
child_item.show()
child_menu.append(child_item)
if no_children:
item.set_sensitive(0)
item.show()
menu.append(item)
2004-06-22 02:53:35 +05:30
# Go over parents and build their menu
item = gtk.MenuItem(_("Parents"))
no_parents = 1
par_list = find_parents(self.db,person)
2004-06-22 02:53:35 +05:30
for par_id in par_list:
par = self.db.get_person_from_handle(par_id)
2004-06-22 02:53:35 +05:30
if not par:
continue
if no_parents:
no_parents = 0
item.set_submenu(gtk.Menu())
par_menu = item.get_submenu()
if find_parents(self.db,par):
2005-01-01 09:57:15 +05:30
label = gtk.Label('<b><i>%s</i></b>' % NameDisplay.displayer.display(par))
2004-06-22 02:53:35 +05:30
else:
2005-01-01 09:57:15 +05:30
label = gtk.Label(NameDisplay.displayer.display(par))
2004-06-22 02:53:35 +05:30
go_image = gtk.image_new_from_stock(gtk.STOCK_JUMP_TO,gtk.ICON_SIZE_MENU)
go_image.show()
par_item = gtk.ImageMenuItem(None)
par_item.set_image(go_image)
label.set_use_markup(True)
2004-06-22 02:53:35 +05:30
label.show()
label.set_alignment(0,0)
par_item.add(label)
par_item.set_data(_PERSON,par_id)
par_item.connect("activate",self.on_childmenu_changed)
par_item.show()
par_menu.append(par_item)
if no_parents:
item.set_sensitive(0)
item.show()
menu.append(item)
# Add separator
item = gtk.MenuItem(None)
item.show()
menu.append(item)
# Add history-based navigation
self.add_nav_portion_to_menu(menu)
self.add_settings_to_menu(menu)
menu.popup(None,None,None,event.button,event.time)
return 1
2004-01-03 01:56:30 +05:30
def format_relation( self, family, line_count):
text = ""
for event_ref in family.get_event_ref_list():
event = self.db.get_event_from_handle(event_ref.ref)
if event:
if line_count < 3:
return DateHandler.get_date(event)
2005-06-04 04:08:14 +05:30
i,s = event.get_type()
name = Utils.family_relations[i]
text += name
text += "\n"
text += DateHandler.get_date(event)
text += "\n"
text += self.get_place_name(event.get_place_handle())
if line_count < 5:
return text;
break
return text
def get_place_name( self, place_handle):
text = ""
place = self.db.get_place_from_handle(place_handle)
if place:
place_title = self.db.get_place_from_handle(place_handle).get_title()
if place_title != "":
if len(place_title) > 25:
text = place_title[:24]+"..."
else:
text = place_title
return text
def format_person( self, person, line_count):
if not person:
return ""
name = NameDisplay.displayer.display(person)
if line_count < 3:
return name
birth_ref = person.get_birth_ref()
bd=""
bp=""
if birth_ref:
birth = self.db.get_event_from_handle(birth_ref.ref)
bd = DateHandler.get_date(birth)
bp = self.get_place_name(birth.get_place_handle())
death_ref = person.get_death_ref()
dd=""
dp=""
if death_ref:
death = self.db.get_event_from_handle(death_ref.ref)
dd = DateHandler.get_date(death)
dp = self.get_place_name(death.get_place_handle())
if line_count < 5:
return "%s\n* %s\n+ %s" % (name,bd,dd)
else:
return "%s\n* %s\n %s\n+ %s\n %s" % (name,bd,bp,dd,dp)
2004-06-22 02:53:35 +05:30
#-------------------------------------------------------------------------
#
# Function to return children's list of a person
#
#-------------------------------------------------------------------------
def find_children(db,p):
"""
Returns the list of all children's IDs for a person.
"""
childlist = []
for family_handle in p.get_family_handle_list():
family = db.get_family_from_handle(family_handle)
for child_handle in family.get_child_handle_list():
childlist.append(child_handle)
2004-06-22 02:53:35 +05:30
return childlist
#-------------------------------------------------------------------------
#
# Function to return parent's list of a person
#
#-------------------------------------------------------------------------
def find_parents(db,p):
"""
Returns the unique list of all parents' IDs for a person.
"""
parentlist = []
for (f,mrel,frel) in p.get_parent_family_handle_list():
family = db.get_family_from_handle(f)
father_handle = family.get_father_handle()
mother_handle = family.get_mother_handle()
if father_handle not in parentlist:
parentlist.append(father_handle)
if mother_handle not in parentlist:
parentlist.append(mother_handle)
2004-06-22 02:53:35 +05:30
return parentlist
#-------------------------------------------------------------------------
#
# Functions to build the text displayed in the details view of a DispBox
# aditionally used by PedigreeView to get the largest area covered by a DispBox
#
#-------------------------------------------------------------------------
def build_detail_string(db,person):
detail_text = NameDisplay.displayer.display(person)
def format_event(db, label, event):
if not event:
return u""
ed = DateHandler.get_date(event)
ep = None
place_handle = event.get_place_handle()
if place_handle:
place_title = db.get_place_from_handle(place_handle).get_title()
if place_title != "":
if len(place_title) > 15:
ep = place_title[:14]+"..."
else:
ep = place_title
if ep:
return u"\n%s %s, %s" % (label,ed,ep)
return u"\n%s %s" % (label,ed)
birth_ref = person.get_birth_ref()
if birth_ref:
detail_text += format_event(db, _BORN,
db.get_event_from_handle(birth_ref.ref))
else:
for event_ref in person.get_event_ref_list():
event = db.get_event_from_handle(event_ref.ref)
if event and event.get_type()[0] == RelLib.Event.BAPTISM:
detail_text += format_event(db, _BAPT, event)
break
if event and event.get_type()[0] == RelLib.Event.CHRISTEN:
detail_text += format_event(db, _CHRI, event)
break
death_ref = person.get_death_ref()
if death_ref:
detail_text += format_event(db, _DIED,
db.get_event_from_handle(death_ref.ref))
else:
for event_ref in person.get_event_ref_list():
event = db.get_event_from_handle(event_ref.ref)
if event and event.get_type()[0] == RelLib.Event.BURIAL:
detail_text += format_event(db, _BURI, event)
break
if event and event.get_type()[0] == RelLib.Event.CREMATION:
detail_text += format_event(db, _CREM, event)
break
return detail_text