Merge changes made between 2.0.3 and 2.0.5

svn: r4911
This commit is contained in:
Alex Roitman 2005-07-08 20:24:54 +00:00
parent 22ea21f744
commit 42534975c3
65 changed files with 12276 additions and 11181 deletions

View File

@ -1,3 +1,6 @@
2005-07-08 Alex Roitman <shura@gramps-project.org>
* various: merge changes made in gramps20 branch with main trunk.
2005-06-24 Martin Hawlisch <Martin.Hawlisch@gmx.de>
* src/GrampsBSDDB.py (upgrade): Disable upgrade_7 until this is
properly working to not accidently destroy a database from gramps20

View File

@ -1,3 +1,20 @@
Version 2.0.5 -- the "It's certainly uncontaminated by cheese" release
* New filters based on personal notes.
* New routine for checking and removing corrupted source references in
the Check and Repair tool.
* Bug fixes.
Version 2.0.4 -- the "That's enough music for now, lads." release
* Speedups for "select" dialogs in Family View.
* Filters are working in reports again.
* vCal and vCard plugins are back.
* Gender guessing is back for new people.
* GEDCOM export fixes.
* Other bug fixes.
Version 2.0.3 -- the "Mynd you, møøse bites Kan be pretty nasti..." release
* Fixed Date handler bug that would not allow dates to be updated.
Version 2.0.2 -- the "Little fermented curd will do the trick" release
* Updated German translation (Anton Huber).
* Usability improvements for large databases.

View File

@ -42,6 +42,7 @@ from gettext import gettext as _
#-------------------------------------------------------------------------
import gtk.glade
import gnome
import gobject
#-------------------------------------------------------------------------
#
@ -100,8 +101,6 @@ class AddSpouse:
self.renderer = gtk.CellRendererText()
self.slist = PeopleModel.PeopleModel(self.db,self.filter)
self.spouse_list.set_model(self.slist)
self.selection = self.spouse_list.get_selection()
self.selection.connect('changed',self.select_row)
self.add_columns(self.spouse_list)
@ -116,7 +115,7 @@ class AddSpouse:
Utils.set_titles(self.window,
self.glade.get_widget('title'),title,
_('Choose Spouse/Partner'))
self.glade.signal_autoconnect({
"on_select_spouse_clicked" : self.select_spouse_clicked,
"on_spouse_help_clicked" : self.on_spouse_help_clicked,
@ -130,22 +129,18 @@ class AddSpouse:
RelLib.Family.CUSTOM,RelLib.Family.MARRIED)
self.set_gender()
self.update_data()
self.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
gobject.idle_add(self.update_data)
def build_all(self):
filt = GenericFilter.GenericFilter()
filt.add_rule(GenericFilter.Everyone([]))
return filt
return None
def build_likely(self,gender):
birth_ref = self.person.get_birth_ref()
death_ref = self.person.get_death_ref()
filt = GenericFilter.GenericFilter()
if gender == RelLib.Person.MALE:
filt.add_rule(GenericFilter.IsFemale([]))
else:
filt.add_rule(GenericFilter.IsMale([]))
filt.add_rule(LikelyFilter([self.person.handle,self.person.gender]))
if birth_ref:
birth = self.db.get_event_from_handle(birth_ref.ref)
@ -162,16 +157,13 @@ class AddSpouse:
def add_columns(self,tree):
column = gtk.TreeViewColumn(_('Name'), self.renderer,text=0)
column.set_resizable(True)
#column.set_clickable(True)
column.set_min_width(225)
tree.append_column(column)
column = gtk.TreeViewColumn(_('ID'), self.renderer,text=1)
column.set_resizable(True)
#column.set_clickable(True)
column.set_min_width(75)
tree.append_column(column)
column = gtk.TreeViewColumn(_('Birth date'), self.renderer,text=3)
#column.set_resizable(True)
column.set_clickable(True)
tree.append_column(column)
@ -194,9 +186,9 @@ class AddSpouse:
"""
idlist = self.get_selected_ids()
if idlist and idlist[0]:
self.ok.set_sensitive(1)
self.ok.set_sensitive(True)
else:
self.ok.set_sensitive(0)
self.ok.set_sensitive(False)
def new_spouse_clicked(self,obj):
"""
@ -227,7 +219,7 @@ class AddSpouse:
been closed.
"""
person = epo.person
self.update_data(person.get_handle())
self.update_data()
self.slist = PeopleModel.PeopleModel(self.db,self.filter)
self.slist.rebuild_data()
@ -321,7 +313,7 @@ class AddSpouse:
m.on_add_clicked()
def relation_type_changed(self,obj):
self.update_data()
gobject.idle_add(self.update_data)
def all_filter(self, person):
return person.get_gender() != self.sgender
@ -387,18 +379,61 @@ class AddSpouse:
else:
self.sgender = RelLib.Person.FEMALE
def update_data(self,person = None):
def update_data(self):
"""
Called whenever the relationship type changes. Rebuilds the
the potential spouse list.
"""
self.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
while(gtk.events_pending()):
gtk.main_iteration()
self.slist = PeopleModel.PeopleModel(self.db,self.filter)
self.spouse_list.set_model(self.slist)
self.window.window.set_cursor(None)
def on_show_toggled(self,obj):
if self.filter == self.likely:
self.filter = self.all
else:
self.filter = self.likely
self.update_data()
gobject.idle_add(self.update_data)
#-------------------------------------------------------------------------
#
# Likely Filters
#
#-------------------------------------------------------------------------
class LikelyFilter(GenericFilter.Rule):
category = _('General filters')
def prepare(self,db):
person = db.get_person_from_handle(self.list[0])
if person.birth_handle:
birth = db.get_event_from_handle(person.birth_handle)
dateobj = Date.Date(birth.date)
year = dateobj.get_year()
dateobj.set_year(year+40)
self.lower = dateobj.sortval
dateobj.set_year(year-40)
self.upper = dateobj.sortval
else:
self.upper = None
self.lower = None
if person.gender == RelLib.Person.MALE:
self.gender = RelLib.Person.FEMALE
else:
self.gender = RelLib.Person.MALE
def apply(self,db,person):
if person.gender != self.gender:
return False
if not person.birth_handle or (self.upper == None and
self.lower == None):
return True
event = db.get_event_from_handle(person.birth_handle)
return (event.date == None or event.date.sortval == 0 or
self.lower > event.date.sortval > self.upper)

View File

@ -42,6 +42,7 @@ from gettext import gettext as _
#-------------------------------------------------------------------------
import gtk.glade
import gtk.gdk
import gobject
import gnome
#-------------------------------------------------------------------------
@ -107,19 +108,25 @@ class ChooseParents:
self.parent_selected = 0
self.renderer = gtk.CellRendererText()
db.connect('person-add', self.redraw)
db.connect('person-add', self.person_added)
db.connect('person-update', self.redraw)
db.connect('person-delete', self.redraw)
db.connect('person-rebuild', self.redraw)
db.connect('person-rebuild', self.redraw_all)
# set default filters
self.all_males_filter = GenericFilter.GenericFilter()
self.all_males_filter.add_rule(GenericFilter.IsMale([]))
self.likely_males_filter = self.build_likely(True)
self.all_females_filter = GenericFilter.GenericFilter()
self.all_females_filter.add_rule(GenericFilter.IsFemale([]))
self.likely_females_filter = self.build_likely(False)
bh = person.birth_handle
if bh and self.db.get_event_from_handle(bh).date.sortval != 0:
self.likely_females_filter = self.build_likely(False)
self.likely_males_filter = self.build_likely(True)
else:
self.likely_males_filter = self.all_males_filter
self.likely_females_filter = self.all_females_filter
self.father_filter = self.likely_males_filter
self.mother_filter = self.likely_females_filter
@ -133,6 +140,11 @@ class ChooseParents:
self.glade = gtk.glade.XML(const.gladeFile,"familyDialog","gramps")
self.window = self.glade.get_widget("familyDialog")
self.flabel = self.glade.get_widget("flabel")
self.mlabel = self.glade.get_widget("mlabel")
self.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
self.mlabel.set_label("<i>%s</i>" % _("Loading..."))
self.flabel.set_label("<i>%s</i>" % _("Loading..."))
name = NameDisplay.displayer.display(self.person)
self.title_text = _("Choose the Parents of %s") % name
@ -145,14 +157,11 @@ class ChooseParents:
self.title = self.glade.get_widget("chooseTitle")
self.father_list = self.glade.get_widget("father_list")
self.mother_list = self.glade.get_widget("mother_list")
self.flabel = self.glade.get_widget("flabel")
self.mlabel = self.glade.get_widget("mlabel")
self.showallf = self.glade.get_widget('showallf')
self.showallm = self.glade.get_widget('showallm')
self.add_itself_to_menu()
self.build_father_list()
self.build_mother_list()
gobject.idle_add(self.draw_list)
if gtk.gdk.screen_height() > 700:
self.father_list.set_size_request(-1,150)
@ -201,7 +210,20 @@ class ChooseParents:
self.window.show()
def draw_list(self):
self.build_father_list()
self.build_mother_list()
self.window.window.set_cursor(None)
def build_likely(self,is_male):
filt = GenericFilter.GenericFilter()
if is_male:
filt.add_rule(LikelyFather([self.person.handle]))
else:
filt.add_rule(LikelyMother([self.person.handle]))
return filt
def build_likely2(self,is_male):
birth_ref = self.person.get_birth_ref()
filt = GenericFilter.GenericFilter()
@ -242,21 +264,32 @@ class ChooseParents:
self.redrawm()
def add_columns(self,tree):
column = gtk.TreeViewColumn(_('Name'), self.renderer,text=0)
column.set_resizable(True)
column.set_clickable(True)
column.set_sort_column_id(0)
column.set_min_width(225)
column.set_fixed_width(255)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
tree.append_column(column)
column = gtk.TreeViewColumn(_('ID'), self.renderer,text=1)
column.set_resizable(True)
column.set_clickable(True)
column.set_sort_column_id(1)
column.set_min_width(75)
column.set_fixed_width(75)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
#column.set_min_width(75)
tree.append_column(column)
column = gtk.TreeViewColumn(_('Birth date'), self.renderer,text=3)
#column.set_resizable(True)
column.set_clickable(True)
column.set_fixed_width(150)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
tree.append_column(column)
def on_delete_event(self,obj,b):
@ -298,10 +331,48 @@ class ChooseParents:
"""Display the relevant portion of GRAMPS manual"""
gnome.help_display('gramps-manual','gramps-edit-quick')
def person_added(self,handle_list):
update_father = False
update_mother = False
for handle in handle_list:
person = self.db.get_person_from_handle(handle)
if person.get_gender() == RelLib.Person.MALE:
update_father = True
elif person.get_gender() == RelLib.Person.FEMALE:
update_mother = True
if update_father:
self.person_added_base(handle_list,self.father_model,
self.father_filter)
if update_mother:
self.person_added_base(handle_list,self.mother_model,
self.mother_filter)
def person_added_base(self,handle_list,model,data_filter):
for node in handle_list:
person = self.db.get_person_from_handle(node)
top = person.get_primary_name().get_group_name()
model.rebuild_data(data_filter)
if not model.is_visable(node):
continue
if (not model.sname_sub.has_key(top) or
len(model.sname_sub[top]) == 1):
path = model.on_get_path(top)
pnode = model.get_iter(path)
model.row_inserted(path,pnode)
path = model.on_get_path(node)
pnode = model.get_iter(path)
model.row_inserted(path,pnode)
def redraw(self,handle_list):
self.redrawf()
self.redrawm()
def redraw_all(self):
self.redrawf()
self.redrawm()
def redrawf(self):
"""Redraws the potential father list"""
self.father_model = PeopleModel.PeopleModel(self.db,self.father_filter)
@ -315,8 +386,8 @@ class ChooseParents:
def redrawm(self):
"""Redraws the potential mother list"""
self.mother_model = PeopleModel.PeopleModel(self.db,self.mother_filter)
self.mother_list.set_model(self.mother_model)
self.mother_list.set_model(self.mother_model)
if self.type[0] == RelLib.Family.CIVIL_UNION:
self.mlabel.set_label("<b>%s</b>" % _("Pa_rent"))
else:
@ -537,7 +608,7 @@ class ChooseParents:
self.father_list.scroll_to_cell(path,None,1,0.5,0)
except KeyError:
self.father_filter = self.all_males_filter
self.showallf_toggled(None)
self.redrawf()
path = self.father_model.on_get_path(handle)
top_path = self.father_model.on_get_path(name)
self.father_list.expand_row(top_path,0)
@ -552,7 +623,7 @@ class ChooseParents:
self.mother_list.scroll_to_cell(path,None,1,0.5,0)
except:
self.mother_filter = self.all_females_filter
self.showallm_toggled(None)
self.redrawm()
path = self.mother_model.on_get_path(handle)
top_path = self.mother_model.on_get_path(name)
self.mother_list.expand_row(top_path,0)
@ -743,3 +814,51 @@ class ModifyParents:
trans = self.db.transaction_begin()
self.db.commit_person(self.person,trans)
self.db.transaction_commit(trans,_("Modify Parents"))
#-------------------------------------------------------------------------
#
# Likely Filters
#
#-------------------------------------------------------------------------
class LikelyFilter(GenericFilter.Rule):
category = _('General filters')
def prepare(self,db):
person = db.get_person_from_handle(self.list[0])
birth = db.get_event_from_handle(person.birth_handle)
dateobj = Date.Date(birth.date)
year = dateobj.get_year()
dateobj.set_year(year-10)
self.lower = dateobj.sortval
dateobj.set_year(year-70)
self.upper = dateobj.sortval
def apply(self,db,person):
if person.gender != self.gender:
return False
if not person.birth_handle:
return True
event = db.get_event_from_handle(person.birth_handle)
return (event.date == None or event.date.sortval == 0 or
self.lower > event.date.sortval > self.upper)
class LikelyFather(LikelyFilter):
name = _('Likely Father')
description = _('Matches likely fathers')
def __init__(self,data_list):
GenericFilter.Rule.__init__(self,data_list)
self.gender = RelLib.Person.MALE
class LikelyMother(LikelyFilter):
name = _('Likely Mother')
description = _('Matches likely mothers')
def __init__(self,data_list):
GenericFilter.Rule.__init__(self,data_list)
self.gender = RelLib.Person.FEMALE

View File

@ -156,12 +156,12 @@ class Date:
instance IN ALL REGARDS. Needed, because the __cmp__ only looks
at the sorting value, and ignores the modifiers/comments.
"""
if self.modifier == other.modifier and self.modifier == MOD_TEXTONLY:
return self.text == other.text
return (self.calendar == other.calendar and
self.modifier == other.modifier and
self.quality == other.quality and
self.dateval == other.dateval and
self.text == other.text and
self.sortval == other.sortval)
def __str__(self):
@ -340,6 +340,7 @@ class Date:
"""
"""
self.dateval = self.dateval[0:2] + (year,) + self.dateval[3:]
self.calc_sort_value()
def get_year_valid(self):
return self._get_low_item_valid(_POS_YR)
@ -458,6 +459,12 @@ class Date:
if text:
self.text = text
def calc_sort_value(self):
year = max(self.dateval[_POS_YR],1)
month = max(self.dateval[_POS_MON],1)
day = max(self.dateval[_POS_DAY],1)
self.sortval = _calendar_convert[self.calendar](year,month,day)
def convert_calendar(self,calendar):
"""
Converts the date from the current calendar to the specified

View File

@ -95,12 +95,17 @@ class EditPerson:
self.dp = DateHandler.parser
self.dd = DateHandler.displayer
self.orig_handle = person.get_handle()
# UGLY HACK to refresh person object from handle if that exists
# done to ensure that the person object is not stale, as it could
# have been changed by something external (merge, tool, etc).
if self.orig_handle:
person = db.get_person_from_handle(self.orig_handle)
self.person = person
self.orig_surname = person.get_primary_name().get_group_name()
self.orig_surname = self.person.get_primary_name().get_group_name()
self.parent = parent
self.orig_handle = self.person.get_handle()
if self.parent.child_windows.has_key(self.orig_handle):
self.parent.child_windows[self.person.get_handle()].present(None)
self.parent.child_windows[self.orig_handle].present(None)
return
self.db = db
self.callback = callback

View File

@ -247,11 +247,25 @@ class EditPlace:
self.add_itself_to_menu()
self.top_window.get_widget('ok').set_sensitive(not self.db.readonly)
self.top.show()
self.pdmap = {}
self.build_pdmap()
if self.ref_not_loaded:
Utils.temp_label(self.refs_label,self.top)
gobject.idle_add(self.display_references)
self.ref_not_loaded = 0
def build_pdmap(self):
self.pdmap.clear()
cursor = self.db.get_place_cursor()
data = cursor.next()
while data:
if data[1][2]:
self.pdmap[data[1][2]] = data[0]
data = cursor.next()
cursor.close()
def on_delete_event(self,obj,b):
self.glry.close()
self.close_child_windows()
@ -375,6 +389,15 @@ class EditPlace:
format = self.preform.get_active()
mloc = self.place.get_main_location()
title = self.title.get_text()
if self.pdmap.has_key(title) and self.pdmap[title] != self.place.handle:
import QuestionDialog
QuestionDialog.ErrorDialog(_("Place title is already in use"),
_("Each place must have a unique title, and "
"title you have selected is already used by "
"another place"))
return
self.set(self.city,mloc.get_city,mloc.set_city)
self.set(self.parish,mloc.get_parish,mloc.set_parish)
self.set(self.state,mloc.get_state,mloc.set_state)

View File

@ -818,28 +818,45 @@ class FamilyView:
family = self.family
# determine the child
model, node = self.child_selection.get_selected()
if not node:
return
handle = self.child_model.get_value(node,_HANDLE_COL)
child = self.parent.db.get_person_from_handle(handle)
trans = self.parent.db.transaction_begin()
# remove the child from the family and the family from the child
family.remove_child_handle(child.get_handle())
child.remove_parent_family_handle(family.get_handle())
if len(family.get_child_handle_list()) == 0:
if family.get_father_handle() == None:
self.delete_family_from(family.get_mother_handle(),trans)
elif family.get_mother_handle() == None:
self.delete_family_from(family.get_father_handle(),trans)
# begin transaction
trans = self.parent.db.transaction_begin()
# if there are no children left, and the spouse is empty, delete the
# family
mother_handle = family.get_mother_handle()
father_handle = family.get_father_handle()
no_of_kids = len(family.get_child_handle_list())
self.parent.db.disable_all_signals()
if no_of_kids == 0 and (mother_handle == None or father_handle == None):
if family.get_father_handle() == None:
temp = self.parent.db.get_person_from_handle(family.get_mother_handle())
temp.get_family_handle_list().remove(family.get_handle())
elif family.get_mother_handle() == None:
temp = self.parent.db.get_person_from_handle(family.get_father_handle())
temp.get_family_handle_list().remove(family.get_handle())
self.parent.db.remove_family(family.get_handle(),trans)
else:
self.parent.db.commit_family(family,trans)
# commit the transaction
self.parent.db.commit_person(child,trans)
self.parent.db.commit_family(family,trans)
n = child.get_primary_name().get_regular_name()
self.parent.db.transaction_commit(trans,_("Remove Child (%s)") % n)
self.parent.db.enable_all_signals()
self.parent.db.emit('family-update',([family.get_handle()],))
def remove_spouse(self,obj):
if self.selected_spouse:
@ -863,32 +880,27 @@ class FamilyView:
cur_spouse = self.selected_spouse
cur_family = self.family
# Remove spouse from the family
if cur_spouse.get_handle() == cur_family.get_father_handle():
cur_family.set_father_handle(None)
else:
cur_family.set_mother_handle(None)
trans = self.parent.db.transaction_begin()
#If the spouse is defined, remove the family from the spouse
if cur_spouse:
cur_spouse.remove_family_handle(cur_family.get_handle())
self.parent.db.commit_person(cur_spouse,trans)
self.parent.db.commit_family(cur_family,trans)
# if there are no children, remove it from the current person
# and delete the family
if len(cur_family.get_child_handle_list()) == 0:
mother_id = cur_family.get_mother_handle()
father_id = cur_family.get_father_handle()
for handle in [father_id, mother_id]:
if handle:
p = self.parent.db.get_person_from_handle(handle)
p.remove_family_handle(cur_family.get_handle())
self.parent.db.commit_person(p,trans)
# if len(cur_person.get_family_handle_list()) > 0:
# handle = cur_person.get_family_handle_list()[0]
# family = self.parent.db.find_family_from_handle(handle,trans)
cur_person.remove_family_handle(cur_family.get_handle())
self.parent.db.commit_person(cur_person,trans)
self.parent.db.remove_family(cur_family.get_handle(),trans)
else:
self.parent.db.commit_family(cur_family,trans)
person_id = cur_person.get_handle()
self.person = self.parent.db.get_person_from_handle(person_id)
@ -1142,16 +1154,6 @@ class FamilyView:
else:
return _("%s: unknown") % (l)
def delete_family_from(self,person_handle,trans):
person = self.parent.db.get_person_from_handle(person_handle)
person.remove_family_handle(self.family.get_handle())
self.parent.db.remove_family(self.family.get_handle(),trans)
flist = self.person.get_family_handle_list()
if len(flist) > 0:
self.family = self.parent.db.get_family_from_handle(flist[0])
else:
self.family = None
def display_marriage(self,family):
if not family:
self.family = None
@ -1160,6 +1162,7 @@ class FamilyView:
return
hlist = family.get_child_handle_list()
self.child_model = DisplayModels.ChildModel(hlist,self.parent.db)
self.child_list.set_model(self.child_model)
self.family = self.parent.db.get_family_from_handle(family.get_handle())
@ -1572,10 +1575,10 @@ class FamilyView:
pname = self.person.get_primary_name()
return (pname.get_surname_prefix(),pname.get_surname())
elif self.family:
fid = self.family.get_father_handle()
f = self.parent.db.get_family_from_handle(fid)
if f:
pname = f.get_primary_name()
father_handle = self.family.get_father_handle()
if father_handle:
father = self.parent.db.get_person_from_handle(father_handle)
pname = father.get_primary_name()
return (pname.get_surname_prefix(),pname.get_surname())
return ("","")
@ -1584,10 +1587,12 @@ class FamilyView:
def latin_american(self,val):
if self.family:
father = self.family.get_father_handle()
mother = self.family.get_mother_handle()
if not father or not mother:
father_handle = self.family.get_father_handle()
mother_handle = self.family.get_mother_handle()
if not father_handle or not mother_handle:
return ("","")
father = self.parent.db.get_person_from_handle(father_handle)
mother = self.parent.db.get_person_from_handle(mother_handle)
fsn = father.get_primary_name().get_surname()
msn = mother.get_primary_name().get_surname()
if not father or not mother:
@ -1604,9 +1609,10 @@ class FamilyView:
if self.person.get_gender() == RelLib.Person.MALE:
fname = self.person.get_primary_name().get_first_name()
elif self.family:
f = self.family.get_father_handle()
if f:
fname = f.get_primary_name().get_first_name()
father_handle = self.family.get_father_handle()
if father_handle:
father = self.parent.db.get_person_from_handle(father_handle)
fname = father.get_primary_name().get_first_name()
if fname:
fname = fname.split()[0]
if val == 0:

View File

@ -37,6 +37,7 @@ from xml.sax import make_parser,handler,SAXParseException
#
#-------------------------------------------------------------------------
import os
import sets
from gettext import gettext as _
#-------------------------------------------------------------------------
@ -266,7 +267,7 @@ class HasIdOf(Rule):
#-------------------------------------------------------------------------
#
# HasIdOf
# IsDefaultPerson
#
#-------------------------------------------------------------------------
class IsDefaultPerson(Rule):
@ -276,11 +277,16 @@ class IsDefaultPerson(Rule):
category = _('General filters')
description = _("Matches the default person")
def apply(self,db,person):
def_person = db.get_default_person()
if def_person:
return person.handle == def_person.handle
return False
def prepare(self,db):
p = db.get_default_person()
if p:
self.def_handle = p.get_handle()
self.apply = self.apply_real
else:
self.apply = lambda db,p: False
def apply_real(self,db,person):
return person.handle == self.def_handle
#-------------------------------------------------------------------------
#
@ -294,10 +300,16 @@ class IsBookmarked(Rule):
category = _('General filters')
description = _("Matches the people on the bookmark list")
def apply(self,db,person):
if person.handle in db.get_bookmarks():
return True
return False
def prepare(self,db):
bookmarks = db.get_bookmarks()
if len(bookmarks) == 0:
self.apply = lambda db,p : False
else:
self.bookmarks = sets.Set(bookmarks)
self.apply = self.apply_real
def apply_real(self,db,person):
return person.handle in self.bookmarks
#-------------------------------------------------------------------------
#
@ -342,7 +354,7 @@ class HasUnknownGender(Rule):
description = _('Matches all people with unknown gender')
def apply(self,db,person):
return person.get_gender() == RelLib.Person.UNKNOWN
return person.gender == RelLib.Person.UNKNOWN
#-------------------------------------------------------------------------
#
@ -369,8 +381,8 @@ class IsDescendantOf(Rule):
except IndexError:
first = True
try:
root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle()
self.init_list(root_handle,first)
root_person = db.get_person_from_gramps_id(self.list[0])
self.init_list(root_person,first)
except:
pass
@ -380,18 +392,17 @@ class IsDescendantOf(Rule):
def apply(self,db,person):
return self.map.has_key(person.handle)
def init_list(self,handle,first):
if not handle:
def init_list(self,person,first):
if not person:
return
if not first:
self.map[handle] = 1
self.map[person.handle] = 1
p = self.db.get_person_from_handle(handle)
for fam_id in p.get_family_handle_list():
for fam_id in person.get_family_handle_list():
fam = self.db.get_family_from_handle(fam_id)
if fam:
for child_handle in fam.get_child_handle_list():
self.init_list(child_handle,0)
self.init_list(self.db.get_person_from_handle(child_handle),0)
#-------------------------------------------------------------------------
#
@ -408,8 +419,8 @@ class IsDescendantOfFilterMatch(IsDescendantOf):
description = _("Matches people that are descendants of anybody matched by a filter")
def __init__(self,list):
IsDescendantOf.__init__(self,list)
# def __init__(self,list):
# IsDescendantOf.__init__(self,list)
def prepare(self,db):
self.db = db
@ -425,8 +436,9 @@ class IsDescendantOfFilterMatch(IsDescendantOf):
filt = MatchesFilter(self.list)
filt.prepare(db)
for person_handle in db.get_person_handles(sort_handles=False):
if filt.apply (db, person_handle):
self.init_list (person_handle,first)
person = db.get_person_from_handle( person_handle)
if filt.apply (db, person):
self.init_list (person,first)
filt.reset()
def reset(self):
@ -454,8 +466,8 @@ class IsLessThanNthGenerationDescendantOf(Rule):
self.db = db
self.map = {}
try:
root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle()
self.init_list(root_handle,0)
root_person = db.get_person_from_gramps_id(self.list[0])
self.init_list(root_person,0)
except:
pass
@ -465,19 +477,18 @@ class IsLessThanNthGenerationDescendantOf(Rule):
def apply(self,db,person):
return self.map.has_key(person.handle)
def init_list(self,handle,gen):
if not handle:
def init_list(self,person,gen):
if not person:
return
if gen:
self.map[handle] = 1
self.map[person.handle] = 1
if gen >= int(self.list[1]):
return
p = self.db.get_person_from_handle(handle)
for fam_id in p.get_family_handle_list():
for fam_id in person.get_family_handle_list():
fam = self.db.get_family_from_handle(fam_id)
for child_handle in fam.get_child_handle_list():
self.init_list(child_handle,gen+1)
self.init_list(self.db.get_person_from_handle(child_handle),gen+1)
#-------------------------------------------------------------------------
#
@ -499,8 +510,8 @@ class IsMoreThanNthGenerationDescendantOf(Rule):
self.db = db
self.map = {}
try:
root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle()
self.init_list(root_handle,0)
root_person = db.get_person_from_gramps_id(self.list[0])
self.init_list(root_person,0)
except:
pass
@ -510,17 +521,16 @@ class IsMoreThanNthGenerationDescendantOf(Rule):
def apply(self,db,person):
return self.map.has_key(person.handle)
def init_list(self,handle,gen):
if not handle:
def init_list(self,person,gen):
if not person:
return
if gen >= int(self.list[1]):
self.map[handle] = 1
self.map[person.handle] = 1
p = self.db.get_person_from_handle(handle)
for fam_id in p.get_family_handle_list():
for fam_id in person.get_family_handle_list():
fam = self.db.get_family_from_handle(fam_id)
for child_handle in fam.get_child_handle_list():
self.init_list(child_handle,gen+1)
self.init_list(self.db.get_person_from_handle(child_handle),gen+1)
#-------------------------------------------------------------------------
#
@ -542,8 +552,9 @@ class IsChildOfFilterMatch(Rule):
filt = MatchesFilter(self.list)
filt.prepare(db)
for person_handle in db.get_person_handles(sort_handles=False):
if filt.apply (db, person_handle):
self.init_list (person_handle)
person = db.get_person_from_handle( person_handle)
if filt.apply (db, person):
self.init_list (person)
filt.reset()
def reset(self):
@ -552,11 +563,10 @@ class IsChildOfFilterMatch(Rule):
def apply(self,db,person):
return self.map.has_key(person.handle)
def init_list(self,handle):
if not handle:
def init_list(self,person):
if not person:
return
p = self.db.get_person_from_handle(handle)
for fam_id in p.get_family_handle_list():
for fam_id in person.get_family_handle_list():
fam = self.db.get_family_from_handle(fam_id)
for child_handle in fam.get_child_handle_list():
self.map[child_handle] = 1
@ -580,8 +590,9 @@ class IsSiblingOfFilterMatch(Rule):
filt = MatchesFilter(self.list)
filt.prepare(db)
for person_handle in db.get_person_handles(sort_handles=False):
if filt.apply (db, person_handle):
self.init_list (person_handle)
person = db.get_person_from_handle( person_handle)
if filt.apply (db, person):
self.init_list (person)
filt.reset()
def reset(self):
@ -590,11 +601,10 @@ class IsSiblingOfFilterMatch(Rule):
def apply(self,db,person):
return self.map.has_key(person.handle)
def init_list(self,handle):
if not handle:
def init_list(self,person):
if not person:
return
p = self.db.get_person_from_handle(handle)
fam_id = p.get_main_parents_family_handle()
fam_id = person.get_main_parents_family_handle()
fam = self.db.get_family_from_handle(fam_id)
if fam:
for child_handle in fam.get_child_handle_list():
@ -614,13 +624,13 @@ class IsDescendantFamilyOf(Rule):
name = _('Descendant family members of <person>')
category = _('Descendant filters')
description = _("Matches people that are descendants or the spouse "
"of a descendant of a specified person")
"of a descendant of a specified person")
def apply(self,db,person):
self.map = {}
self.orig_handle = person.handle
self.db = db
return self.search(handle,1)
return self.search(person.handle,1)
def search(self,handle,val):
try:
@ -674,8 +684,8 @@ class IsAncestorOf(Rule):
except IndexError:
first = 1
try:
root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle()
self.init_ancestor_list(db,root_handle,first)
root_person = db.get_person_from_gramps_id(self.list[0])
self.init_ancestor_list(db,root_person,first)
except:
pass
@ -685,23 +695,22 @@ class IsAncestorOf(Rule):
def apply(self,db,person):
return self.map.has_key(person.handle)
def init_ancestor_list(self,db,handle,first):
if not handle:
def init_ancestor_list(self,db,person,first):
if not person:
return
if not first:
self.map[handle] = 1
self.map[person.handle] = 1
p = db.get_person_from_handle(handle)
fam_id = p.get_main_parents_family_handle()
fam_id = person.get_main_parents_family_handle()
fam = db.get_family_from_handle(fam_id)
if fam:
f_id = fam.get_father_handle()
m_id = fam.get_mother_handle()
if f_id:
self.init_ancestor_list(db,f_id,0)
self.init_ancestor_list(db,db.get_person_from_handle(f_id),0)
if m_id:
self.init_ancestor_list(db,m_id,0)
self.init_ancestor_list(db,db.get_person_from_handle(m_id),0)
#-------------------------------------------------------------------------
#
@ -736,8 +745,9 @@ class IsAncestorOfFilterMatch(IsAncestorOf):
filt = MatchesFilter(self.list)
filt.prepare(db)
for person_handle in db.get_person_handles(sort_handles=False):
if filt.apply (db, person_handle):
self.init_ancestor_list (db,person_handle,first)
person = db.get_person_from_handle( person_handle)
if filt.apply (db, person):
self.init_ancestor_list (db,person,first)
filt.reset()
def reset(self):
@ -868,8 +878,9 @@ class IsParentOfFilterMatch(Rule):
filt = MatchesFilter(self.list)
filt.prepare(db)
for person_handle in db.get_person_handles(sort_handles=False):
if filt.apply (db, person_handle):
self.init_list (person_handle)
person = db.get_person_from_handle(person_handle)
if filt.apply (db, person):
self.init_list (person)
filt.reset()
def reset(self):
@ -878,9 +889,8 @@ class IsParentOfFilterMatch(Rule):
def apply(self,db,person):
return self.map.has_key(person.handle)
def init_list(self,handle):
p = self.db.get_person_from_handle(handle)
for fam_id,frel,mrel in p.get_parent_family_handle_list():
def init_list(self,person):
for fam_id,frel,mrel in person.get_parent_family_handle_list():
fam = self.db.get_family_from_handle(fam_id)
for parent_id in [fam.get_father_handle (), fam.get_mother_handle ()]:
if parent_id:
@ -946,6 +956,7 @@ class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith):
def __init__(self,list):
HasCommonAncestorWith.__init__(self,list)
self.ancestor_cache = {}
def init_ancestor_cache(self,db):
filt = MatchesFilter(self.list)
@ -953,7 +964,7 @@ class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith):
def init(self,h): self.ancestor_cache[h] = 1
for handle in db.get_person_handles(sort_handles=False):
if (not self.ancestor_cache.has_key (handle)
and filt.apply (db, handle)):
and filt.apply (db, db.get_person_from_handle(handle))):
for_each_ancestor(db,[handle],init,self)
filt.reset()
@ -1297,10 +1308,9 @@ class SearchName(Rule):
description = _("Matches people with a specified (partial) name")
category = _('General filters')
def apply(self,db,handle):
def apply(self,db,person):
self.f = self.list[0]
p = db.get_person_from_handle(handle)
n = NameDisplay.displayer.display(p)
n = NameDisplay.displayer.display(person)
return self.f and n.upper().find(self.f.upper()) != -1
#-------------------------------------------------------------------------
@ -1356,13 +1366,13 @@ class MatchesFilter(Rule):
for rule in filt.flist:
rule.reset()
def apply(self,db,handle):
def apply(self,db,person):
for filt in SystemFilters.get_filters():
if filt.get_name() == self.list[0]:
return filt.check(handle)
return filt.check(person.handle)
for filt in CustomFilters.get_filters():
if filt.get_name() == self.list[0]:
return filt.check(db,handle)
return filt.check(db,person.handle)
return False
#-------------------------------------------------------------------------
@ -1386,9 +1396,9 @@ class IsSpouseOfFilterMatch(Rule):
for spouse_id in [family.get_father_handle (), family.get_mother_handle ()]:
if not spouse_id:
continue
if spouse_id == handle:
if spouse_id == person.handle:
continue
if filt.apply (db, spouse_id):
if filt.apply (db, db.get_person_from_handle( spouse_id)):
return True
return False
@ -1404,7 +1414,8 @@ class HaveAltFamilies(Rule):
def apply(self,db,person):
for (fam,rel1,rel2) in person.get_parent_family_handle_list():
if rel1 == RelLib.Person.CHILD_ADOPTED or rel2 == RelLib.Person.CHILD_ADOPTED:
if rel1 == RelLib.Person.CHILD_ADOPTED \
or rel2 == RelLib.Person.CHILD_ADOPTED:
return True
return False
@ -1816,6 +1827,36 @@ class HasSourceOf(Rule):
return False
return person.has_source_reference( self.source_handle)
#-------------------------------------------------------------------------
# "People having notes"
#-------------------------------------------------------------------------
class HasNote(Rule):
"""People having notes"""
name = _('People having notes')
description = _("Matches people that have a note")
category = _('General filters')
def apply(self,db,person):
return bool(person.get_note())
#-------------------------------------------------------------------------
# "People having notes that contain a substring"
#-------------------------------------------------------------------------
class HasNoteMatchingSubstringOf(Rule):
"""People having notes containing <subtring>"""
labels = [ _('Substring:')]
name = _('People having notes containing <subtring>')
description = _("Matches people whose notes contain text matching a substring")
category = _('General filters')
def apply(self,db,person):
n = person.get_note()
if n:
return n.find(self.list[0]) != -1
return False
#-------------------------------------------------------------------------
#
# GenericFilter
@ -1892,6 +1933,7 @@ class GenericFilter:
person.unserialize(data[1])
if self.invert ^ task(db,person):
final_list.append(data[0])
data = cursor.next()
else:
for handle in id_list:
person = db.get_person_from_handle(handle)
@ -1903,7 +1945,33 @@ class GenericFilter:
return self.check_func(db,id_list,self.or_test)
def check_and(self,db,id_list):
return self.check_func(db,id_list,self.and_test)
final_list = []
flist = self.flist
invert = self.invert
if id_list == None:
cursor = db.get_person_cursor()
data = cursor.next()
p = RelLib.Person
while data:
person = p(data[1])
val = True
for rule in flist:
if not rule.apply(db,person):
val = False
break
if invert ^ val:
final_list.append(data[0])
data = cursor.next()
else:
for handle in id_list:
person = db.get_person_from_handle(handle)
val = True
for rule in flist:
if not rule.apply(db,person):
val = False
if invert ^ val:
final_list.append(handle)
return final_list
def check_one(self,db,id_list):
return self.check_func(db,id_list,self.one_test)
@ -1917,12 +1985,6 @@ class GenericFilter:
test = test ^ rule.apply(db,handle)
return test
def and_test(self,db,person):
for rule in self.flist:
if not rule.apply(db,person):
return False
return True
def one_test(self,db,person):
count = 0
for rule in self.flist:
@ -1932,7 +1994,7 @@ class GenericFilter:
count += 1
return count != 1
def and_or(self,db,person):
def or_test(self,db,person):
for rule in self.flist:
if rule.apply(db,person):
return True
@ -1946,7 +2008,7 @@ class GenericFilter:
return m
def check(self,db,handle):
return self.get_check_func()(db,handle)
return self.get_check_func()(db,[handle])
def apply(self,db,id_list=None):
m = self.get_check_func()
@ -1957,7 +2019,6 @@ class GenericFilter:
rule.reset()
return res
#-------------------------------------------------------------------------
#
# Name to class mappings
@ -2068,6 +2129,8 @@ editor_rule_list = [
IsSiblingOfFilterMatch,
RelationshipPathBetween,
HasTextMatchingSubstringOf,
HasNote,
HasNoteMatchingSubstringOf
]
#-------------------------------------------------------------------------
@ -2222,7 +2285,7 @@ class ParamFilter(GenericFilter):
def set_parameter(self,param):
self.param_list = [param]
def apply(self,db,id_list):
def apply(self,db,id_list=None):
for rule in self.flist:
rule.set_list(self.param_list)
for rule in self.flist:
@ -2278,14 +2341,14 @@ class GrampsFilterComboBox(gtk.ComboBox):
cnt += 1
for filt in SystemFilters.get_filters():
self.store.append(row=[_(filt.get_name())])
self.store.append(row=[filt.get_name()])
self.map[filt.get_name()] = filt
if default != "" and default == filt.get_name():
active = cnt
cnt += 1
for filt in CustomFilters.get_filters():
self.store.append(row=[_(filt.get_name())])
self.store.append(row=[filt.get_name()])
self.map[filt.get_name()] = filt
if default != "" and default == filt.get_name():
active = cnt
@ -2306,7 +2369,7 @@ class GrampsFilterComboBox(gtk.ComboBox):
active = self.get_active()
if active < 0:
return None
key = self.store[active][0]
key = unicode(self.store[active][0])
return self.map[key]

View File

@ -43,7 +43,7 @@ from bsddb import dbshelve, db
from RelLib import *
from GrampsDbBase import *
_DBVERSION = 7
_DBVERSION = 8
def find_surname(key,data):
return str(data[3].get_surname())
@ -516,12 +516,14 @@ class GrampsBSDDB(GrampsDbBase):
self.upgrade_5()
if version < 6:
self.upgrade_6()
self.metadata['version'] = _DBVERSION
if version < 7:
self.upgrade_7()
if version < 8:
#self.upgrade_7()
raise Exception("Currently there is no database upgrade available")
else:
print 'Successfully finished all upgrades'
self.metadata['version'] = _DBVERSION
def upgrade_2(self,child_rel_notrans):
print "Upgrading to DB version 2"
@ -851,6 +853,19 @@ class GrampsBSDDB(GrampsDbBase):
def upgrade_7(self):
print "Upgrading to DB version 7"
self.genderStats = GenderStats()
cursor = self.get_person_cursor()
data = cursor.first()
while data:
handle,val = data
p = Person(val)
self.genderStats.count_person(p,self)
data = cursor.next()
cursor.close()
def upgrade_8(self):
print "Upgrading to DB version 8"
# First, make sure the stored default person handle is str, not unicode
try:
handle = self.metadata['default']

View File

@ -311,7 +311,17 @@ class GrampsDbBase(GrampsDBCallback.GrampsDBCallback):
update_list.append((handle,obj.serialize()))
else:
add_list.append((handle,obj.serialize()))
# committing person, do gender stats here
if old_data and key == PERSON_KEY:
old_person = Person(old_data)
if (old_data[2] != person.gender or
old_data[3].first_name != obj.primary_name.first_name):
self.genderStats.uncount_person(old_person)
self.genderStats.count_person(obj,self)
else:
self.genderStats.count_person(obj,self)
def commit_person(self,person,transaction,change_time=None):
"""
Commits the specified Person to the database, storing the changes
@ -632,27 +642,25 @@ class GrampsDbBase(GrampsDBCallback.GrampsDBCallback):
"""
assert False, "Needs to be overridden in the derived class"
def add_person(self,person,transaction):
"""
Adds a Person to the database, assigning internal IDs if they have
not already been defined.
"""
if not person.gramps_id:
person.gramps_id = self.find_next_person_gramps_id()
if not person.handle:
person.handle = self.create_id()
self.commit_person(person,transaction)
self.genderStats.count_person (person, self)
return person.handle
def _add_object(self,obj,transaction,find_next_func,commit_func):
if not obj.gramps_id:
obj.gramps_id = find_next_func()
if not obj.handle:
obj.handle = self.create_id()
commit_func(obj,transaction)
if obj.__class__.__name__ == 'Person':
self.genderStats.count_person (person, self)
return obj.handle
def add_person(self,person,transaction):
"""
Adds a Person to the database, assigning internal IDs if they have
not already been defined.
"""
return self._add_object(person,transaction,
self.find_next_person_gramps_id,
self.commit_person)
def add_family(self,family,transaction):
"""
Adds a Family to the database, assigning internal IDs if they have

View File

@ -1170,6 +1170,8 @@ class GlobalMediaProperties:
text = unicode(t.get_text(t.get_start_iter(),t.get_end_iter(),False))
desc = unicode(self.descr_window.get_text())
note = self.obj.get_note()
path = self.change_dialog.get_widget('path').get_text()
self.obj.set_path(path)
if not self.date_object.is_equal(self.obj.get_date_object()):
self.obj.set_date_object(self.date_object)

View File

@ -80,10 +80,16 @@ class Marriage:
def __init__(self,parent,family,db):
"""Initializes the Marriage class, and displays the window"""
family_handle = family.get_handle()
# UGLY HACK to refresh faimly object from handle if that exists
# done to ensure that the family object is not stale, as it could
# have been changed by something external (merge, tool, etc).
if family_handle:
family = db.get_family_from_handle(family_handle)
self.family = family
self.parent = parent
if self.parent.child_windows.has_key(family.get_handle()):
self.parent.child_windows[family.get_handle()].present(None)
if self.parent.child_windows.has_key(family_handle):
self.parent.child_windows[family_handle].present(None)
return
self.child_windows = {}
self.db = db

View File

@ -361,7 +361,6 @@ class PedigreeView:
return True
return 0
def on_show_child_menu(self,obj):
"""User clicked button to move to child of active person"""

View File

@ -105,11 +105,12 @@ class PeopleModel(gtk.GenericTreeModel):
return
if data_filter:
handle_list = self.db.get_person_handles(sort_handles=False)
keys = data_filter.apply(self.db,handle_list)
keys = data_filter.apply(self.db)
if self.invert_result:
handle_list = self.db.get_person_handles(sort_handles=False)
#TODO: Could be optimized by using a cursor
keys = [k for k in handle_list if k not in keys]
del handle_list
del handle_list
else:
keys = self.db.get_person_handles(sort_handles=False)

View File

@ -211,7 +211,12 @@ class PeopleView:
"""Remove the selected person from the list. A person object is
expected, not an ID"""
path = self.person_model.on_get_path(person.get_handle())
self.person_model.row_deleted(path)
#self.person_model.row_deleted(path)
(col,row) = path
if row > 0:
self.person_selection.select_path((col,row-1))
elif row == 0 and self.person_model.on_get_iter(path):
self.person_selection.select_path(path)
def remove_from_history(self,person_handle,old_id=None):
"""Removes a person from the history list"""
@ -289,7 +294,7 @@ class PeopleView:
entries = [
(gtk.STOCK_GO_BACK,self.parent.back_clicked,back_sensitivity),
(gtk.STOCK_GO_FORWARD,self.parent.fwd_clicked,fwd_sensitivity),
(gtk.STOCK_HOME,self.parent.on_home_clicked,1),
(_("Home"),self.parent.on_home_clicked,1),
(_("Add Bookmark"),self.parent.on_add_bookmark_activate,sel_sensitivity),
(None,None,0),
(gtk.STOCK_ADD, self.parent.add_button_clicked,1),

View File

@ -98,18 +98,19 @@ class PlaceView:
order = gtk.SORT_DESCENDING
self.sort_col = data
handle = self.first_selected()
colmap = self.parent.db.get_place_column_order()
self.model = DisplayModels.PlaceModel(self.parent.db,
self.sort_col,order)
self.scol_map[self.sort_col],order)
self.list.set_model(self.model)
colmap = self.parent.db.get_place_column_order()
if handle:
path = self.model.on_get_path(handle)
self.selection.select_path(path)
self.list.scroll_to_cell(path,None,1,0.5,0)
for i in range(0,len(self.columns)):
self.columns[i].set_sort_indicator(i==colmap[data][1]-1)
self.columns[i].set_sort_indicator(i==self.sort_col)
self.columns[self.sort_col].set_sort_order(order)
def build_columns(self):
@ -122,12 +123,14 @@ class PlaceView:
column.connect('clicked',self.column_clicked,0)
column.set_clickable(True)
self.list.append_column(column)
self.scol_map = [0]
self.columns = [column]
index = 1
for pair in self.parent.db.get_place_column_order():
if not pair[0]:
continue
self.scol_map.append(pair[1])
name = column_names[pair[1]]
column = gtk.TreeViewColumn(name, self.renderer, text=pair[1])
column.set_resizable(True)

View File

@ -32,6 +32,7 @@ import re
import string
import const
import time
import sets
from gettext import gettext as _
#-------------------------------------------------------------------------
@ -279,6 +280,15 @@ class GedcomParser:
self.lid2id = {}
self.fid2id = {}
self.place_names = sets.Set()
cursor = dbase.get_place_cursor()
data = cursor.next()
while data:
(handle,val) = data
self.place_names.add(val[2])
data = cursor.next()
cursor.close()
self.f = open(filename,"rU")
self.filename = filename
self.index = 0
@ -742,18 +752,37 @@ class GedcomParser:
self.sid2id[gramps_id] = intid
return source
def find_or_create_place(self,gramps_id):
def find_or_create_place(self,title):
place = RelLib.Place()
intid = self.lid2id.get(gramps_id)
# check to see if we've encountered this name before
# if we haven't we need to get a new GRAMPS ID
intid = self.lid2id.get(title)
if intid == None:
new_id = self.db.find_next_place_gramps_id()
else:
new_id = None
# check to see if the name already existed in the database
# if it does, create a new name by appending the GRAMPS ID.
# generate a GRAMPS ID if needed
if title in self.place_names:
if not new_id:
new_id = self.db.find_next_place_gramps_id()
pname = "%s [%s]" % (title,new_id)
else:
pname = title
if self.db.place_map.has_key(intid):
place.unserialize(self.db.place_map.get(intid))
else:
intid = create_id()
place.set_handle(intid)
place.set_title(gramps_id)
place.set_gramps_id(self.db.find_next_place_gramps_id())
place.set_title(pname)
place.set_gramps_id(new_id)
self.db.add_place(place,self.trans)
self.lid2id[gramps_id] = intid
self.lid2id[title] = intid
return place
def parse_cause(self,event,level):

View File

@ -26,6 +26,7 @@
#
#-------------------------------------------------------------------------
import os
import sets
import gtk
import shutil
from xml.parsers.expat import ExpatError, ParserCreate
@ -184,87 +185,6 @@ def importData(database, filename, callback=None,cl=0,use_trans=True):
database.commit_media_object(mobject,None,change)
except (IOError,OSError),msg:
ErrorDialog(_('Could not copy file'),str(msg))
#-------------------------------------------------------------------------
# def remove_clicked():
# # File is lost => remove all references and the object itself
# mobj = database.find_object_from_handle(NewMediaID)
# for fid in database.get_family_handles():
# p = database.get_family_from_handle(fid)
# nl = p.get_media_list()
# for o in nl:
# if o.get_reference() == mobj:
# nl.remove(o)
# p.set_media_list(nl)
# for key in database.get_person_handles(sort_handles=False):
# p = database.find_person_from_handle(key)
# nl = p.get_media_list()
# for o in nl:
# if o.get_reference_handle() == mobj.get_handle():
# nl.remove(o)
# p.set_media_list(nl)
# for key in database.get_source_handles():
# p = database.find_source_from_handle(key)
# nl = p.get_media_list()
# for o in nl:
# if o.get_reference_handle() == mobj.get_handle():
# nl.remove(o)
# p.set_media_list(nl)
# for key in database.get_place_handles():
# p = database.find_place_from_handle(key)
# nl = p.get_media_list()
# for o in nl:
# if o.get_reference() == mobj:
# nl.remove(o)
# p.set_media_list(nl)
# database.remove_object(NewMediaID)
# def leave_clicked():
# # File is lost => do nothing, leave as is
# pass
# def select_clicked():
# # File is lost => select a file to replace the lost one
# def fs_close_window(obj):
# pass
# def fs_ok_clicked(obj):
# name = fs_top.get_filename()
# if os.path.isfile(name):
# shutil.copyfile(name,newfile)
# try:
# shutil.copystat(name,newfile)
# except:
# pass
# choose = gtk.FileChooserDialog('Select file',
# None,
# gtk.FILE_CHOOSER_ACTION_OPEN,
# (gtk.STOCK_CANCEL,
# gtk.RESPONSE_CANCEL,
# gtk.STOCK_OPEN,
# gtk.RESPONSE_OK))
# filter = gtk.FileFilter()
# filter.set_name(_('All files'))
# filter.add_pattern('*')
# choose.add_filter(filter)
# response = choose.run()
# if response == gtk.RESPONSE_OK:
# name = fs_top.get_filename()
# if os.path.isfile(name):
# shutil.copyfile(name,newfile)
# try:
# shutil.copystat(name,newfile)
# except:
# pass
# choose.destroy()
# del parser
# return 1
#-------------------------------------------------------------------------
#
@ -299,7 +219,6 @@ class GrampsParser:
self.gid2sid = {}
self.change = change
self.dp = DateHandler.parser
self.child_relmap = {
"None" : RelLib.Person.CHILD_NONE,
"Birth" : RelLib.Person.CHILD_BIRTH,
@ -309,6 +228,14 @@ class GrampsParser:
"Foster" : RelLib.Person.CHILD_FOSTER,
"Unknown" : RelLib.Person.CHILD_UNKNOWN,
}
self.place_names = sets.Set()
cursor = database.get_place_cursor()
data = cursor.next()
while data:
(handle,val) = data
self.place_names.add(val[2])
data = cursor.next()
cursor.close()
self.ord = None
self.objref = None
@ -686,6 +613,7 @@ class GrampsParser:
title = attrs['title']
if title == "":
title = attrs['id']
self.placeobj.set_title(title)
self.locations = 0
if self.callback != None and self.count % self.increment == 0:
@ -1242,6 +1170,11 @@ class GrampsParser:
if self.placeobj.get_title() == "":
loc = self.placeobj.get_main_location()
self.placeobj.set_title(build_place_title(loc))
title = self.placeobj.get_title()
if title in self.place_names:
self.placeobj.set_title(title + " [%s]" % self.placeobj.get_gramps_id())
self.db.commit_place(self.placeobj,self.trans,self.change)
self.placeobj = None

View File

@ -524,7 +524,7 @@ class SourceNote(BaseObject,NoteBase):
for ix_replace in xrange(n_replace):
ix = refs_list.index(old_handle)
self.source_list[ix].ref = new_handle
refs_list.pop(ix)
refs_list[ix] = new_handle
for item in self.get_sourcref_child_list():
item.replace_source_references(old_handle,new_handle)
@ -624,7 +624,7 @@ class MediaBase:
for ix_replace in xrange(n_replace):
ix = refs_list.index(old_handle)
self.media_list[ix].ref = new_handle
refs_list.pop(ix)
refs_list[ix] = new_handle
class DateBase:
"""
@ -903,36 +903,38 @@ class Person(PrimaryObject,PrivateSourceNote,MediaBase,AttributeBase):
CHILD_UNKNOWN = 6
CHILD_CUSTOM = 7
def __init__(self):
def __init__(self,data=None):
"""
Creates a new Person instance. After initialization, most
data items have empty or null values, including the database
handle.
"""
PrimaryObject.__init__(self)
PrivateSourceNote.__init__(self)
MediaBase.__init__(self)
AttributeBase.__init__(self)
self.primary_name = Name()
self.event_ref_list = []
self.family_list = []
self.parent_family_list = []
self.nickname = ""
self.alternate_names = []
self.gender = Person.UNKNOWN
self.death_ref = None
self.birth_ref = None
self.address_list = []
self.urls = []
self.lds_bapt = None
self.lds_endow = None
self.lds_seal = None
self.complete = False
if data:
self.unserialize(data)
else:
PrimaryObject.__init__(self)
PrivateSourceNote.__init__(self)
MediaBase.__init__(self)
AttributeBase.__init__(self)
self.primary_name = Name()
self.event_ref_list = []
self.family_list = []
self.parent_family_list = []
self.nickname = ""
self.alternate_names = []
self.gender = Person.UNKNOWN
self.death_ref = None
self.birth_ref = None
self.address_list = []
self.urls = []
self.lds_bapt = None
self.lds_endow = None
self.lds_seal = None
self.complete = False
# We hold a reference to the GrampsDB so that we can maintain
# its genderStats. It doesn't get set here, but from
# GenderStats.count_person.
self.db = None
def serialize(self):
"""
@ -1128,12 +1130,7 @@ class Person(PrimaryObject,PrivateSourceNote,MediaBase,AttributeBase):
@param name: L{Name} to be assigned to the person
@type name: L{Name}
"""
db = self.db
if db:
db.genderStats.uncount_person (self)
self.primary_name = name
if db:
db.genderStats.count_person (self, db)
def get_primary_name(self):
"""
@ -1227,13 +1224,7 @@ class Person(PrimaryObject,PrivateSourceNote,MediaBase,AttributeBase):
Person.UNKNOWN
@type gender: int
"""
# if the db object has been assigned, update the
# genderStats of the database
if self.db:
self.db.genderStats.uncount_person (self)
self.gender = gender
if self.db:
self.db.genderStats.count_person (self, self.db)
def get_gender(self) :
"""
@ -1922,7 +1913,7 @@ class Family(PrimaryObject,SourceNote,MediaBase,AttributeBase):
@return: Returns the list of objects refereincing primary objects.
@rtype: list
"""
return get_sourcref_child_list() + self.source_list
return self.get_sourcref_child_list() + self.source_list
def set_complete_flag(self,val):
"""
@ -4352,7 +4343,6 @@ class GenderStats:
if not person:
return
# Let the Person do their own counting later
person.db = db
name = self._get_key (person)
if not name:

View File

@ -1,7 +1,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -29,6 +29,7 @@
import RelLib
import types
from gettext import gettext as _
from Utils import strip_context as __
#-------------------------------------------------------------------------
#
@ -43,7 +44,7 @@ _level_name = [ "", "first", "second", "third", "fourth", "fifth", "sixth",
_removed_level = [ "", " once removed", " twice removed", " three times removed",
" four times removed", " five times removed", " six times removed",
" sevent times removed", " eight times removed", " nine times removed",
" sevent times removed", " eight times removed", " nine times removed",
" ten times removed", " eleven times removed", " twelve times removed",
" thirteen times removed", " fourteen times removed", " fifteen times removed",
" sixteen times removed", " seventeen times removed", " eighteen times removed",
@ -240,12 +241,59 @@ class RelationshipCalculator:
def is_spouse(self,orig,other):
for f in orig.get_family_handle_list():
family = self.db.get_family_from_handle(f)
if family:
if other.get_handle() == family.get_father_handle() or other.get_handle() == family.get_mother_handle():
return 1
if family and other.get_handle() in [family.get_father_handle(),
family.get_mother_handle()]:
family_rel = family.get_relationship()
# Determine person's gender
if other.get_gender() == RelLib.Person.MALE:
gender = RelLib.Person.MALE
elif other.get_gender() == RelLib.Person.FEMALE:
gender = RelLib.Person.FEMALE
# Person's gender is unknown, try guessing from spouse's
elif orig.get_gender() == RelLib.Person.MALE:
if family_rel == RelLib.Family.CIVIL_UNION:
gender = RelLib.Person.MALE
else:
gender = RelLib.Person.FEMALE
elif orig.get_gender() == RelLib.Person.FEMALE:
if family_rel == RelLib.Family.CIVIL_UNION:
gender = RelLib.Person.FEMALE
else:
gender = RelLib.Person.MALE
else:
gender = RelLib.Person.UNKNOWN
if family_rel == RelLib.Family.MARRIED:
if gender == RelLib.Person.MALE:
return _("husband")
elif gender == RelLib.Person.FEMALE:
return _("wife")
else:
return __("gender unknown|spouse")
elif family_rel == RelLib.Family.UNMARRIED:
if gender == RelLib.Person.MALE:
return __("unmarried|husband")
elif gender == RelLib.Person.FEMALE:
return __("unmarried|wife")
else:
return __("gender unknown,unmarried|spouse")
elif family_rel == RelLib.Family.CIVIL_UNION:
if gender == RelLib.Person.MALE:
return __("male,civil union|partner")
elif gender == RelLib.Person.FEMALE:
return __("female,civil union|partner")
else:
return __("gender unknown,civil union|partner")
else:
if gender == RelLib.Person.MALE:
return __("male,unknown relation|partner")
elif gender == RelLib.Person.FEMALE:
return __("female,unknown relation|partner")
else:
return __("gender unknown,unknown relation|partner")
else:
return 0
return 0
return None
return None
def get_relationship_distance(self,orig_person,other_person):
"""
@ -304,8 +352,9 @@ class RelationshipCalculator:
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
return ("spouse",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

View File

@ -1677,7 +1677,7 @@ class CommandLineReport:
for paper in PaperMenu.paper_sizes:
if paper.get_name() == self.options_dict['papers']:
self.paper = paper
self.option_class.handler.set_paper(self.paper)
self.option_class.handler.set_paper(self.paper)
self.options_help['papers'].append(
[ paper.get_name() for paper in PaperMenu.paper_sizes
if paper.get_name() != 'Custom Size' ] )

View File

@ -401,6 +401,7 @@ def place_name(db,place_handle):
place = db.get_place_from_handle(place_handle).get_title()
else:
place = ""
return place
#-------------------------------------------------------------------------
#

View File

@ -35,6 +35,7 @@ from gettext import gettext as _
#-------------------------------------------------------------------------
import gtk.glade
import gnome
import gobject
#-------------------------------------------------------------------------
#
@ -48,6 +49,8 @@ import PeopleModel
import NameDisplay
import AutoComp
from QuestionDialog import ErrorDialog
import GenericFilter
import Date
#-------------------------------------------------------------------------
#
@ -116,10 +119,12 @@ class SelectChild:
else:
self.frel.set_sensitive(False)
self.refmodel = PeopleModel.PeopleModel(self.db)
self.likely_filter = GenericFilter.GenericFilter()
self.likely_filter.add_rule(LikelyFilter([self.person.handle]))
self.active_filter = self.likely_filter
self.add_child.set_model(self.refmodel)
self.redraw_child_list(2)
self.top.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
gobject.idle_add(self.redraw_child_list)
self.add_itself_to_menu()
self.add_columns(self.add_child)
self.top.show()
@ -176,110 +181,10 @@ class SelectChild:
"""Display the relevant portion of GRAMPS manual"""
gnome.help_display('gramps-manual','gramps-edit-quick')
def redraw_child_list(self,filter):
return
birth = self.db.get_event_from_handle(self.person.get_birth_handle())
death = self.db.get_event_from_handle(self.person.get_death_handle())
if birth:
bday = birth.get_date_object()
else:
bday = None
if death:
dday = death.get_date_object()
else:
dday = None
slist = {}
for f in self.person.get_parent_family_handle_list():
if f:
family = self.db.get_family_from_handle(f[0])
if family.get_father_handle():
slist[family.get_father_handle()] = 1
elif family.get_mother_handle():
slist[family.get_mother_handle()] = 1
for c in family.get_child_handle_list():
slist[c] = 1
person_list = []
for key in self.db.get_person_handles(sort_handles=True):
person = self.db.get_person_from_handle(key)
if filter:
if slist.has_key(key) or person.get_main_parents_family_handle():
continue
birth_event = self.db.get_event_from_handle(person.get_birth_handle())
if birth_event:
pbday = birth_event.get_date_object()
else:
pbday = None
death_event = self.db.get_event_from_handle(person.get_death_handle())
if death_event:
pdday = death_event.get_date_object()
else:
pdday = None
if bday and bday.getYearValid():
if pbday and pbday.getYearValid():
# reject if child birthdate < parents birthdate + 10
if pbday.getLowYear() < bday.getHighYear()+10:
continue
# reject if child birthdate > parents birthdate + 90
if pbday.getLowYear() > bday.getHighYear()+90:
continue
if pdday and pdday.getYearValid():
# reject if child deathdate < parents birthdate+ 10
if pdday.getLowYear() < bday.getHighYear()+10:
continue
if dday and dday.getYearValid():
if pbday and pbday.getYearValid():
# reject if childs birth date > parents deathday + 3
if pbday.getLowYear() > dday.getHighYear()+3:
continue
if pdday and pdday.getYearValid():
# reject if childs death date > parents deathday + 150
if pdday.getLowYear() > dday.getHighYear() + 150:
continue
person_list.append(person.get_handle())
node = None
for idval in person_list:
person = self.db.get_person_from_handle(idval)
name = NameDisplay.displayer.display(person)
if person.gender == RelLib.Person.MALE:
gender = _("male")
elif person.gender == RelLib.Person.FEMALE:
gender = _("female")
else:
gender = _("unknown")
bh = person.get_birth_handle()
dh = person.get_death_handle()
if bh:
bdate = self.db.get_event_from_handle(bh).get_date()
else:
bdate = ""
if dh:
ddate = self.db.get_event_from_handle(bh).get_date()
else:
ddate = ""
rdata = [name,person.get_gramps_id(),gender,bdate,ddate]
node = self.refmodel.add(rdata)
self.refmodel.connect_model()
if node:
self.refmodel.selection.select_iter(node)
path = self.refmodel.model.get_path(node)
col = self.add_child.get_column(0)
self.add_child.scroll_to_cell(path,col,1,0.5,0.0)
def redraw_child_list(self):
self.refmodel = PeopleModel.PeopleModel(self.db,self.active_filter)
self.add_child.set_model(self.refmodel)
self.top.window.set_cursor(None)
def select_function(self,store,path,node,id_list):
id_list.append(self.refmodel.get_value(node,PeopleModel.COLUMN_INT_ID))
@ -349,7 +254,14 @@ class SelectChild:
self.callback()
def on_show_toggled(self,obj):
self.redraw_child_list(not obj.get_active())
if obj.get_active():
self.active_filter = None
else:
self.active_filter = self.likely_filter
self.top.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
while(gtk.events_pending()):
gtk.main_iteration()
self.redraw_child_list()
def north_american(self,val):
if self.person.get_gender() == RelLib.Person.MALE:
@ -397,3 +309,35 @@ class SelectChild:
return ("","%sdóttir" % fname)
else:
return ("","")
#-------------------------------------------------------------------------
#
# Likely Filters
#
#-------------------------------------------------------------------------
class LikelyFilter(GenericFilter.Rule):
category = _('General filters')
def prepare(self,db):
person = db.get_person_from_handle(self.list[0])
if person.birth_handle:
birth = db.get_event_from_handle(person.birth_handle)
dateobj = Date.Date(birth.date)
year = dateobj.get_year()
dateobj.set_year(year+10)
self.lower = dateobj.sortval
dateobj.set_year(year+70)
self.upper = dateobj.sortval
else:
self.lower = None
self.upper = None
def apply(self,db,person):
if not person.birth_handle or (self.upper == None and
self.lower == None):
return True
event = db.get_event_from_handle(person.birth_handle)
return (event.date == None or event.date.sortval == 0 or
self.lower < event.date.sortval < self.upper)

View File

@ -59,7 +59,7 @@ column_names = [
_HANDLE_COL = len(column_names)
#-------------------------------------------------------------------------
#
#
# SouceView
#
#-------------------------------------------------------------------------
@ -97,7 +97,7 @@ class SourceView:
self.sort_col = data
handle = self.first_selected()
self.model = DisplayModels.SourceModel(self.parent.db,
self.sort_col,order)
self.scol_map[self.sort_col],order)
self.list.set_model(self.model)
colmap = self.parent.db.get_place_column_order()
@ -106,7 +106,7 @@ class SourceView:
self.selection.select_path(path)
self.list.scroll_to_cell(path,None,1,0.5,0)
for i in range(0,len(self.columns)):
self.columns[i].set_sort_indicator(i==colmap[data][1]-1)
self.columns[i].set_sort_indicator(i==self.sort_col)
self.columns[self.sort_col].set_sort_order(order)
def build_columns(self):
@ -119,12 +119,14 @@ class SourceView:
column.set_clickable(True)
column.connect('clicked',self.column_clicked,0)
self.list.append_column(column)
self.scol_map = [0]
self.columns = [column]
index = 1
for pair in self.parent.db.get_source_column_order():
if not pair[0]:
continue
self.scol_map.append(pair[1])
name = column_names[pair[1]]
column = gtk.TreeViewColumn(name, self.renderer, text=pair[1])
column.connect('clicked',self.column_clicked,index)

View File

@ -111,7 +111,7 @@ class ReadTarFile:
if filename == None:
return data
self.f.read(24) # modes
l = self.f.read(12)(chr(0),' ')
l = self.f.read(12).replace(chr(0),' ')
length = int(l,8)
self.f.read(12)
self.f.read(6)

View File

@ -643,7 +643,7 @@ def search_for(name):
#-------------------------------------------------------------------------
#
# Change label apperance
# Change label appearance
#
#-------------------------------------------------------------------------
def bold_label(label,widget=None):
@ -1028,3 +1028,26 @@ def get_type_converter_by_name(val_str):
elif val_str in ('str','unicode'):
return unicode
return unicode
def strip_context(msgid,sep='|'):
"""
Strip the context used for resolving translation ambiguities.
The translation of msgid is returned unless the translation is
not available and the msgid contains the separator. In that case,
the returned value is the portion of msgid following the last
separator. Default separator is '|'.
@param msgid: The string to translated.
@type msgid: unicode
@param sep: The separator marking the context.
@type sep: unicode
@return: Translation or the original with context stripped.
@rtype: unicode
"""
msgval = _(msgid)
sep_idx = msgid.rfind(sep)
if msgval == msgid and sep_idx != -1:
msgval = msgid[sep_idx+1:]
return msgval

View File

@ -120,8 +120,8 @@ def add_familys_sources(db,family_handle,slist,private):
continue
for source_ref in attr.get_source_references():
sbase = source_ref.get_base_handle()
if sbase != None and not slist.has_key(sbase.get_handle()):
slist[sbase.get_handle()] = 1
if sbase != None and not slist.has_key(sbase):
slist[sbase] = 1
#-------------------------------------------------------------------------
#
@ -329,20 +329,28 @@ class GedcomWriterOptionBox:
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % NameDisplay.displayer.display(self.person))
des.add_rule(GenericFilter.IsDescendantOf([self.person.get_handle(),1]))
if self.person:
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") %
NameDisplay.displayer.display(self.person))
des.add_rule(GenericFilter.IsDescendantOf(
[self.person.get_gramps_id(),1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % NameDisplay.displayer.display(self.person))
ans.add_rule(GenericFilter.IsAncestorOf([self.person.get_handle(),1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s")
% NameDisplay.displayer.display(self.person))
ans.add_rule(GenericFilter.IsAncestorOf(
[self.person.get_gramps_id(),1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
NameDisplay.displayer.display(self.person))
com.add_rule(GenericFilter.HasCommonAncestorWith([self.person.get_handle()]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
NameDisplay.displayer.display(self.person))
com.add_rule(GenericFilter.HasCommonAncestorWith(
[self.person.get_gramps_id()]))
self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com])
self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com])
else:
self.filter_menu = GenericFilter.build_filter_menu([all])
filter_obj.set_menu(self.filter_menu)
gedmap = GedcomInfo.GedcomInfoDB()
@ -734,16 +742,19 @@ class GedcomWriter:
self.writeln('2 _STAT %s' % f[2])
break
for srcref in family.get_source_references():
self.write_source_ref(1,srcref)
self.write_change(1,family.get_change_time())
def write_sources(self):
index = 0.0
sorted = []
for key in self.slist.keys():
source = self.db.get_source_from_handle(key)
for handle in self.slist.keys():
source = self.db.get_source_from_handle(handle)
if not source:
continue
data = (self.sid (source.get_gramps_id ()), source)
data = (self.sid(handle), source)
sorted.append (data)
sorted.sort ()
for (source_id, source) in sorted:
@ -896,12 +907,19 @@ class GedcomWriter:
val = Utils.personalConstantAttributes[name]
else:
val = ""
if val :
self.writeln("1 %s" % val)
value = self.cnvtxt(attr.get_value()).replace('\r',' ')
if val:
if value:
self.writeln("1 %s %s" % (val, value))
else:
self.writeln("1 %s" % val)
else:
self.writeln("1 EVEN")
self.writeln("2 TYPE %s" % self.cnvtxt(name))
self.writeln("2 PLAC %s" % self.cnvtxt(attr.get_value()).replace('\r',' '))
if value:
self.writeln("2 TYPE %s %s" % (self.cnvtxt(name), value
))
else:
self.writeln("2 TYPE %s" % self.cnvtxt(name))
if attr.get_note():
self.write_long_text("NOTE",2,self.cnvtxt(attr.get_note()))
for srcref in attr.get_source_references():
@ -944,6 +962,8 @@ class GedcomWriter:
photos = []
for photo in photos:
if self.private and photo.get_privacy():
continue
photo_obj_id = photo.get_reference_handle()
photo_obj = self.db.get_object_from_handle(photo_obj_id)
if photo_obj and photo_obj.get_mime_type() == "image/jpeg":
@ -975,14 +995,19 @@ class GedcomWriter:
if self.adopt == GedcomInfo.ADOPT_PEDI:
if family[1] == RelLib.Person.CHILD_ADOPTED:
self.writeln("2 PEDI Adopted")
for family_handle in person.get_family_handle_list():
if family_handle != None and self.flist.has_key(family_handle):
self.writeln("1 FAMS @%s@" % self.fid(family_handle))
for srcref in person.get_source_references():
self.write_source_ref(1,srcref)
if not restricted:
if self.obje:
for url in person.get_url_list():
if self.private and url.get_privacy():
continue
self.writeln('1 OBJE')
self.writeln('2 FORM URL')
if url.get_description():
@ -1105,10 +1130,7 @@ class GedcomWriter:
def print_date(self,prefix,date):
start = date.get_start_date()
val = date.get_text()
if val:
self.writeln("%s %s" % (prefix,self.cnvtxt(val)))
elif not date.is_empty ():
if start != Date.EMPTY:
cal = date.get_calendar()
mod = date.get_modifier()
if date.get_modifier() == Date.MOD_SPAN:
@ -1120,6 +1142,8 @@ class GedcomWriter:
else:
val = make_date(start,cal,mod)
self.writeln("%s %s" % (prefix,val))
elif date.get_text():
self.writeln("%s %s" % (prefix,self.cnvtxt(date.get_text())))
def write_person_name(self,name,nick):
firstName = self.cnvtxt(name.get_first_name())
@ -1220,14 +1244,9 @@ class GedcomWriter:
if match:
self.writeln('1 REFN %d' % int(match.groups()[0]))
def sid(self,id):
if self.sidmap.has_key(id):
return self.sidmap[id]
else:
val = "S%05d" % self.sidval
self.sidval = self.sidval + 1
self.sidmap[id] = val
return val
def sid(self,handle):
source = self.db.get_source_from_handle(handle)
return source.get_gramps_id()
#-------------------------------------------------------------------------
#

View File

@ -211,6 +211,61 @@ longopts = [
shortopts = "O:i:o:f:a:p:?"
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
child_rel_list = [
_("None"), _("Birth"), _("Adopted"), _("Stepchild"),
_("Sponsored"), _("Foster"), _("Unknown"), _("Other"), ]
child_rel_notrans = [
"None", "Birth", "Adopted", "Stepchild",
"Sponsored", "Foster", "Unknown", "Other", ]
child_relations = TransTable( {
_("Birth") : "Birth",
_("Adopted") : "Adopted",
_("Stepchild") : "Stepchild",
_("Sponsored") : "Sponsored",
_("Foster") : "Foster",
_("None") : "None",
_("Unknown") : "Unknown",
_("Other") : "Other",
})
#-------------------------------------------------------------------------
#
# Confidence
#
#-------------------------------------------------------------------------
confidence = [
_("Very Low"),
_("Low"),
_("Normal"),
_("High"),
_("Very High"),
]
#-------------------------------------------------------------------------
#
# Family event string mappings
#
#-------------------------------------------------------------------------
familyConstantEvents = {
"Annulment" : "ANUL",
"Divorce Filing" : "DIVF",
"Divorce" : "DIV",
"Engagement" : "ENGA",
"Marriage Banns" : "MARB",
"Marriage Contract" : "MARC",
"Marriage License" : "MARL",
"Marriage Settlement" : "MARS",
"Marriage" : "MARR"
}
#-------------------------------------------------------------------------
#
#

View File

@ -1,7 +1,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2004 Donald N. Allingham
# Copyright (C) 2000-2005 Donald N. Allingham
#
# 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
@ -30,7 +30,6 @@ Provides a BaseDoc based interface to the AbiWord document format.
#
#-------------------------------------------------------------------------
import base64
import string
import os
import BaseDoc
@ -59,8 +58,7 @@ class AbiWordDoc(BaseDoc.BaseDoc):
self.level = 0
self.new_page = 0
self.in_table = 0
self.icount = 0;
self.imap = {}
self.in_paragraph = 0
def open(self,filename):
"""Opens the document, writing the necessary header information.
@ -161,15 +159,16 @@ class AbiWordDoc(BaseDoc.BaseDoc):
def close(self):
"""Write the trailing information and closes the file"""
self.f.write('</section>\n')
if len(self.media_list) > 0:
if self.media_list:
self.f.write('<data>\n')
for file_tuple in self.media_list:
tag = self.imap[file_tuple[0]]
img = ImgManip.ImgManip(file_tuple[0])
for tag_number in range(len(self.media_list)):
name = self.media_list[tag_number]
img = ImgManip.ImgManip(name)
buf = img.png_data()
self.f.write('<d name="%s" mime-type="image/png" base64="yes">\n' % tag)
self.f.write(
'<d name="image%d" mime-type="image/png" base64="yes">\n'
% tag_number)
self.f.write(base64.encodestring(buf))
self.f.write('</d>\n')
self.f.write('</data>\n')
@ -206,14 +205,21 @@ class AbiWordDoc(BaseDoc.BaseDoc):
act_height = y_cm
act_width = x_cm*aspect_ratio
self.media_list.append((name,act_width,act_height))
if name in self.media_list:
tag_number = self.media_list.index(name)
else:
tag_number = len(self.media_list)
self.media_list.append(name)
tag = "image%d" % self.icount
if self.in_paragraph: # We cannot insert photo
start_p = end_p = '' # outside text paragraph.
else: # So if not in paragraph, insert one.
start_p = '<p>'
end_p = '</p>'
self.f.write('<image dataid="%s" props="width:%.3fcm; ' % (tag, x_cm))
self.f.write('height:%.3fcm"/>' % y_cm)
self.imap[name] = tag
self.icount += 1
self.f.write('%s<image dataid="image%d" '
'props="height:%.3fcm; width:%.3fcm"/>%s '
% (start_p,tag_number,act_height,act_width,end_p))
def start_superscript(self):
self.text = self.text + '<c props="text-position:superscript">'
@ -222,6 +228,7 @@ class AbiWordDoc(BaseDoc.BaseDoc):
self.text = self.text + '</c>'
def start_paragraph(self,style_name,leader=None):
self.in_paragraph = 1
style = self.style_list[style_name]
self.current_style = style
self.f.write('<p style="%s">' % style_name)
@ -236,6 +243,7 @@ class AbiWordDoc(BaseDoc.BaseDoc):
self.new_page = 1
def end_paragraph(self):
self.in_paragraph = 0
self.f.write('</p>\n')
def write_note(self,text,format,style_name):
@ -249,7 +257,7 @@ class AbiWordDoc(BaseDoc.BaseDoc):
for line in text.split('\n\n'):
self.start_paragraph(style_name)
line = line.replace('\n',' ')
line = string.join(string.split(line))
line = ' '.join(line.split())
self.write_text(line)
self.end_paragraph()

View File

@ -139,7 +139,7 @@ except ImportError:
def _(s): return s
__version__ = '1.4'
default_keywords = ['_']
default_keywords = ['_','__']
EMPTYSTRING = ''

View File

@ -4891,7 +4891,7 @@ tories&lt;/b&gt;</property>
<property name="spacing">0</property>
<child>
<widget class="GtkTable" id="table40">
<widget class="GtkTable" id="container">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="n_rows">10</property>
@ -15821,7 +15821,7 @@ tories&lt;/b&gt;</property>
<child>
<widget class="GtkLabel" id="label247">
<property name="visible">True</property>
<property name="label" translatable="yes">C_ounty:</property>
<property name="label" translatable="yes">Co_unty:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
@ -15853,7 +15853,7 @@ tories&lt;/b&gt;</property>
<child>
<widget class="GtkLabel" id="label248">
<property name="visible">True</property>
<property name="label" translatable="yes">Co_untry:</property>
<property name="label" translatable="yes">Count_ry:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
@ -16229,7 +16229,7 @@ tories&lt;/b&gt;</property>
<child>
<widget class="GtkLabel" id="label291">
<property name="visible">True</property>
<property name="label" translatable="yes">P_hone:</property>
<property name="label" translatable="yes">Phon_e:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
@ -25317,40 +25317,12 @@ Very High</property>
<widget class="GtkTable" id="table8">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<widget class="GtkLabel" id="label180">
<property name="visible">True</property>
<property name="label" translatable="yes">Path:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label181">
<property name="visible">True</property>
@ -25400,8 +25372,8 @@ Very High</property>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
@ -25435,7 +25407,7 @@ Very High</property>
</child>
<child>
<widget class="GtkLabel" id="path">
<widget class="GtkLabel" id="type">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
@ -25461,34 +25433,6 @@ Very High</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="type">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
@ -25525,8 +25469,8 @@ Very High</property>
<widget class="GtkTable" id="table49">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
@ -25551,8 +25495,8 @@ Very High</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
@ -25573,8 +25517,8 @@ Very High</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
@ -25600,10 +25544,10 @@ Very High</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
@ -25660,12 +25604,61 @@ Very High</property>
</child>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label180">
<property name="visible">True</property>
<property name="label" translatable="yes">Path:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="path">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
</widget>

View File

@ -1086,6 +1086,16 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
all.add_rule(GenericFilter.HasTextMatchingRegexpOf([]))
filter_list.append(all)
all = GenericFilter.GenericFilter()
all.set_name(_("People with notes"))
all.add_rule(GenericFilter.HasNote([]))
filter_list.append(all)
all = GenericFilter.ParamFilter()
all.set_name(_("People with notes containing..."))
all.add_rule(GenericFilter.HasNoteMatchingSubstringOf([]))
filter_list.append(all)
self.filter_model = GenericFilter.FilterStore(filter_list)
self.filter_list.set_model(self.filter_model)
self.filter_list.set_active(self.filter_model.default_index())
@ -1118,7 +1128,14 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
import MergePeople
p1 = self.db.get_person_from_handle(mlist[0])
p2 = self.db.get_person_from_handle(mlist[1])
merger = MergePeople.MergePeopleUI(self.db,p1,p2,self.merge_update)
if p1 and p2:
merger = MergePeople.MergePeopleUI(self.db,p1,p2,self.merge_update)
else:
msg = _("Cannot merge people.")
msg2 = _("Exactly two people must be selected to perform a merge. "
"A second person can be selected by holding down the "
"control key while clicking on the desired person.")
ErrorDialog(msg,msg2)
elif page == PLACE_VIEW:
self.place_view.merge()
elif page == SOURCE_VIEW:
@ -1141,7 +1158,14 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
import MergePeople
p1 = self.db.get_person_from_handle(mlist[0])
p2 = self.db.get_person_from_handle(mlist[1])
merger = MergePeople.Compare(self.db,p1,p2,self.merge_update)
if p1 and p2:
merger = MergePeople.Compare(self.db,p1,p2,self.merge_update)
else:
msg = _("Cannot merge people.")
msg2 = _("Exactly two people must be selected to perform a merge. "
"A second person can be selected by holding down the "
"control key while clicking on the desired person.")
ErrorDialog(msg,msg2)
elif page == PLACE_VIEW:
self.place_view.merge()
elif page == SOURCE_VIEW:

View File

@ -82,6 +82,7 @@ def runTool(database,active_person,callback,parent=None):
checker.check_events()
checker.check_place_references()
checker.check_source_references()
database.transaction_commit(trans, _("Check Integrity"))
database.enable_signals()
database.request_rebuild()
@ -115,6 +116,7 @@ class CheckIntegrity:
self.invalid_birth_events = []
self.invalid_death_events = []
self.invalid_place_references = []
self.invalid_source_references = []
def family_errors(self):
return len(self.broken_parent_links) + len(self.broken_links) + len(self.empty_family)
@ -429,6 +431,123 @@ class CheckIntegrity:
self.db.commit_event(event,self.trans)
self.invalid_place_references.append(key)
def check_source_references(self):
known_handles = self.db.get_source_handles()
cursor = self.db.get_person_cursor()
data = cursor.first()
while data:
handle,info = data
person = RelLib.Person()
person.unserialize(info)
handle_list = person.get_referenced_handles_recursively()
bad_handles = [ item[1] for item in handle_list
if item[0] == 'Source' and
item[1] not in known_handles ]
if bad_handles:
person.remove_source_references(bad_handles)
self.db.commit_person(person,self.trans)
new_bad_handles = [handle for handle in bad_handles if handle
not in self.invalid_source_references]
self.invalid_source_references += new_bad_handles
data = cursor.next()
cursor.close()
cursor = self.db.get_family_cursor()
data = cursor.first()
while data:
handle,info = data
family = RelLib.Family()
family.unserialize(info)
handle_list = family.get_referenced_handles_recursively()
bad_handles = [ item[1] for item in handle_list
if item[0] == 'Source' and
item[1] not in known_handles ]
if bad_handles:
family.remove_source_references(bad_handles)
self.db.commit_family(family,self.trans)
new_bad_handles = [handle for handle in bad_handles if handle
not in self.invalid_source_references]
self.invalid_source_references += new_bad_handles
data = cursor.next()
cursor.close()
cursor = self.db.get_place_cursor()
data = cursor.first()
while data:
handle,info = data
place = RelLib.Place()
place.unserialize(info)
handle_list = place.get_referenced_handles_recursively()
bad_handles = [ item[1] for item in handle_list
if item[0] == 'Source' and
item[1] not in known_handles ]
if bad_handles:
place.remove_source_references(bad_handles)
self.db.commit_family(place,self.trans)
new_bad_handles = [handle for handle in bad_handles if handle
not in self.invalid_source_references]
self.invalid_source_references += new_bad_handles
data = cursor.next()
cursor.close()
cursor = self.db.get_source_cursor()
data = cursor.first()
while data:
handle,info = data
source = RelLib.Source()
source.unserialize(info)
handle_list = source.get_referenced_handles_recursively()
bad_handles = [ item[1] for item in handle_list
if item[0] == 'Source' and
item[1] not in known_handles ]
if bad_handles:
source.remove_source_references(bad_handles)
self.db.commit_source(source,self.trans)
new_bad_handles = [handle for handle in bad_handles if handle
not in self.invalid_source_references]
self.invalid_source_references += new_bad_handles
data = cursor.next()
cursor.close()
cursor = self.db.get_media_cursor()
data = cursor.first()
while data:
handle,info = data
obj = RelLib.MediaObject()
obj.unserialize(info)
handle_list = obj.get_referenced_handles_recursively()
bad_handles = [ item[1] for item in handle_list
if item[0] == 'Source' and
item[1] not in known_handles ]
if bad_handles:
obj.remove_source_references(bad_handles)
self.db.commit_object(obj,self.trans)
new_bad_handles = [handle for handle in bad_handles if handle
not in self.invalid_source_references]
self.invalid_source_references += new_bad_handles
data = cursor.next()
cursor.close()
cursor = self.db.get_event_cursor()
data = cursor.first()
while data:
handle,info = data
event = RelLib.Event()
event.unserialize(info)
handle_list = event.get_referenced_handles_recursively()
bad_handles = [ item[1] for item in handle_list
if item[0] == 'Source' and
item[1] not in known_handles ]
if bad_handles:
event.remove_source_references(bad_handles)
self.db.commit_event(event,self.trans)
new_bad_handles = [handle for handle in bad_handles if handle
not in self.invalid_source_references]
self.invalid_source_references += new_bad_handles
data = cursor.next()
cursor.close()
def build_report(self,cl=0):
bad_photos = len(self.bad_photo)
replaced_photos = len(self.replaced_photo)
@ -443,8 +562,10 @@ class CheckIntegrity:
death_invalid = len(self.invalid_death_events)
person = birth_invalid + death_invalid
place_references = len(self.invalid_place_references)
source_references = len(self.invalid_source_references)
errors = blink + efam + photos + rel + person + event_invalid + place_references
errors = blink + efam + photos + rel + person \
+ event_invalid + place_references + source_references
if errors == 0:
if cl:
@ -534,6 +655,10 @@ class CheckIntegrity:
self.text.write(_("1 place was referenced but not found\n"))
elif place_references > 1:
self.text.write(_("%d places were referenced, but not found\n") % place_references)
if source_references == 1:
self.text.write(_("1 source was referenced but not found\n"))
elif source_references > 1:
self.text.write(_("%d sources were referenced, but not found\n") % source_references)
return errors

View File

@ -0,0 +1,65 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2005 Martin Hawlisch, Donald N. Allingham
#
# 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$
"Dump gender stats"
import gtk
import ListModel
_GENDER = [ _(u'female'), _(u'male'), _(u'unknown') ]
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def DumpGenderStatsPlugin(database,active_person,callback,parent=None):
stats_list = []
for name in database.genderStats.stats.keys():
stats_list.append((name,)+database.genderStats.stats[name]+(_GENDER[database.genderStats.guess_gender(name)],))
titles = [(_('Name'),1,100), (_('Male'),2,70),
(_('Female'),3,70), ('Unknown',4,70), (_('Guess'),5,70) ]
treeview = gtk.TreeView()
model = ListModel.ListModel(treeview,titles)
for entry in stats_list:
model.add(entry,entry[0])
w = gtk.Window()
w.set_position(gtk.WIN_POS_MOUSE)
w.set_default_size(400,300)
s=gtk.ScrolledWindow()
s.add(treeview)
w.add(s)
w.show_all()
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
from PluginMgr import register_tool
register_tool(
DumpGenderStatsPlugin,
_("Dumps gender statistics"),
category=_("Debug"),
description=_("Will dump the statistics for the gender guessing from the first name.")
)

View File

@ -2,6 +2,7 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2004 Martin Hawlisch
# Copyright (C) 2005 Donald N. Allingham
#
# 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
@ -81,20 +82,29 @@ class CalendarWriterOptionBox:
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % self.person.get_primary_name().get_name())
des.add_rule(GenericFilter.IsDescendantOf([self.person.get_handle(),1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % self.person.get_primary_name().get_name())
ans.add_rule(GenericFilter.IsAncestorOf([self.person.get_handle(),1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
if person:
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") %
self.person.get_primary_name().get_name())
com.add_rule(GenericFilter.HasCommonAncestorWith([self.person.get_handle()]))
des.add_rule(GenericFilter.IsDescendantOf(
[self.person.get_gramps_id(),1]))
self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com])
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") %
self.person.get_primary_name().get_name())
ans.add_rule(GenericFilter.IsAncestorOf(
[self.person.get_gramps_id(),1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
self.person.get_primary_name().get_name())
com.add_rule(GenericFilter.HasCommonAncestorWith(
[self.person.get_gramps_id()]))
self.filter_menu = GenericFilter.build_filter_menu(
[all,des,ans,com])
else:
self.filter_menu = GenericFilter.build_filter_menu([all])
filter_obj.set_menu(self.filter_menu)
the_box = self.topDialog.get_widget('vbox1')

View File

@ -2,6 +2,7 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2004 Martin Hawlisch
# Copyright (C) 2005 Donald N. Allingham
#
# 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
@ -27,7 +28,6 @@
#
#-------------------------------------------------------------------------
import os
import string
import time
import re
@ -84,20 +84,29 @@ class CardWriterOptionBox:
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % self.person.get_primary_name().get_name())
des.add_rule(GenericFilter.IsDescendantOf([self.person.get_handle(),1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % self.person.get_primary_name().get_name())
ans.add_rule(GenericFilter.IsAncestorOf([self.person.get_handle(),1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
if self.person:
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") %
self.person.get_primary_name().get_name())
com.add_rule(GenericFilter.HasCommonAncestorWith([self.person.get_handle()]))
des.add_rule(GenericFilter.IsDescendantOf(
[self.person.get_gramps_id(),1]))
self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com])
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") %
self.person.get_primary_name().get_name())
ans.add_rule(GenericFilter.IsAncestorOf(
[self.person.get_gramps_id(),1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
self.person.get_primary_name().get_name())
com.add_rule(GenericFilter.HasCommonAncestorWith(
[self.person.get_gramps_id()]))
self.filter_menu = GenericFilter.build_filter_menu(
[all,des,ans,com])
else:
self.filter_menu = GenericFilter.build_filter_menu([all])
filter_obj.set_menu(self.filter_menu)
the_box = self.topDialog.get_widget('vbox1')

View File

@ -48,6 +48,7 @@ import Report
import ReportOptions
import GenericFilter
import const
import RelLib
from BaseDoc import PAPER_LANDSCAPE
from latin_utf8 import utf8_to_latin
from QuestionDialog import ErrorDialog
@ -233,8 +234,8 @@ class GraphViz:
family = self.database.get_family_from_handle(family_handle)
father_handle = family.get_father_handle()
mother_handle = family.get_mother_handle()
fadopted = frel != _("Birth")
madopted = mrel != _("Birth")
fadopted = frel != RelLib.Person.CHILD_REL_BIRTH
madopted = mrel != RelLib.Person.CHILD_REL_BIRTH
famid = family.get_gramps_id().replace('-','_')
if (self.show_families and
(father_handle and person_dict.has_key(father_handle) or
@ -504,10 +505,10 @@ class GraphVizOptions(ReportOptions.ReportOptions):
"""Set up the list of possible content filters."""
if person:
name = person.get_primary_name().get_name()
handle = person.get_handle()
gramps_id = person.get_gramps_id()
else:
name = 'PERSON'
handle = ''
gramps_id = ''
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
@ -515,15 +516,15 @@ class GraphVizOptions(ReportOptions.ReportOptions):
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % name)
des.add_rule(GenericFilter.IsDescendantOf([handle,1]))
des.add_rule(GenericFilter.IsDescendantOf([gramps_id,1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % name)
ans.add_rule(GenericFilter.IsAncestorOf([handle,1]))
ans.add_rule(GenericFilter.IsAncestorOf([gramps_id,1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") % name)
com.add_rule(GenericFilter.HasCommonAncestorWith([handle]))
com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id]))
return [all,des,ans,com]

View File

@ -497,14 +497,14 @@ class IndivCompleteOptions(ReportOptions.ReportOptions):
"""Set up the list of possible content filters."""
if person:
name = person.get_primary_name().get_name()
handle = person.get_handle()
gramps_id = person.get_gramps_id()
else:
name = 'PERSON'
handle = ''
gramps_id = ''
filt_id = GenericFilter.GenericFilter()
filt_id.set_name(name)
filt_id.add_rule(GenericFilter.HasIdOf([handle]))
filt_id.add_rule(GenericFilter.HasIdOf([gramps_id]))
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
@ -512,15 +512,15 @@ class IndivCompleteOptions(ReportOptions.ReportOptions):
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % name)
des.add_rule(GenericFilter.IsDescendantOf([handle,1]))
des.add_rule(GenericFilter.IsDescendantOf([gramps_id,1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % name)
ans.add_rule(GenericFilter.IsAncestorOf([handle,1]))
ans.add_rule(GenericFilter.IsAncestorOf([gramps_id,1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") % name)
com.add_rule(GenericFilter.HasCommonAncestorWith([handle]))
com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id]))
return [filt_id,all,des,ans,com]

View File

@ -21,6 +21,8 @@ pkgdata_PYTHON = \
DetAncestralReport.py\
DetDescendantReport.py\
EventCmp.py\
ExportVCalendar.py\
ExportVCard.py\
FamilyGroup.py\
FanChart.py\
FtmStyleAncestors.py\
@ -29,6 +31,7 @@ pkgdata_PYTHON = \
GraphViz.py\
IndivComplete.py\
IndivSummary.py\
ImportvCard.py\
Merge.py\
PatchNames.py\
ReadPkg.py\
@ -81,7 +84,9 @@ GLADEFILES = \
book.glade\
writeftree.glade\
genewebexport.glade\
scratchpad.glade
scratchpad.glade\
vcardexport.glade\
vcalendarexport.glade
GRAPHICS = \
stock_link.png

View File

@ -135,7 +135,7 @@ class BasePage:
of.write('<br>\n')
of.write('<br>\n')
of.write('<hr>\n')
of.write('<div class="footer">Generated by ')
of.write('<div class="footer">%s ' % _('Generated by'))
of.write('<a href="http://gramps.sourceforge.net">GRAMPS</a> ')
of.write('on 13 December 2004.')
of.write('</div>\n')
@ -159,14 +159,14 @@ class BasePage:
of.write(' <h1 class="navtitle">%s</h1>\n' % self.title_str)
of.write(' <hr>\n')
of.write(' <div class="nav">\n')
of.write(' <a href="index.html">Home</a> &nbsp;\n')
of.write(' <a href="introduction.html">Introduction</a> &nbsp;\n')
of.write(' <a href="surnames.html">Surnames</a> &nbsp;\n')
of.write(' <a href="individuals.html">Individuals</a> &nbsp;\n')
of.write(' <a href="sources.html">Sources</a> &nbsp;\n')
of.write(' <a href="places.html">Places</a> &nbsp;\n')
of.write(' <a href="download.html">Download</a> &nbsp;\n')
of.write(' <a href="contact.html">Contact</a> &nbsp;\n')
of.write(' <a href="index.html">%s</a> &nbsp;\n' % _('Home'))
of.write(' <a href="introduction.html">%s</a> &nbsp;\n' % _('Introduction'))
of.write(' <a href="surnames.html">%s</a> &nbsp;\n' % _('Surnames'))
of.write(' <a href="individuals.html">%s</a> &nbsp;\n' % _('Individuals'))
of.write(' <a href="sources.html">%s</a> &nbsp;\n' % _('Sources'))
of.write(' <a href="places.html">%s</a> &nbsp;\n' % _('Places'))
of.write(' <a href="download.html">%s</a> &nbsp;\n' % _('Download'))
of.write(' <a href="contact.html">%s</a> &nbsp;\n' % _('Contact'))
of.write(' </div>\n')
of.write(' </div>\n')
@ -255,9 +255,9 @@ class PlaceListPage(BasePage):
for handle in handle_list:
place = db.get_place_from_handle(handle)
n = place.title
n = ReportUtils.place_name(db,handle)
if len(n) == 0:
if not n or len(n) == 0:
continue
if n[0] != last_letter:
@ -274,7 +274,7 @@ class PlaceListPage(BasePage):
of.write('<tr><td class="category">&nbsp;</td>')
of.write('<td class="data">')
of.write(n)
of.write(' <sup><a href="%s">' % place.gramps_id)
of.write(' <sup><a href="%s.html">' % place.gramps_id)
of.write('[%s]' % place.gramps_id)
of.write('</a></sup></td></tr>')
@ -282,6 +282,58 @@ class PlaceListPage(BasePage):
self.display_footer(of)
of.close()
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
class PlacePage(BasePage):
def __init__(self, db, title, place_handle, html_dir, src_list):
place = db.get_place_from_handle( place_handle)
BasePage.__init__(self,title)
page_name = os.path.join(html_dir,place.get_gramps_id()+".html")
of = open(page_name, "w")
place_name = ReportUtils.place_name(db,place_handle)
self.display_header(of,place_name,
db.get_researcher().get_name())
of.write('<h3>%s</h3>\n' % place_name)
photolist = place.get_media_list()
if photolist:
photo_handle = photolist[0].get_reference_handle()
photo = db.get_object_from_handle(photo_handle)
try:
newpath = photo.gramps_id + os.path.splitext(photo.get_path())[1]
shutil.copyfile(photo.get_path(),os.path.join(html_dir,newpath))
of.write('<div class="snapshot">\n')
of.write('<a href="%s">' % newpath)
of.write('<img class="thumbnail" border="0" src="%s" ' % newpath)
of.write('height="100"></a>')
of.write('</div>\n')
except (IOError,OSError),msg:
ErrorDialog(str(msg))
# TODO: Add more information
of.write('<h4>%s</h4>\n' % _('Narrative'))
of.write('<hr>\n')
noteobj = place.get_note_object()
if noteobj:
format = noteobj.get_format()
text = noteobj.get()
if format:
text = "<pre>" + "<br>".join(text.split("\n"))
else:
text = "</p><p>".join(text.split("\n"))
of.write('<p>%s</p>\n' % text)
self.display_footer(of)
of.close()
#------------------------------------------------------------------------
#
#
@ -403,13 +455,16 @@ class HomePage(BasePage):
else:
mime_type = obj.get_mime_type()
if mime_type and mime_type.startswith("image"):
newpath = obj.gramps_id + os.path.splitext(obj.get_path())[1]
shutil.copyfile(obj.get_path(),
os.path.join(html_dir,newpath))
of.write('<div align="center">\n')
of.write('<img border="0" ')
of.write('src="%s" />' % newpath)
of.write('</div>\n')
try:
newpath = obj.gramps_id + os.path.splitext(obj.get_path())[1]
shutil.copyfile(obj.get_path(),
os.path.join(html_dir,newpath))
of.write('<div align="center">\n')
of.write('<img border="0" ')
of.write('src="%s" />' % newpath)
of.write('</div>\n')
except (IOError,OSError),msg:
ErrorDialog(str(msg))
note_obj = obj.get_note_object()
if note_obj:
@ -447,9 +502,12 @@ class SourcesPage(BasePage):
index = 1
for handle in handle_list:
source = db.get_source_from_handle(handle)
of.write('<tr><td class="category">%d.</td>\n' % index)
of.write('<td class="data">')
of.write(source.get_title())
of.write('</td></tr>\n')
index += 1
of.write('</table>\n<blockquote>\n')
@ -615,13 +673,16 @@ class IndividualPage(BasePage):
photo_handle = photolist[0].get_reference_handle()
photo = self.db.get_object_from_handle(photo_handle)
newpath = self.person.gramps_id + os.path.splitext(photo.get_path())[1]
shutil.copyfile(photo.get_path(),os.path.join(self.dirpath,newpath))
of.write('<div class="snapshot">\n')
of.write('<a href="%s">' % newpath)
of.write('<img class="thumbnail" border="0" src="%s" ' % newpath)
of.write('height="100"></a>')
of.write('</div>\n')
try:
newpath = self.person.gramps_id + os.path.splitext(photo.get_path())[1]
shutil.copyfile(photo.get_path(),os.path.join(self.dirpath,newpath))
of.write('<div class="snapshot">\n')
of.write('<a href="%s">' % newpath)
of.write('<img class="thumbnail" border="0" src="%s" ' % newpath)
of.write('height="100"></a>')
of.write('</div>\n')
except (IOError,OSError),msg:
ErrorDialog(str(msg))
of.write('<div class="summaryarea">\n')
of.write('<h3>%s</h3>\n' % self.sort_name)
@ -819,6 +880,8 @@ class IndividualPage(BasePage):
of.write('</blockquote>\n')
def format_event(self,event):
for sref in event.get_source_references():
self.src_list.add(sref.get_base_handle())
descr = event.get_description()
place_handle = event.get_place_handle()
if place_handle:
@ -994,6 +1057,11 @@ class WebReport(Report.Report):
PlaceListPage(self.database, self.title, place_list,
dir_name, source_list)
for place in place_list:
print place
PlacePage(self.database, self.title, place, dir_name, source_list)
SourcesPage(self.database,self.title, source_list, dir_name)
self.progress_bar_done()
@ -1031,7 +1099,7 @@ class WebReportOptions(ReportOptions.ReportOptions):
'HTMLsplita' : 0,
'HTMLshorttree' : 1,
'HTMLimagedir' : 'images',
'HTMLtitle' : 'My Family Tree',
'HTMLtitle' : _('My Family Tree'),
'HTMLincid' : 0,
'HTMLidurl' : '',
'HTMLlinktidx' : 1,
@ -1058,10 +1126,10 @@ class WebReportOptions(ReportOptions.ReportOptions):
"""Set up the list of possible content filters."""
if person:
name = person.get_primary_name().get_name()
handle = person.get_handle()
gramps_id = person.get_gramps_id()
else:
name = 'PERSON'
handle = ''
gramps_is = ''
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
@ -1069,19 +1137,19 @@ class WebReportOptions(ReportOptions.ReportOptions):
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % name)
des.add_rule(GenericFilter.IsDescendantOf([handle,1]))
des.add_rule(GenericFilter.IsDescendantOf([gramps_id,1]))
df = GenericFilter.GenericFilter()
df.set_name(_("Descendant Families of %s") % name)
df.add_rule(GenericFilter.IsDescendantFamilyOf([handle]))
df.add_rule(GenericFilter.IsDescendantFamilyOf([gramps_id]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % name)
ans.add_rule(GenericFilter.IsAncestorOf([handle,1]))
ans.add_rule(GenericFilter.IsAncestorOf([gramps_id,1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") % name)
com.add_rule(GenericFilter.HasCommonAncestorWith([handle]))
com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id]))
return [all,des,df,ans,com]

View File

@ -818,10 +818,10 @@ class StatisticsChartOptions(ReportOptions.ReportOptions):
if person:
name = person.get_primary_name().get_name()
handle = person.get_handle()
gramps_id = person.get_gramps_id()
else:
name = 'PERSON'
handle = ''
gramps_id = ''
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
@ -829,15 +829,15 @@ class StatisticsChartOptions(ReportOptions.ReportOptions):
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % name)
des.add_rule(GenericFilter.IsDescendantOf([handle, 1]))
des.add_rule(GenericFilter.IsDescendantOf([gramps_id, 1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % name)
ans.add_rule(GenericFilter.IsAncestorOf([handle, 1]))
ans.add_rule(GenericFilter.IsAncestorOf([gramps_id, 1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") % name)
com.add_rule(GenericFilter.HasCommonAncestorWith([handle]))
com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id]))
return [all, des, ans, com]
@ -865,10 +865,14 @@ class StatisticsChartOptions(ReportOptions.ReportOptions):
self.reverse.show()
# year range
self.from_box = gtk.Entry(4)
self.from_box.set_text(str(self.options_dict['year_from']))
self.to_box = gtk.Entry(4)
self.to_box.set_text(str(self.options_dict['year_to']))
from_adj = gtk.Adjustment(value=self.options_dict['year_from'],
lower=1, upper=time.localtime()[0],
step_incr=1, page_incr=100)
self.from_box = gtk.SpinButton(adjustment=from_adj, digits=0)
to_adj = gtk.Adjustment(value=self.options_dict['year_to'],
lower=1, upper=time.localtime()[0],
step_incr=1, page_incr=100)
self.to_box = gtk.SpinButton(adjustment=to_adj, digits=0)
box = gtk.HBox()
box.add(self.from_box)
@ -897,8 +901,9 @@ class StatisticsChartOptions(ReportOptions.ReportOptions):
# max. pie item selection
tip = _("With fewer items pie chart and legend will be used instead of a bar chart.")
self.bar_items = gtk.Entry(2)
self.bar_items.set_text(str(self.options_dict['bar_items']))
pie_adj = gtk.Adjustment(value=self.options_dict['bar_items'],
lower=0, upper=20, step_incr=1)
self.bar_items = gtk.SpinButton(adjustment=pie_adj, digits=0)
dialog.add_option(_("Max. items for a pie"), self.bar_items, tip)
# -------------------------------------------------
@ -933,11 +938,11 @@ class StatisticsChartOptions(ReportOptions.ReportOptions):
"""
self.options_dict['sortby'] = _options.sorts[self.sort_menu.get_active()][0]
self.options_dict['reverse'] = int(self.reverse.get_active())
self.options_dict['year_to'] = int(self.to_box.get_text())
self.options_dict['year_from'] = int(self.from_box.get_text())
self.options_dict['year_to'] = int(self.to_box.get_value_as_int())
self.options_dict['year_from'] = int(self.from_box.get_value_as_int())
self.options_dict['no_years'] = int(self.no_years.get_active())
self.options_dict['gender'] = _options.genders[self.gender_menu.get_active()][0]
self.options_dict['bar_items'] = int(self.bar_items.get_text())
self.options_dict['bar_items'] = int(self.bar_items.get_value_as_int())
for key in _Extract.extractors:
self.options_dict[key] = int(self.charts[key].get_active())

View File

@ -402,10 +402,10 @@ class TimeLineOptions(ReportOptions.ReportOptions):
"""Set up the list of possible content filters."""
if person:
name = person.get_primary_name().get_name()
handle = person.get_handle()
gramps_id = person.get_gramps_id()
else:
name = 'PERSON'
handle = ''
gramps_id = ''
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
@ -413,15 +413,15 @@ class TimeLineOptions(ReportOptions.ReportOptions):
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % name)
des.add_rule(GenericFilter.IsDescendantOf([handle,1]))
des.add_rule(GenericFilter.IsDescendantOf([gramps_id,1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % name)
ans.add_rule(GenericFilter.IsAncestorOf([handle,1]))
ans.add_rule(GenericFilter.IsAncestorOf([gramps_id,1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") % name)
com.add_rule(GenericFilter.HasCommonAncestorWith([handle]))
com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id]))
return [all,des,ans,com]

View File

@ -715,12 +715,24 @@ class IndividualPage:
self.doc.write_text(_("Siblings"))
self.doc.end_paragraph()
self.doc.start_table("three","IndTable")
self.doc.start_table("four","IndTable")
self.doc.start_row()
self.doc.start_cell("NormalCell")
self.doc.start_paragraph("Label")
self.doc.write_text(_("Siblings"))
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.start_cell("NormalCell")
first = True
for child_handle in all_sisters:
child = self.db.get_person_from_handle(child_handle)
self.doc.start_paragraph("Data")
name = child.get_primary_name().get_regular_name()
if first:
self.doc.start_paragraph("Data")
first = False
else:
self.doc.write_text('\n')
if self.person.get_handle() == child_handle:
self.doc.write_text(name)
elif self.list.has_key(child_handle):
@ -729,8 +741,12 @@ class IndividualPage:
self.doc.end_link()
else:
self.doc.write_text(name)
if not first:
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.end_row()
self.doc.end_table()
#------------------------------------------------------------------------
#
@ -1093,7 +1109,7 @@ class WebReport(Report.Report):
def write_report(self):
dir_name = self.target_path
if dir_name == None:
if not dir_name:
dir_name = os.getcwd()
elif not os.path.isdir(dir_name):
parent_dir = os.path.dirname(dir_name)
@ -1256,10 +1272,10 @@ class WebReportOptions(ReportOptions.ReportOptions):
"""Set up the list of possible content filters."""
if person:
name = person.get_primary_name().get_name()
handle = person.get_handle()
gramps_id = person.get_gramps_id()
else:
name = 'PERSON'
handle = ''
gramps_id = ''
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
@ -1267,19 +1283,19 @@ class WebReportOptions(ReportOptions.ReportOptions):
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % name)
des.add_rule(GenericFilter.IsDescendantOf([handle,1]))
des.add_rule(GenericFilter.IsDescendantOf([gramps_id,1]))
df = GenericFilter.GenericFilter()
df.set_name(_("Descendant Families of %s") % name)
df.add_rule(GenericFilter.IsDescendantFamilyOf([handle]))
df.add_rule(GenericFilter.IsDescendantFamilyOf([gramps_id]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % name)
ans.add_rule(GenericFilter.IsAncestorOf([handle,1]))
ans.add_rule(GenericFilter.IsAncestorOf([gramps_id,1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") % name)
com.add_rule(GenericFilter.HasCommonAncestorWith([handle]))
com.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id]))
return [all,des,df,ans,com]

View File

@ -86,20 +86,28 @@ class FtreeWriterOptionBox:
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % self.person.get_primary_name().get_name())
des.add_rule(GenericFilter.IsDescendantOf([self.person.get_handle(),1]))
if self.person:
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") %
self.person.get_primary_name().get_name())
des.add_rule(GenericFilter.IsDescendantOf(
[self.person.get_gramps_id(),1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % self.person.get_primary_name().get_name())
ans.add_rule(GenericFilter.IsAncestorOf([self.person.get_handle(),1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s")
% self.person.get_primary_name().get_name())
ans.add_rule(GenericFilter.IsAncestorOf(
[self.person.get_gramps_id(),1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
self.person.get_primary_name().get_name())
com.add_rule(GenericFilter.HasCommonAncestorWith([self.person.get_handle()]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
self.person.get_primary_name().get_name())
com.add_rule(GenericFilter.HasCommonAncestorWith(
[self.person.get_gramps_id()]))
self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com])
self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com])
else:
self.filter_menu = GenericFilter.build_filter_menu([all])
filter_obj.set_menu(self.filter_menu)
the_box = self.top.get_widget("vbox1")

View File

@ -87,20 +87,29 @@ class GeneWebWriterOptionBox:
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % self.person.get_primary_name().get_name())
des.add_rule(GenericFilter.IsDescendantOf([self.person.get_handle(),1]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % self.person.get_primary_name().get_name())
ans.add_rule(GenericFilter.IsAncestorOf([self.person.get_handle(),1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
if self.person:
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") %
self.person.get_primary_name().get_name())
com.add_rule(GenericFilter.HasCommonAncestorWith([self.person.get_handle()]))
des.add_rule(GenericFilter.IsDescendantOf(
[self.person.get_gramps_id(),1]))
self.filter_menu = GenericFilter.build_filter_menu([all,des,ans,com])
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") %
self.person.get_primary_name().get_name())
ans.add_rule(GenericFilter.IsAncestorOf(
[self.person.get_gramps_id(),1]))
com = GenericFilter.GenericFilter()
com.set_name(_("People with common ancestor with %s") %
self.person.get_primary_name().get_name())
com.add_rule(GenericFilter.HasCommonAncestorWith(
[self.person.get_gramps_id()]))
self.filter_menu = GenericFilter.build_filter_menu(
[all,des,ans,com])
else:
self.filter_menu = GenericFilter.build_filter_menu([all])
filter_obj.set_menu(self.filter_menu)
the_box = self.topDialog.get_widget('vbox1')

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -147,11 +147,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
if other_person.get_gender() == RelLib.Person.MALE:
return ("ægtefælle",[])
else:
return ("hustru",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -338,8 +338,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
return ("spouse",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -254,11 +254,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
if other_person.get_gender() == RelLib.Person.MALE:
return ("marido",[])
else:
return ("mujer",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -182,8 +182,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
return ("puoliso",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -39,28 +39,30 @@ from gettext import gettext as _
#-------------------------------------------------------------------------
_level_name = [ "", "premier", "deuxième", "troisième", "quatrième", "cinquième", "sixième",
"septième", "huitième", "neuvième", "dicième", "onzième", "douzième",
"septième", "huitième", "neuvième", "dixième", "onzième", "douzième",
"treizième", "quatorzième", "quinzième", "seizième",
"dix-septième", "dix-huitième", "dix_neuvième", "vingtième", ]
"dix-septième", "dix-huitième", "dix-neuvième", "vingtième", "vingt-et-unième", "vingt-deuxième",
"vingt-deuxième", "vingt-troisième","vingt-quatrième","vingt-sixième","vingt-septième",
"vingt-huitième","vingt-neuvième","trentième" ]
_parents_level = [ "", "les parents", "les grand-parents", "les arrières grand-parents",
_parents_level = [ "", "les parents", "les grand-parents", "les arrière-grand-parents",
"les trisaïeux", ]
_father_level = [ "", "le père", "le grand-père", "l'arrière grand-père", "le trisaïeul", ]
_father_level = [ "", "le père", "le grand-père paternel", "l'arrière-grand-père paternel", "le trisaïeul paternel", ]
_mother_level = [ "", "la mère", "la grand-mère", "l'arrière grand-mère", "la trisaïeule", ]
_mother_level = [ "", "la mère", "la grand-mère maternelle", "l'arrière-grand-mère maternelle", "la trisaïeule maternelle", ]
_son_level = [ "", "le fils", "le petits-fils", "l'arrière petit-fils", ]
_son_level = [ "", "le fils", "le petit-fils", "l'arrière-petit-fils", ]
_daughter_level = [ "", "la fille", "la petite-fille", "l'arrière petite-fille", ]
_daughter_level = [ "", "la fille", "la petite-fille", "l'arrière-petite-fille", ]
_sister_level = [ "", "la soeur", "la tante", "la grande-tante", "l'arrière grande-tante", ]
_sister_level = [ "", "la soeur", "la tante", "la grand-tante", "l'arrière-grand-tante", ]
_brother_level = [ "", "le frère", "l'oncle", "le grand-oncle", "l'arrière grand-oncle", ]
_brother_level = [ "", "le frère", "l'oncle", "le grand-oncle", "l'arrière-grand-oncle", ]
_nephew_level = [ "", "le neveu", "le petit-neveu", "l'arrière petit-neveu", ]
_nephew_level = [ "", "le neveu", "le petit-neveu", "l'arrière-petit-neveu", ]
_niece_level = [ "", "la nièce", "la petite-nièce", "l'arrière petite-nièce", ]
_niece_level = [ "", "la nièce", "la petite-nièce", "l'arrière-petite-nièce", ]
#-------------------------------------------------------------------------
#
@ -73,10 +75,16 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
Relationship.RelationshipCalculator.__init__(self,db)
def get_male_cousin(self,level):
return "le cousin au %s degré" % (_level_name[level])
if level>len(_level_name)-1:
return "le parent lointain"
else:
return "le cousin au %s degré" % (_level_name[level])
def get_female_cousin(self,level):
return "la cousine au %s degré" % (_level_name[level])
if level>len(_level_name)-1:
return "la parente lointaine"
else:
return "la cousine au %s degré" % (_level_name[level])
def get_parents(self,level):
if level>len(_parents_level)-1:
@ -146,11 +154,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
if other_person.get_gender() == RelLib.Person.MALE:
return ("le mari",[])
else:
return ("la femme",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -268,13 +268,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
if other_person.get_gender() == RelLib.Person.MALE:
#FIXME: husband
return ("spouse",[])
else:
#FIXME: wife
return ("spouse",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
if self.is_fathermother_in_law(other_person,orig_person):
if other_person.getGender() == RelLib.Person.MALE:

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -151,8 +151,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
return ("coniuge",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -232,15 +232,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
return ('spouse', [])
# FIXME: need Norwegian term for spouse. If gender-specific, use the code below.
# UPDATE by Frode: unsure about how it's included in the finished code, so I need
# to see this running to know if it is the right words to use.
# if other_person.get_gender() == RelLib.Person.MALE:
# return ("ektemann",[])
# else:
# return ("hustru",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -206,8 +206,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
return ("spouse",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

View File

@ -2,7 +2,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004 Donald N. Allingham
# Copyright (C) 2003-2005 Donald N. Allingham
#
# 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
@ -187,11 +187,9 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
if self.is_spouse(orig_person,other_person):
if other_person.get_gender() == RelLib.Person.MALE:
return ("make",[])
else:
return ("maka",[])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<filters>
<filter name="asfd" function="and">
<rule class="Is a male">
</rule>
</filter>
<filter name="asfasdfasdf" function="and">
</filter>
</filters>