Added uistate to gramplet class; Finished Interactive Fan Chart: right-click gives menu options (same from PedigreeView)
svn: r11719
This commit is contained in:
parent
b2816502f4
commit
04b9ec770f
@ -219,6 +219,7 @@ class Gramplet(object):
|
|||||||
self.gui = gui # plugin gramplet has link to gui
|
self.gui = gui # plugin gramplet has link to gui
|
||||||
gui.pui = self # gui has link to plugin ui
|
gui.pui = self # gui has link to plugin ui
|
||||||
self.dbstate = gui.dbstate
|
self.dbstate = gui.dbstate
|
||||||
|
self.uistate = gui.uistate
|
||||||
self.init()
|
self.init()
|
||||||
self.on_load()
|
self.on_load()
|
||||||
self.build_options()
|
self.build_options()
|
||||||
@ -400,7 +401,7 @@ class Gramplet(object):
|
|||||||
from PluginUtils import make_gui_option
|
from PluginUtils import make_gui_option
|
||||||
#tooltips, dbstate, uistate, track
|
#tooltips, dbstate, uistate, track
|
||||||
widget, label = make_gui_option(option, None, self.dbstate,
|
widget, label = make_gui_option(option, None, self.dbstate,
|
||||||
self.gui.uistate,None)
|
self.uistate,None)
|
||||||
self.option_dict.update({option.get_label(): (widget, option)})
|
self.option_dict.update({option.get_label(): (widget, option)})
|
||||||
self.option_order.append(option.get_label())
|
self.option_order.append(option.get_label())
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
# Gramps - a GTK+/GNOME based genealogy program
|
# Gramps - a GTK+/GNOME based genealogy program
|
||||||
#
|
#
|
||||||
|
# Copyright (C) 2001-2007 Donald N. Allingham, Martin Hawlisch
|
||||||
# Copyright (C) 2009 Douglas S. Blank
|
# Copyright (C) 2009 Douglas S. Blank
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
@ -26,13 +27,6 @@
|
|||||||
## Found by redwood:
|
## Found by redwood:
|
||||||
## http://www.gramps-project.org/bugs/view.php?id=2611
|
## http://www.gramps-project.org/bugs/view.php?id=2611
|
||||||
|
|
||||||
## TODO:
|
|
||||||
## 1) add arrows to show rotation ability (click on background)
|
|
||||||
## 2) add center popup to pick center's children
|
|
||||||
## 3) perhaps right-click shows choice to edit, or make active, quick views,
|
|
||||||
## etc
|
|
||||||
## 4) add animations
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Python modules
|
# Python modules
|
||||||
@ -44,6 +38,7 @@ import pango
|
|||||||
import gtk
|
import gtk
|
||||||
import math
|
import math
|
||||||
from gtk import gdk
|
from gtk import gdk
|
||||||
|
from cgi import escape
|
||||||
try:
|
try:
|
||||||
import cairo
|
import cairo
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -60,11 +55,25 @@ if gtk.pygtk_version < (2,3,93):
|
|||||||
from BasicUtils import name_displayer
|
from BasicUtils import name_displayer
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
from DataViews import Gramplet, register
|
from DataViews import Gramplet, register
|
||||||
|
from DataViews.PedigreeView import (find_children, find_parents,
|
||||||
|
find_witnessed_people, FormattingHelper)
|
||||||
import gen.lib
|
import gen.lib
|
||||||
|
import Errors
|
||||||
|
from Editors import EditPerson, EditFamily
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Functions
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
def gender_code(is_male):
|
def gender_code(is_male):
|
||||||
if is_male: return 1
|
"""
|
||||||
return 0
|
Given boolean is_male (means position in FanChart) return code.
|
||||||
|
"""
|
||||||
|
if is_male:
|
||||||
|
return gen.lib.Person.MALE
|
||||||
|
else:
|
||||||
|
return gen.lib.Person.FEMALE
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -91,16 +100,17 @@ class FanChartWidget(gtk.Widget):
|
|||||||
NORMAL = 1
|
NORMAL = 1
|
||||||
EXPANDED = 2
|
EXPANDED = 2
|
||||||
|
|
||||||
def __init__(self, generations, right_click_callback=None):
|
def __init__(self, generations, context_popup_callback=None):
|
||||||
"""
|
"""
|
||||||
Highly experimental... documents forthcoming...
|
Fan Chart Widget. Handles visualization of data in self.data.
|
||||||
|
See main() of FanChartGramplet for example of model format.
|
||||||
"""
|
"""
|
||||||
gtk.Widget.__init__(self)
|
gtk.Widget.__init__(self)
|
||||||
self.last_x, self.last_y = None, None
|
self.last_x, self.last_y = None, None
|
||||||
self.connect("button_release_event", self.on_mouse_up)
|
self.connect("button_release_event", self.on_mouse_up)
|
||||||
self.connect("motion_notify_event", self.on_mouse_move)
|
self.connect("motion_notify_event", self.on_mouse_move)
|
||||||
self.connect("button-press-event", self.on_mouse_down)
|
self.connect("button-press-event", self.on_mouse_down)
|
||||||
self.right_click_callback = right_click_callback
|
self.context_popup_callback = context_popup_callback
|
||||||
self.add_events(gdk.BUTTON_PRESS_MASK |
|
self.add_events(gdk.BUTTON_PRESS_MASK |
|
||||||
gdk.BUTTON_RELEASE_MASK |
|
gdk.BUTTON_RELEASE_MASK |
|
||||||
gdk.POINTER_MOTION_MASK)
|
gdk.POINTER_MOTION_MASK)
|
||||||
@ -130,12 +140,13 @@ class FanChartWidget(gtk.Widget):
|
|||||||
self.angle = {}
|
self.angle = {}
|
||||||
self.data = {}
|
self.data = {}
|
||||||
for i in range(self.generations):
|
for i in range(self.generations):
|
||||||
self.data[i] = [(None, None, None) for j in range(2 ** i)]
|
# name, person, parents?, children?
|
||||||
|
self.data[i] = [(None, None, None, None) for j in range(2 ** i)]
|
||||||
self.angle[i] = []
|
self.angle[i] = []
|
||||||
angle = 0
|
angle = 0
|
||||||
slice = 360.0 / (2 ** i)
|
slice = 360.0 / (2 ** i)
|
||||||
gender = True
|
gender = True
|
||||||
for a in range(len(self.data[i])):
|
for count in range(len(self.data[i])):
|
||||||
# start, stop, male, state
|
# start, stop, male, state
|
||||||
self.angle[i].append([angle, angle + slice,gender,self.NORMAL])
|
self.angle[i].append([angle, angle + slice,gender,self.NORMAL])
|
||||||
angle += slice
|
angle += slice
|
||||||
@ -208,13 +219,13 @@ class FanChartWidget(gtk.Widget):
|
|||||||
cr.rotate(self.rotate_value * math.pi/180)
|
cr.rotate(self.rotate_value * math.pi/180)
|
||||||
for generation in range(self.generations - 1, 0, -1):
|
for generation in range(self.generations - 1, 0, -1):
|
||||||
for p in range(len(self.data[generation])):
|
for p in range(len(self.data[generation])):
|
||||||
(text, person, parents) = self.data[generation][p]
|
(text, person, parents, child) = self.data[generation][p]
|
||||||
if person:
|
if person:
|
||||||
start, stop, male, state = self.angle[generation][p]
|
start, stop, male, state = self.angle[generation][p]
|
||||||
if state in [self.NORMAL, self.EXPANDED]:
|
if state in [self.NORMAL, self.EXPANDED]:
|
||||||
self.draw_person(cr, gender_code(male),
|
self.draw_person(cr, gender_code(male),
|
||||||
text, start, stop,
|
text, start, stop,
|
||||||
generation, state, parents)
|
generation, state, parents, child)
|
||||||
cr.set_source_rgb(1, 1, 1) # white
|
cr.set_source_rgb(1, 1, 1) # white
|
||||||
cr.move_to(0,0)
|
cr.move_to(0,0)
|
||||||
cr.arc(0, 0, self.center, 0, 2 * math.pi)
|
cr.arc(0, 0, self.center, 0, 2 * math.pi)
|
||||||
@ -224,20 +235,26 @@ class FanChartWidget(gtk.Widget):
|
|||||||
cr.arc(0, 0, self.center, 0, 2 * math.pi)
|
cr.arc(0, 0, self.center, 0, 2 * math.pi)
|
||||||
cr.stroke()
|
cr.stroke()
|
||||||
# Draw center person:
|
# Draw center person:
|
||||||
(text, person, parents) = self.data[0][0]
|
(text, person, parents, child) = self.data[0][0]
|
||||||
cr.restore()
|
cr.restore()
|
||||||
if person:
|
if person:
|
||||||
cr.save()
|
cr.save()
|
||||||
name = name_displayer.display(person)
|
name = name_displayer.display(person)
|
||||||
self.draw_text(cr, name, self.center - 10, 95, 455)
|
self.draw_text(cr, name, self.center - 10, 95, 455)
|
||||||
cr.restore()
|
cr.restore()
|
||||||
|
if child: # has at least one child
|
||||||
|
cr.set_source_rgb(0, 0, 0) # black
|
||||||
|
cr.move_to(0,0)
|
||||||
|
cr.arc(0, 0, 10, 0, 2 * math.pi)
|
||||||
|
cr.move_to(0,0)
|
||||||
|
cr.fill()
|
||||||
fontw, fonth = self.layout.get_pixel_size()
|
fontw, fonth = self.layout.get_pixel_size()
|
||||||
cr.move_to((w - fontw - 4), (h - fonth ))
|
cr.move_to((w - fontw - 4), (h - fonth ))
|
||||||
cr.update_layout(self.layout)
|
cr.update_layout(self.layout)
|
||||||
cr.show_layout(self.layout)
|
cr.show_layout(self.layout)
|
||||||
|
|
||||||
def draw_person(self, cr, gender, name, start, stop, generation,
|
def draw_person(self, cr, gender, name, start, stop, generation,
|
||||||
state, parents):
|
state, parents, child):
|
||||||
"""
|
"""
|
||||||
Display the piece of pie for a given person. start and stop
|
Display the piece of pie for a given person. start and stop
|
||||||
are in degrees.
|
are in degrees.
|
||||||
@ -485,11 +502,16 @@ class FanChartWidget(gtk.Widget):
|
|||||||
selected = p
|
selected = p
|
||||||
break
|
break
|
||||||
# Handle the click:
|
# Handle the click:
|
||||||
if selected == None: # clicked in open area
|
if selected == None: # clicked in open area, or center
|
||||||
if radius < self.center:
|
if radius < self.center:
|
||||||
print "TODO: select child, spouse"
|
# right mouse
|
||||||
self.queue_draw()
|
if event.button == 3 and self.context_popup_callback:
|
||||||
return True
|
self.context_popup_callback(widget, event,
|
||||||
|
self.data[0][0][1].handle)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
# else, what to do on left click?
|
||||||
else:
|
else:
|
||||||
# save the mouse location for movements
|
# save the mouse location for movements
|
||||||
self.last_x, self.last_y = event.x, event.y
|
self.last_x, self.last_y = event.x, event.y
|
||||||
@ -498,9 +520,9 @@ class FanChartWidget(gtk.Widget):
|
|||||||
if event.button == 1: # left mouse
|
if event.button == 1: # left mouse
|
||||||
self.change_slice(generation, selected)
|
self.change_slice(generation, selected)
|
||||||
elif event.button == 3: # right mouse
|
elif event.button == 3: # right mouse
|
||||||
text, person, parents = self.data[generation][selected]
|
text, person, parents, child = self.data[generation][selected]
|
||||||
if person and self.right_click_callback:
|
if person and self.context_popup_callback:
|
||||||
self.right_click_callback(person)
|
self.context_popup_callback(widget, event, person.handle)
|
||||||
self.queue_draw()
|
self.queue_draw()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -509,10 +531,11 @@ class FanChartGramplet(Gramplet):
|
|||||||
The Gramplet code that realizes the FanChartWidget.
|
The Gramplet code that realizes the FanChartWidget.
|
||||||
"""
|
"""
|
||||||
def init(self):
|
def init(self):
|
||||||
self.set_tooltip("Click to expand/contract person\nRight-click to make person active")
|
self.set_tooltip("Click to expand/contract person\nRight-click for options\nClick and drag in open area to rotate")
|
||||||
self.generations = 6
|
self.generations = 6
|
||||||
|
self.format_helper = FormattingHelper(self.dbstate)
|
||||||
self.gui.fan = FanChartWidget(self.generations,
|
self.gui.fan = FanChartWidget(self.generations,
|
||||||
right_click_callback=self.dbstate.change_active_person)
|
context_popup_callback=self.on_popup)
|
||||||
# Replace the standard textview with the fan chart widget:
|
# Replace the standard textview with the fan chart widget:
|
||||||
self.gui.get_container_widget().remove(self.gui.textview)
|
self.gui.get_container_widget().remove(self.gui.textview)
|
||||||
self.gui.get_container_widget().add_with_viewport(self.gui.fan)
|
self.gui.get_container_widget().add_with_viewport(self.gui.fan)
|
||||||
@ -536,6 +559,17 @@ class FanChartGramplet(Gramplet):
|
|||||||
return m != None or f != None
|
return m != None or f != None
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def have_children(self, person):
|
||||||
|
"""
|
||||||
|
Returns True if a person has children.
|
||||||
|
"""
|
||||||
|
if person:
|
||||||
|
for family_handle in person.get_family_handle_list():
|
||||||
|
family = self.dbstate.db.get_family_from_handle(family_handle)
|
||||||
|
if family and len(family.get_child_ref_list()) > 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def get_parent(self, person, gender):
|
def get_parent(self, person, gender):
|
||||||
"""
|
"""
|
||||||
Get the father if gender == "male", or get mother otherwise.
|
Get the father if gender == "male", or get mother otherwise.
|
||||||
@ -566,11 +600,12 @@ class FanChartGramplet(Gramplet):
|
|||||||
else:
|
else:
|
||||||
name = name_displayer.display(person)
|
name = name_displayer.display(person)
|
||||||
parents = self.have_parents(person)
|
parents = self.have_parents(person)
|
||||||
self.gui.fan.data[0][0] = (name, person, parents)
|
child = self.have_children(person)
|
||||||
|
self.gui.fan.data[0][0] = (name, person, parents, child)
|
||||||
for current in range(1, self.generations):
|
for current in range(1, self.generations):
|
||||||
parent = 0
|
parent = 0
|
||||||
# name, person, parents
|
# name, person, parents, children
|
||||||
for (n,p,q) in self.gui.fan.data[current - 1]:
|
for (n,p,q,c) in self.gui.fan.data[current - 1]:
|
||||||
# Get father's details:
|
# Get father's details:
|
||||||
person = self.get_parent(p, "male")
|
person = self.get_parent(p, "male")
|
||||||
if person:
|
if person:
|
||||||
@ -581,7 +616,7 @@ class FanChartGramplet(Gramplet):
|
|||||||
parents = self.have_parents(person)
|
parents = self.have_parents(person)
|
||||||
else:
|
else:
|
||||||
parents = None
|
parents = None
|
||||||
self.gui.fan.data[current][parent] = (name, person, parents)
|
self.gui.fan.data[current][parent] = (name, person, parents, None)
|
||||||
if person is None:
|
if person is None:
|
||||||
# start,stop,male/right,state
|
# start,stop,male/right,state
|
||||||
self.gui.fan.angle[current][parent][3] = self.gui.fan.COLLAPSED
|
self.gui.fan.angle[current][parent][3] = self.gui.fan.COLLAPSED
|
||||||
@ -592,14 +627,263 @@ class FanChartGramplet(Gramplet):
|
|||||||
name = name_displayer.display(person)
|
name = name_displayer.display(person)
|
||||||
else:
|
else:
|
||||||
name = None
|
name = None
|
||||||
parents = self.have_parents(person)
|
if current == self.generations - 1:
|
||||||
self.gui.fan.data[current][parent] = (name, person, parents)
|
parents = self.have_parents(person)
|
||||||
|
else:
|
||||||
|
parents = None
|
||||||
|
self.gui.fan.data[current][parent] = (name, person, parents, None)
|
||||||
if person is None:
|
if person is None:
|
||||||
# start,stop,male/right,state
|
# start,stop,male/right,state
|
||||||
self.gui.fan.angle[current][parent][3] = self.gui.fan.COLLAPSED
|
self.gui.fan.angle[current][parent][3] = self.gui.fan.COLLAPSED
|
||||||
parent += 1
|
parent += 1
|
||||||
self.gui.fan.queue_draw()
|
self.gui.fan.queue_draw()
|
||||||
|
|
||||||
|
def on_childmenu_changed(self, obj,person_handle):
|
||||||
|
"""Callback for the pulldown menu selection, changing to the person
|
||||||
|
attached with menu item."""
|
||||||
|
self.dbstate.change_active_handle(person_handle)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def edit_person_cb(self, obj,person_handle):
|
||||||
|
person = self.dbstate.db.get_person_from_handle(person_handle)
|
||||||
|
if person:
|
||||||
|
try:
|
||||||
|
EditPerson(self.dbstate, self.uistate, [], person)
|
||||||
|
except Errors.WindowActiveError:
|
||||||
|
pass
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def copy_person_to_clipboard_cb(self, obj,person_handle):
|
||||||
|
"""Renders the person data into some lines of text and puts that into the clipboard"""
|
||||||
|
person = self.dbstate.db.get_person_from_handle(person_handle)
|
||||||
|
if person:
|
||||||
|
cb = gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD)
|
||||||
|
cb.set_text( self.format_helper.format_person(person,11))
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on_popup(self, obj, event, person_handle):
|
||||||
|
"""
|
||||||
|
Builds the full menu (including Siblings, Spouses, Children,
|
||||||
|
and Parents) with navigation. Copied from PedigreeView.
|
||||||
|
"""
|
||||||
|
|
||||||
|
menu = gtk.Menu()
|
||||||
|
menu.set_title(_('People Menu'))
|
||||||
|
|
||||||
|
person = self.dbstate.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(name_displayer.display(person))
|
||||||
|
go_item.set_image(go_image)
|
||||||
|
go_item.connect("activate",self.on_childmenu_changed,person_handle)
|
||||||
|
go_item.show()
|
||||||
|
menu.append(go_item)
|
||||||
|
|
||||||
|
edit_item = gtk.ImageMenuItem(gtk.STOCK_EDIT)
|
||||||
|
edit_item.connect("activate",self.edit_person_cb,person_handle)
|
||||||
|
edit_item.show()
|
||||||
|
menu.append(edit_item)
|
||||||
|
|
||||||
|
clipboard_item = gtk.ImageMenuItem(gtk.STOCK_COPY)
|
||||||
|
clipboard_item.connect("activate",self.copy_person_to_clipboard_cb,person_handle)
|
||||||
|
clipboard_item.show()
|
||||||
|
menu.append(clipboard_item)
|
||||||
|
|
||||||
|
# collect all spouses, parents and children
|
||||||
|
linked_persons = []
|
||||||
|
|
||||||
|
# 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.dbstate.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.dbstate.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(name_displayer.display(spouse))
|
||||||
|
sp_item.set_image(go_image)
|
||||||
|
linked_persons.append(sp_id)
|
||||||
|
sp_item.connect("activate",self.on_childmenu_changed,sp_id)
|
||||||
|
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 in pfam_list:
|
||||||
|
fam = self.dbstate.db.get_family_from_handle(f)
|
||||||
|
sib_list = fam.get_child_ref_list()
|
||||||
|
for sib_ref in sib_list:
|
||||||
|
sib_id = sib_ref.ref
|
||||||
|
if sib_id == person.get_handle():
|
||||||
|
continue
|
||||||
|
sib = self.dbstate.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()
|
||||||
|
|
||||||
|
if find_children(self.dbstate.db,sib):
|
||||||
|
label = gtk.Label('<b><i>%s</i></b>' % escape(name_displayer.display(sib)))
|
||||||
|
else:
|
||||||
|
label = gtk.Label(escape(name_displayer.display(sib)))
|
||||||
|
|
||||||
|
go_image = gtk.image_new_from_stock(gtk.STOCK_JUMP_TO,gtk.ICON_SIZE_MENU)
|
||||||
|
go_image.show()
|
||||||
|
sib_item = gtk.ImageMenuItem(None)
|
||||||
|
sib_item.set_image(go_image)
|
||||||
|
label.set_use_markup(True)
|
||||||
|
label.show()
|
||||||
|
label.set_alignment(0,0)
|
||||||
|
sib_item.add(label)
|
||||||
|
linked_persons.append(sib_id)
|
||||||
|
sib_item.connect("activate",self.on_childmenu_changed,sib_id)
|
||||||
|
sib_item.show()
|
||||||
|
sib_menu.append(sib_item)
|
||||||
|
|
||||||
|
if no_siblings:
|
||||||
|
item.set_sensitive(0)
|
||||||
|
item.show()
|
||||||
|
menu.append(item)
|
||||||
|
|
||||||
|
# Go over children and build their menu
|
||||||
|
item = gtk.MenuItem(_("Children"))
|
||||||
|
no_children = 1
|
||||||
|
childlist = find_children(self.dbstate.db,person)
|
||||||
|
for child_handle in childlist:
|
||||||
|
child = self.dbstate.db.get_person_from_handle(child_handle)
|
||||||
|
if not child:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if no_children:
|
||||||
|
no_children = 0
|
||||||
|
item.set_submenu(gtk.Menu())
|
||||||
|
child_menu = item.get_submenu()
|
||||||
|
|
||||||
|
if find_children(self.dbstate.db,child):
|
||||||
|
label = gtk.Label('<b><i>%s</i></b>' % escape(name_displayer.display(child)))
|
||||||
|
else:
|
||||||
|
label = gtk.Label(escape(name_displayer.display(child)))
|
||||||
|
|
||||||
|
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)
|
||||||
|
label.show()
|
||||||
|
label.set_alignment(0,0)
|
||||||
|
child_item.add(label)
|
||||||
|
linked_persons.append(child_handle)
|
||||||
|
child_item.connect("activate",self.on_childmenu_changed,child_handle)
|
||||||
|
child_item.show()
|
||||||
|
child_menu.append(child_item)
|
||||||
|
|
||||||
|
if no_children:
|
||||||
|
item.set_sensitive(0)
|
||||||
|
item.show()
|
||||||
|
menu.append(item)
|
||||||
|
|
||||||
|
# Go over parents and build their menu
|
||||||
|
item = gtk.MenuItem(_("Parents"))
|
||||||
|
no_parents = 1
|
||||||
|
par_list = find_parents(self.dbstate.db,person)
|
||||||
|
for par_id in par_list:
|
||||||
|
par = self.dbstate.db.get_person_from_handle(par_id)
|
||||||
|
if not par:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if no_parents:
|
||||||
|
no_parents = 0
|
||||||
|
item.set_submenu(gtk.Menu())
|
||||||
|
par_menu = item.get_submenu()
|
||||||
|
|
||||||
|
if find_parents(self.dbstate.db,par):
|
||||||
|
label = gtk.Label('<b><i>%s</i></b>' % escape(name_displayer.display(par)))
|
||||||
|
else:
|
||||||
|
label = gtk.Label(escape(name_displayer.display(par)))
|
||||||
|
|
||||||
|
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)
|
||||||
|
label.show()
|
||||||
|
label.set_alignment(0,0)
|
||||||
|
par_item.add(label)
|
||||||
|
linked_persons.append(par_id)
|
||||||
|
par_item.connect("activate",self.on_childmenu_changed,par_id)
|
||||||
|
par_item.show()
|
||||||
|
par_menu.append(par_item)
|
||||||
|
|
||||||
|
if no_parents:
|
||||||
|
item.set_sensitive(0)
|
||||||
|
item.show()
|
||||||
|
menu.append(item)
|
||||||
|
|
||||||
|
# Go over parents and build their menu
|
||||||
|
item = gtk.MenuItem(_("Related"))
|
||||||
|
no_related = 1
|
||||||
|
for p_id in find_witnessed_people(self.dbstate.db,person):
|
||||||
|
#if p_id in linked_persons:
|
||||||
|
# continue # skip already listed family members
|
||||||
|
|
||||||
|
per = self.dbstate.db.get_person_from_handle(p_id)
|
||||||
|
if not per:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if no_related:
|
||||||
|
no_related = 0
|
||||||
|
item.set_submenu(gtk.Menu())
|
||||||
|
per_menu = item.get_submenu()
|
||||||
|
|
||||||
|
label = gtk.Label(escape(name_displayer.display(per)))
|
||||||
|
|
||||||
|
go_image = gtk.image_new_from_stock(gtk.STOCK_JUMP_TO,gtk.ICON_SIZE_MENU)
|
||||||
|
go_image.show()
|
||||||
|
per_item = gtk.ImageMenuItem(None)
|
||||||
|
per_item.set_image(go_image)
|
||||||
|
label.set_use_markup(True)
|
||||||
|
label.show()
|
||||||
|
label.set_alignment(0,0)
|
||||||
|
per_item.add(label)
|
||||||
|
per_item.connect("activate",self.on_childmenu_changed,p_id)
|
||||||
|
per_item.show()
|
||||||
|
per_menu.append(per_item)
|
||||||
|
|
||||||
|
if no_related:
|
||||||
|
item.set_sensitive(0)
|
||||||
|
item.show()
|
||||||
|
menu.append(item)
|
||||||
|
menu.popup(None,None,None,event.button,event.time)
|
||||||
|
return 1
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
|
Loading…
x
Reference in New Issue
Block a user