Merged geps21 branch, changes r15866-16034, into trunk

svn: r16035
This commit is contained in:
Benny Malengier
2010-10-24 14:43:47 +00:00
48 changed files with 3589 additions and 1548 deletions
+19 -14
View File
@@ -498,14 +498,12 @@ class GedcomWriter(UpdateCallback):
"""
Write the names associated with the person to the current level.
Since nicknames are now separate from the name structure, we search
the attribute list to see if we can find a nickname. Because we do
not know the mappings, we just take the first nickname we find, and
add it to the primary name.
Since nicknames in version < 3.3 are separate from the name structure,
we search the attribute list to see if we can find a nickname.
Because we do not know the mappings, we just take the first nickname
we find, and add it to the primary name.
If a nickname is present in the name structure, it has precedence
All other names are assumed to not have a nickname, even if other
nicknames exist in the attribute list.
"""
nicknames = [ attr.get_value() for attr in person.get_attribute_list()
if int(attr.get_type()) == gen.lib.AttributeType.NICKNAME ]
@@ -1193,7 +1191,7 @@ class GedcomWriter(UpdateCallback):
elif date.get_text():
self.__writeln(level, 'DATE', date.get_text())
def __person_name(self, name, nick):
def __person_name(self, name, attr_nick):
"""
n NAME <NAME_PERSONAL> {1:1}
+1 NPFX <NAME_PIECE_PREFIX> {0:1}
@@ -1208,13 +1206,21 @@ class GedcomWriter(UpdateCallback):
gedcom_name = name.get_gedcom_name()
firstname = name.get_first_name().strip()
patron = name.get_patronymic().strip()
if patron:
firstname = "%s %s" % (firstname, patron)
surname = name.get_surname().replace('/', '?')
surprefix = name.get_surname_prefix().replace('/', '?')
surns = []
surprefs = []
for surn in name.get_surname_list():
surns.append(surn.get_surname().replace('/', '?'))
if surn.get_connector():
#we store connector with the surname
surns[-1] = surns[-1] + ' ' + surn.get_connector()
surprefs.append(surn.get_prefix().replace('/', '?'))
surname = ', '.join(surns)
surprefix = ', '.join(surprefs)
suffix = name.get_suffix()
title = name.get_title()
nick = name.get_nick_name()
if nick.strip() == '':
nick = attr_nick
self.__writeln(1, 'NAME', gedcom_name)
@@ -1224,7 +1230,6 @@ class GedcomWriter(UpdateCallback):
self.__writeln(2, 'SPFX', surprefix)
if surname:
self.__writeln(2, 'SURN', surname)
if name.get_suffix():
self.__writeln(2, 'NSFX', suffix)
if name.get_title():
+29 -16
View File
@@ -783,16 +783,26 @@ class GrampsXmlWriter(UpdateCallback):
if rel != "":
self.g.write(' %s<rel type="%s"/>\n' % (sp,rel) )
def write_last(self, name,indent=1):
p = name.get_surname_prefix()
n = name.get_surname()
g = name.get_group_as()
self.g.write('%s<last' % (' '*indent))
if p:
self.g.write(' prefix="%s"' % escxml(p))
if g:
self.g.write(' group="%s"' % escxml(g))
self.g.write('>%s</last>\n' % self.fix(n))
def write_surname(self, surname, indent=1):
"""
Writes a surname of the name
"""
pre = surname.get_prefix()
con = surname.get_connector()
nam = surname.get_surname()
der = surname.get_origintype().xml_str()
pri = surname.get_primary()
self.g.write('%s<surname' % (' '*indent))
if pre:
self.g.write(' prefix="%s"' % escxml(pre))
if not pri:
self.g.write(' prim="0"')
if con:
self.g.write(' connector="%s"' % escxml(con))
if der:
self.g.write(' derivation="%s"' % escxml(der))
self.g.write('>%s</surname>\n' % self.fix(nam))
def write_line(self,tagname,value,indent=1):
if value:
@@ -915,12 +925,15 @@ class GrampsXmlWriter(UpdateCallback):
if name.get_display_as() != 0:
self.g.write(' display="%d"' % name.get_display_as())
self.g.write('>\n')
self.write_line("first", name.get_first_name(),index+1)
self.write_line("call", name.get_call_name(),index+1)
self.write_last(name,index+1)
self.write_line("suffix", name.get_suffix(),index+1)
self.write_line("patronymic", name.get_patronymic(),index+1)
self.write_line("title", name.get_title(),index+1)
self.write_line("first", escxml(name.get_first_name()),index+1)
self.write_line("call", escxml(name.get_call_name()),index+1)
for surname in name.get_surname_list():
self.write_surname(surname,index+1)
self.write_line("suffix", escxml(name.get_suffix()),index+1)
self.write_line("title", escxml(name.get_title()),index+1)
self.write_line("nick", escxml(name.get_nick_name()), index+1)
self.write_line("familynick", escxml(name.get_family_nick_name()), index+1)
self.write_line("group", escxml(name.get_group_as()), index+1)
if name.date:
self.write_date(name.date,4)
self.write_note_list(name.get_note_list(),index+1)
+110 -14
View File
@@ -77,8 +77,9 @@ def find_surname(key, data):
"""
Return the surname from the data stream. Used for building a secondary
index.
This function is not needed, as we don't use the secondary index.
"""
return str(data[3][5])
return str("a")
def find_idmap(key, data):
"""
@@ -138,6 +139,10 @@ class GrampsBSDDB(DbGrdb, UpdateCallback):
This is replaced for internal use by gen/db/dbdir.py
However, this class is still used for import of the 2.2.x
GRDB format. In 3.0+ this format is no longer used.
We only need to upgrade the old main tables.
That will be used to append data to the database this GrampsBSDDB is
imported to.
"""
def __init__(self, use_txn = True):
@@ -1247,19 +1252,6 @@ class GrampsBSDDB(DbGrdb, UpdateCallback):
self.surname_list = list(set(self.surnames.keys()))
self.sort_surname_list()
def remove_from_surname_list(self, person):
"""
Check whether there are persons with the same surname left in
the database. If not then we need to remove the name from the list.
The function must be overridden in the derived class.
"""
name = str(person.get_primary_name().get_surname())
try:
if self.surnames.keys().count(name) == 1:
self.surname_list.remove(unicode(name))
except ValueError:
pass
def __get_obj_from_gramps_id(self, val, tbl, class_init, prim_tbl):
if tbl.has_key(str(val)):
#if str(val) in tbl:
@@ -1563,6 +1555,8 @@ class GrampsBSDDB(DbGrdb, UpdateCallback):
self.gramps_upgrade_13()
if version < 14:
self.gramps_upgrade_14()
if version < 15:
self.gramps_upgrade_15()
LOG.debug("Upgrade time: %s %s", int(time.time()-t), "seconds")
def gramps_upgrade_10(self):
@@ -2589,6 +2583,108 @@ class GrampsBSDDB(DbGrdb, UpdateCallback):
name_type, prefix, patronymic,
group_as, sort_as, display_as, call)
def gramps_upgrade_15(self):
"""Upgrade database from version 14 to 15. This upgrade adds:
* tagging
* surname list
"""
length = len(self.person_map)+10
self.set_total(length)
# ---------------------------------
# Modify Person
# ---------------------------------
for handle in self.person_map.keys():
person = self.person_map[handle]
(junk_handle, # 0
gramps_id, # 1
gender, # 2
primary_name, # 3
alternate_names, # 4
death_ref_index, # 5
birth_ref_index, # 6
event_ref_list, # 7
family_list, # 8
parent_family_list, # 9
media_list, # 10
address_list, # 11
attribute_list, # 12
urls, # 13
ord_list, # 14
psource_list, # 15
pnote_list, # 16
change, # 17
marker, # 18
pprivate, # 19
person_ref_list, # 20
) = person
new_primary_name = self.convert_name_15(primary_name)
new_alternate_names = [self.convert_name_15(altname) for altname in
alternate_names]
new_person = (junk_handle, # 0
gramps_id, # 1
gender, # 2
new_primary_name, # 3
new_alternate_names,# 4
death_ref_index, # 5
birth_ref_index, # 6
event_ref_list, # 7
family_list, # 8
parent_family_list, # 9
media_list, # 10
address_list, # 11
attribute_list, # 12
urls, # 13
ord_list, # 14
psource_list, # 15
pnote_list, # 16
change, # 17
marker, # 18
pprivate, # 19
person_ref_list, # 20
[] # 21, tags
)
the_txn = self.env.txn_begin()
self.person_map.put(str(handle), new_person, txn=the_txn)
the_txn.commit()
self.update(length)
#surname is now different, normally remove secondary index with names
#we skip this, as this database will not be used after the import
# Bump up database version. Separate transaction to save metadata.
the_txn = self.env.txn_begin()
self.metadata.put('version', 15, txn=the_txn)
the_txn.commit()
def convert_name_15(self, name):
(privacy, source_list, note_list, date,
first_name, surname, suffix, title,
name_type, prefix, patronymic,
group_as, sort_as, display_as, call) = name
connector = u""
origintype = (NameOriginType.NONE, u"")
patorigintype = (NameOriginType.PATRONYMIC, u"")
if patronymic.strip() == u"":
#no patronymic, create a single surname
surname_list = [(surname, prefix, True, origintype, connector)]
else:
#a patronymic, if no surname or equal as patronymic, a single surname
if (surname.strip() == u"") or (surname == patronymic and prefix == u""):
surname_list = [(patronymic, prefix, True, patorigintype, connector)]
else:
#two surnames, first patronymic, then surname which is primary
surname_list = [(patronymic, u"", False, patorigintype, u""),
(surname, prefix, True, origintype, connector)]
#return new value, add two empty strings for nick and family nick
return (privacy, source_list, note_list, date,
first_name, surname_list, suffix, title, name_type,
group_as, sort_as, display_as, call, u"", u"")
def set_auto_remove(self):
"""
BSDDB change log settings using new method with renamed attributes
+159 -64
View File
@@ -96,9 +96,23 @@ def importData(database, filename, callback=None, cl=0):
database.smap = {}
database.pmap = {}
database.fmap = {}
xml_file = open_file(filename, cl)
versionparser = VersionParser(xml_file)
if xml_file is None or \
version_is_valid(versionparser, cl) is False:
if cl:
sys.exit(1)
else:
return
version_string = versionparser.get_xmlns_version()
#reset file to the start
xml_file.seek(0)
change = os.path.getmtime(filename)
parser = GrampsParser(database, callback, change)
parser = GrampsParser(database, callback, change, version_string)
linecounter = LineParser(filename)
line_cnt = linecounter.get_count()
@@ -107,17 +121,7 @@ def importData(database, filename, callback=None, cl=0):
read_only = database.readonly
database.readonly = False
xml_file = open_file(filename, cl)
if xml_file is None or \
version_is_valid(xml_file, cl) is False:
if cl:
sys.exit(1)
else:
return
try:
xml_file.seek(0)
info = parser.parse(xml_file, line_cnt, person_cnt)
except IOError, msg:
if cl:
@@ -348,8 +352,10 @@ class LineParser(object):
#-------------------------------------------------------------------------
class GrampsParser(UpdateCallback):
def __init__(self, database, callback, change):
def __init__(self, database, callback, change, version_string):
UpdateCallback.__init__(self, callback)
#version of the xml file
self.version_string = version_string
self.stext_list = []
self.scomments_list = []
self.note_list = []
@@ -423,6 +429,8 @@ class GrampsParser(UpdateCallback):
self.childref = None
self.personref = None
self.name = None
self.surname = None
self.surnamepat = None
self.home = None
self.owner = gen.lib.Researcher()
self.func_list = [None]*50
@@ -440,17 +448,33 @@ class GrampsParser(UpdateCallback):
self.eidswap = {}
self.func_map = {
#name part
"name": (self.start_name, self.stop_name),
"first": (None, self.stop_first),
"call": (None, self.stop_call),
"aka": (self.start_name, self.stop_aka), #deprecated < 1.3.0
"last": (self.start_last, self.stop_last), #deprecated in 1.4.0
"nick": (None, self.stop_nick),
"title": (None, self.stop_title),
"suffix": (None, self.stop_suffix),
"patronymic": (self.start_patronymic, self.stop_patronymic), #deprecated in 1.4.0
"familynick": (None, self.stop_familynick), #new in 1.4.0
"group": (None, self.stop_group), #new in 1.4.0, replaces attribute
#new in 1.4.0
"surname": (self.start_surname, self.stop_surname),
#
"namemaps": (None, None),
"name-formats": (None, None),
#other
"address": (self.start_address, self.stop_address),
"addresses": (None, None),
"childlist": (None, None),
"aka": (self.start_name, self.stop_aka),
"childlist": (None, None),
"attribute": (self.start_attribute, self.stop_attribute),
"attr_type": (None, self.stop_attr_type),
"attr_value": (None, self.stop_attr_value),
"bookmark": (self.start_bmark, None),
"bookmarks": (None, None),
"format": (self.start_format, None),
"name-formats": (None, None),
"child": (self.start_child, None),
"childof": (self.start_childof, None),
"childref": (self.start_childref, self.stop_childref),
@@ -476,17 +500,11 @@ class GrampsParser(UpdateCallback):
"rel": (self.start_rel, None),
"region": (self.start_region, None),
"father": (self.start_father, None),
"first": (None, self.stop_first),
"call": (None, self.stop_call),
"gender": (None, self.stop_gender),
"header": (None, None),
"last": (self.start_last, self.stop_last),
"map": (self.start_namemap, None),
"mediapath": (None, self.stop_mediapath),
"mother": (self.start_mother, None),
"name": (self.start_name, self.stop_name),
"namemaps": (None, None),
"nick": (None, self.stop_nick),
"note": (self.start_note, self.stop_note),
"noteref": (self.start_noteref, None),
"p": (None, self.stop_ptag),
@@ -511,7 +529,6 @@ class GrampsParser(UpdateCallback):
"status": (self.start_status, None),
"sealed_to": (self.start_sealed_to, None),
"coord": (self.start_coord, None),
"patronymic": (None, self.stop_patronymic),
"pos": (self.start_pos, None),
"postal": (None, self.stop_postal),
"range": (self.start_range, None),
@@ -536,13 +553,11 @@ class GrampsParser(UpdateCallback):
"stext": (None, self.stop_stext),
"stitle": (None, self.stop_stitle),
"street": (None, self.stop_street),
"style": (self.start_style, None),
"suffix": (None, self.stop_suffix),
"style": (self.start_style, None),
"tag": (self.start_tag, None),
"tagref": (self.start_tagref, None),
"tags": (None, None),
"text": (None, self.stop_text),
"title": (None, self.stop_title),
"url": (self.start_url, None),
"repository": (self.start_repo, self.stop_repo),
"reporef": (self.start_reporef, self.stop_reporef),
@@ -743,6 +758,11 @@ class GrampsParser(UpdateCallback):
return self.nidswap[gramps_id]
def parse(self, ifile, linecount=0, personcount=0):
"""
Parse the xml file
:param ifile: must be a file handle that is already open, with position
at the start of the file
"""
if personcount < 1000:
no_magic = True
else:
@@ -1305,6 +1325,14 @@ class GrampsParser(UpdateCallback):
except KeyError:
pass
def start_surname(self, attrs):
self.surname = gen.lib.Surname()
self.surname.set_prefix(attrs.get("prefix", ""))
self.surname.set_primary(bool(attrs.get("primary",0)))
self.surname.set_connector(attrs.get("connector", ""))
origin_type = attrs.get("derivation", "")
self.surname.origintype.set_from_xml_str(origin_type)
def start_namemap(self, attrs):
type = attrs.get('type')
key = attrs['key']
@@ -1321,9 +1349,17 @@ class GrampsParser(UpdateCallback):
self.db.set_name_group_mapping(key, value)
def start_last(self, attrs):
self.name.prefix = attrs.get('prefix', '')
""" This is the element in version < 1.4.0 to do the surname"""
self.surname = gen.lib.Surname()
self.surname.prefix = attrs.get('prefix', '')
self.name.group_as = attrs.get('group', '')
def start_patronymic(self, attrs):
""" This is the element in version < 1.4.0 to do the patronymic"""
self.surnamepat = gen.lib.Surname()
self.surnamepat.set_origintype(gen.lib.NameTypeOrigin(
gen.lib.NameTypeOrigin.PATRONYMIC))
def start_style(self, attrs):
"""
Styled text tag in notes (v1.4.0 onwards).
@@ -1927,14 +1963,8 @@ class GrampsParser(UpdateCallback):
self.num_places = 0
def start_database(self, attrs):
try:
# This is a proper way to get the XML version
xmlns = attrs.get('xmlns')
self.version_string = xmlns.split('/')[4]
except:
# Before we had a proper DTD, the version was hard to determine
# so we're setting it to 1.0.0
self.version_string = '1.0.0'
# we already parsed xml once in VersionParser to obtain version
pass
def start_pos(self, attrs):
self.person.position = (int(attrs["x"]), int(attrs["y"]))
@@ -2078,15 +2108,62 @@ class GrampsParser(UpdateCallback):
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.event.add_note(note.handle)
elif self.alt_name:
# former aka tag -- alternate name
if self.name.get_type() == "":
self.name.set_type(gen.lib.NameType.AKA)
self.person.add_alternate_name(self.name)
else:
#first correct old xml that has no nametype set
if self.alt_name:
# alternate name or former aka tag
if self.name.get_type() == "":
self.name.set_type(gen.lib.NameType.AKA)
else:
if self.name.get_type() == "":
self.name.set_type(gen.lib.NameType.BIRTH)
#same logic as bsddb upgrade for xml < 1.4.0 which will
#have a surnamepat and/or surname. From 1.4.0 surname has been
#added to name in self.stop_surname
if not self.surnamepat:
#no patronymic, only add surname if present
if self.surname:
self.name.add_surname(self.surname)
self.name.set_primary_surname(0)
else:
#a patronymic, if no surname, a single surname
if not self.surname:
self.name.add_surname(self.surnamepat)
self.name.set_primary_surname(0)
else:
#two surnames, first patronymic, then surname which is primary
self.name.add_surname(self.surnamepat)
self.name.add_surname(self.surname)
self.name.set_primary_surname(1)
if self.alt_name:
self.person.add_alternate_name(self.name)
else:
self.person.set_primary_name(self.name)
self.name = None
self.surname = None
self.surnamepat = None
def stop_aka(self, tag):
if self.name.get_type() == "":
self.name.set_type(gen.lib.NameType.AKA)
if not self.surnamepat:
#no patronymic, only add surname if present
if self.surname:
self.name.add_surname(self.surname)
self.name.set_primary_surname(0)
else:
if self.name.get_type() == "":
self.name.set_type(gen.lib.NameType.BIRTH)
self.person.set_primary_name (self.name)
#a patronymic, if no surname, a single surname
if not self.surname:
self.name.add_surname(self.surnamepat)
self.name.set_primary_surname(0)
else:
#two surnames, first patronymic, then surname which is primary
self.name.add_surname(self.surnamepat)
self.name.add_surname(self.surname)
self.name.set_primary_surname(1)
self.person.add_alternate_name(self.name)
self.name = None
def stop_rname(self, tag):
@@ -2256,28 +2333,53 @@ class GrampsParser(UpdateCallback):
self.source_ref.add_note(note.handle)
def stop_last(self, tag):
if self.surname:
self.surname.set_surname(tag)
if not tag.strip() and not self.surname.get_prefix().strip():
#consider empty surname as no surname
self.surname = None
def stop_surname(self, tag):
if self.name:
self.name.set_surname(tag)
self.surname.set_surname(tag)
self.name.add_surname(self.surname)
self.surname = None
def stop_group(self, tag):
""" group name of a name"""
if self.name:
self.name.set_group_as(tag)
def stop_suffix(self, tag):
if self.name:
self.name.set_suffix(tag)
def stop_patronymic(self, tag):
if self.name:
self.name.set_patronymic(tag)
if self.surnamepat:
self.surnamepat.set_surname(tag)
if not tag.strip():
self.surnamepat = None
def stop_title(self, tag):
if self.name:
self.name.set_title(tag)
def stop_nick(self, tag):
if self.person:
"""in < 1.3.0 nick is on person and mapped to attribute
from 1.4.0 it is a name element
"""
if self.name:
self.name.set_nick_name(tag)
elif self.person:
attr = gen.lib.Attribute()
attr.set_type(gen.lib.AttributeType.NICKNAME)
attr.set_value(tag)
self.person.add_attribute(attr)
def stop_familynick(self, tag):
if self.name:
self.name.set_family_nick_name(tag)
def stop_text(self, tag):
self.note_text = tag
@@ -2379,12 +2481,6 @@ class GrampsParser(UpdateCallback):
elif self.in_scomments:
self.scomments_list.append(tag)
def stop_aka(self, tag):
self.person.add_alternate_name(self.name)
if self.name.get_type() == "":
self.name.set_type(gen.lib.NameType.AKA)
self.name = None
def startElement(self, tag, attrs):
self.func_list[self.func_index] = (self.func, self.tlist)
self.func_index += 1
@@ -2469,7 +2565,6 @@ class VersionParser(object):
self.__p.StartElementHandler = self.__element_handler
self.__gramps_version = 'unknown'
self.__xml_version = '1.0.0'
xml_file.seek(0)
self.__p.ParseFile(xml_file)
@@ -2541,25 +2636,25 @@ def open_file(filename, cli):
return xml_file
def version_is_valid(filename, cli):
def version_is_valid(versionparser, cli):
"""
Validate the xml version.
:param versionparser: A VersionParser object to work with
"""
parser = VersionParser(filename)
if parser.get_xmlns_version() > libgrampsxml.GRAMPS_XML_VERSION:
if versionparser.get_xmlns_version() > libgrampsxml.GRAMPS_XML_VERSION:
msg = _("The .gramps file you are importing was made by version %(newer)s of "
"Gramps, while you are running an older version %(older)s. "
"The file will not be imported. Please upgrade to the latest "
"version of Gramps and try again." ) % {
'newer' : parser.get_gramps_version(), 'older' : const.VERSION }
'newer' : versionparser.get_gramps_version(), 'older' : const.VERSION }
if cli:
LOG.warn(msg)
return False
else:
ErrorDialog(msg)
return False
if parser.get_xmlns_version() < '1.0.0':
if versionparser.get_xmlns_version() < '1.0.0':
msg = _("The .gramps file you are importing was made by version "
"%(oldgramps)s of Gramps, while you are running a more "
"recent version %(newgramps)s.\n\n"
@@ -2567,9 +2662,9 @@ def version_is_valid(filename, cli):
" Gramps that supports version %(xmlversion)s of the xml.\nSee"
"\n http://gramps-project.org/wiki/index.php?title=GRAMPS_XML\n "
"for more info."
) % {'oldgramps': parser.get_gramps_version(),
) % {'oldgramps': versionparser.get_gramps_version(),
'newgramps': const.VERSION,
'xmlversion': parser.get_xmlns_version(),
'xmlversion': versionparser.get_xmlns_version(),
}
if cli:
LOG.warn(msg)
@@ -2577,7 +2672,7 @@ def version_is_valid(filename, cli):
else:
ErrorDialog(_('The file will not be imported'), msg)
return False
elif parser.get_xmlns_version() < '1.1.0':
elif versionparser.get_xmlns_version() < '1.1.0':
msg = _("The .gramps file you are importing was made by version "
"%(oldgramps)s of Gramps, while you are running a much "
"more recent version %(newgramps)s.\n\n"
@@ -2587,9 +2682,9 @@ def version_is_valid(filename, cli):
"is version %(xmlversion)s of the xml.\nSee"
"\n http://gramps-project.org/wiki/index.php?title=GRAMPS_XML\n"
"for more info."
) % {'oldgramps': parser.get_gramps_version(),
) % {'oldgramps': versionparser.get_gramps_version(),
'newgramps': const.VERSION,
'xmlversion': parser.get_xmlns_version(),
'xmlversion': versionparser.get_xmlns_version(),
}
if cli:
LOG.warn(msg)
+36 -11
View File
@@ -1673,16 +1673,25 @@ class GedcomParser(UpdateCallback):
match = SURNAME_RE.match(text)
if match:
#/surname/ extra, we assume extra is given name
names = match.groups()
name.set_first_name(names[1].strip())
name.set_surname(names[0].strip())
surn = gen.lib.Surname()
surn.set_surname(names[0].strip())
surn.set_primary()
name.set_surname_list([surn])
else:
try:
names = NAME_RE.match(text).groups()
# given /surname/ extra, we assume extra is suffix
name.set_first_name(names[0].strip())
name.set_surname(names[2].strip())
surn = gen.lib.Surname()
surn.set_surname(names[2].strip())
surn.set_primary()
name.set_surname_list([surn])
name.set_suffix(names[4].strip())
except:
# something strange, set as first name
name.set_first_name(text.strip())
return name
@@ -2782,7 +2791,7 @@ class GedcomParser(UpdateCallback):
sub_state.name = name
sub_state.level = 2
self.__parse_level(sub_state, self.name_parse_tbl, self.__undefined)
self.__parse_level(sub_state, self.name_parse_tbl, self.__undefined)
def __person_object(self, line, state):
"""
@@ -3164,7 +3173,13 @@ class GedcomParser(UpdateCallback):
@param state: The current state
@type state: CurrentState
"""
state.name.set_surname_prefix(line.data.strip())
if state.name.get_surname_list():
state.name.get_surname_list()[0].set_prefix(line.data.strip())
else:
surn = gen.lib.Surname()
surn.set_prefix(line.data.strip())
surn.set_primary()
state.name.set_surname_list([surn])
self.__skip_subordinate_levels(state.level+1)
def __name_surn(self, line, state):
@@ -3174,7 +3189,13 @@ class GedcomParser(UpdateCallback):
@param state: The current state
@type state: CurrentState
"""
state.name.set_surname(line.data.strip())
if state.name.get_surname_list():
state.name.get_surname_list()[0].set_surname(line.data.strip())
else:
surn = gen.lib.Surname()
surn.set_surname(line.data.strip())
surn.set_primary()
state.name.set_surname_list([surn])
self.__skip_subordinate_levels(state.level+1)
def __name_marnm(self, line, state):
@@ -3188,7 +3209,10 @@ class GedcomParser(UpdateCallback):
data = text.split()
if len(data) == 1:
name = gen.lib.Name(state.person.primary_name)
name.set_surname(data[0].strip())
surn = gen.lib.Surname()
surn.set_surname(data[0].strip())
surn.set_primary()
name.set_surname_list([surn])
name.set_type(gen.lib.NameType.MARRIED)
state.person.add_alternate_name(name)
elif len(data) > 1:
@@ -3203,8 +3227,12 @@ class GedcomParser(UpdateCallback):
@param state: The current state
@type state: CurrentState
"""
if state.name.get_suffix() == "":
if state.name.get_suffix() == "" or state.name.get_suffix() == line.data:
#suffix might be set before when parsing name string
state.name.set_suffix(line.data)
else:
#previously set suffix different, to not loose information, append
state.name.set_suffix(state.name.get_suffix() + ' ' + line.data)
self.__skip_subordinate_levels(state.level+1)
def __name_nick(self, line, state):
@@ -3214,10 +3242,7 @@ class GedcomParser(UpdateCallback):
@param state: The current state
@type state: CurrentState
"""
attr = gen.lib.Attribute()
attr.set_type(gen.lib.AttributeType.NICKNAME)
attr.set_value(line.data)
state.person.add_attribute(attr)
state.name.set_nick_name(line.data.strip())
self.__skip_subordinate_levels(state.level+1)
def __name_aka(self, line, state):
+1
View File
@@ -211,6 +211,7 @@ class DbGrdb(Callback):
self.family_rel_types = set()
self.event_role_names = set()
self.name_types = set()
self.origin_types = set()
self.repository_types = set()
self.note_types = set()
self.source_media_types = set()
+4 -1
View File
@@ -259,9 +259,12 @@ class BasePersonView(ListView):
Add a new person to the database.
"""
person = gen.lib.Person()
#the editor requires a surname
person.primary_name.add_surname(gen.lib.Surname())
person.primary_name.set_primary_surname(0)
try:
EditPerson(self.dbstate, self.uistate, [], gen.lib.Person())
EditPerson(self.dbstate, self.uistate, [], person)
except Errors.WindowActiveError:
pass
+2 -2
View File
@@ -54,7 +54,7 @@ class SameSurname(Rule):
def apply(self, db, person):
src = self.list[0].upper()
for name in [person.get_primary_name()] + person.get_alternate_names():
if name.surname and name.surname.upper() == src.upper():
if name.get_surname() and name.get_surname().upper() == src.upper():
return True
return False
@@ -103,7 +103,7 @@ def run(database, document, person):
surname = person
rsurname = person
# display the title
sdoc.title(_("People with the surname '%s'") % surname)
sdoc.title(_("People sharing the surname '%s'") % surname)
sdoc.paragraph("")
stab.columns(_("Person"), _("Birth Date"), _("Name type"))
filter = GenericFilterFactory('Person')()
+5 -3
View File
@@ -37,6 +37,7 @@ import gtk
# gramps modules
#
#-------------------------------------------------------------------------
from gen.db import find_surname_name
import const
from gui.utils import ProgressMeter
import GrampsDisplay
@@ -243,11 +244,12 @@ class ChangeNames(tool.BatchTool, ManagedWindow.ManagedWindow):
#person = Person(data)
change = False
for name in [person.get_primary_name()] + person.get_alternate_names():
sname = name.get_surname()
sname = find_surname_name(handle, name.serialize())
if sname in changelist:
change = True
sname = self.name_cap(sname)
name.set_surname(sname)
for surn in name.get_surname_list():
sname = self.name_cap(surn.get_surname())
surn.set_surname(sname)
if change:
#cursor.update(handle, person.serialize())
self.db.commit_person(person, transaction=self.trans)
+19 -15
View File
@@ -144,7 +144,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
GrampsDisplay.help(WIKI_HELP_PAGE , WIKI_HELP_SEC)
def ancestors_of(self,p1_id,id_list):
def ancestors_of(self, p1_id, id_list):
if (not p1_id) or (p1_id in id_list):
return
id_list.append(p1_id)
@@ -181,7 +181,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
except Errors.WindowActiveError:
pass
def find_potentials(self,thresh):
def find_potentials(self, thresh):
self.progress = ProgressMeter(_('Find Duplicates'),
_('Looking for duplicate people'))
@@ -197,7 +197,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
for p1_id in self.db.iter_person_handles():
self.progress.step()
p1 = self.db.get_person_from_handle(p1_id)
key = self.gen_key(p1.get_primary_name().get_surname())
key = self.gen_key(get_surnames(p1.get_primary_name()))
if p1.get_gender() == gen.lib.Person.MALE:
if key in males:
males[key].append(p1_id)
@@ -216,7 +216,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
self.progress.step()
p1 = self.db.get_person_from_handle(p1key)
key = self.gen_key(p1.get_primary_name().get_surname())
key = self.gen_key(get_surnames(p1.get_primary_name()))
if p1.get_gender() == gen.lib.Person.MALE:
remaining = males[key]
else:
@@ -246,7 +246,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
self.length = len(self.list)
self.progress.close()
def gen_key(self,val):
def gen_key(self, val):
if self.use_soundex:
try:
return soundex.soundex(val)
@@ -255,7 +255,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
else:
return val
def compare_people(self,p1,p2):
def compare_people(self, p1, p2):
name1 = p1.get_primary_name()
name2 = p2.get_primary_name()
@@ -397,7 +397,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
chance += value
return chance
def name_compare(self,s1,s2):
def name_compare(self, s1, s2):
if self.use_soundex:
try:
return soundex.compare(s1,s2)
@@ -406,7 +406,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
else:
return s1 == s2
def date_match(self,date1,date2):
def date_match(self, date1, date2):
if date1.is_empty() or date2.is_empty():
return 0
if date1.is_equal(date2):
@@ -425,7 +425,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
else:
return -1
def range_compare(self,date1,date2):
def range_compare(self, date1, date2):
start_date_1 = date1.get_start_date()[0:3]
start_date_2 = date2.get_start_date()[0:3]
stop_date_1 = date1.get_stop_date()[0:3]
@@ -454,9 +454,9 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
if not name1 or not name:
return 0
srn1 = name.get_surname()
srn1 = get_surnames(name)
sfx1 = name.get_suffix()
srn2 = name1.get_surname()
srn2 = get_surnames(name1)
sfx2 = name1.get_suffix()
if not self.name_compare(srn1,srn2):
@@ -476,7 +476,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
else:
return self.list_reduce(list2,list1)
def place_match(self,p1_id,p2_id):
def place_match(self, p1_id, p2_id):
if p1_id == p2_id:
return 1
@@ -509,7 +509,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
value += 0.25
return min(value,1) if value else -1
def list_reduce(self,list1,list2):
def list_reduce(self, list1, list2):
value = 0
for name in list1:
for name2 in list2:
@@ -526,7 +526,7 @@ class Merge(tool.Tool,ManagedWindow.ManagedWindow):
class ShowMatches(ManagedWindow.ManagedWindow):
def __init__(self,dbstate,uistate,track,the_list,the_map,callback):
def __init__(self, dbstate, uistate, track, the_list, the_map, callback):
ManagedWindow.ManagedWindow.__init__(self,uistate,track,self.__class__)
self.dellist = {}
@@ -632,7 +632,11 @@ def get_name_obj(person):
return person.get_primary_name()
else:
return None
def get_surnames(name):
"""Construct a full surname of the surnames"""
' '.join([surn.get_surname() for surn in name.get_surname_list()])
#-------------------------------------------------------------------------
#
#
+333 -138
View File
@@ -70,24 +70,19 @@ WIKI_HELP_SEC = _('manual|Extract_Information_from_Names')
# List of possible surname prefixes. Notice that you must run the tool
# multiple times for prefixes such as "van der".
prefix_list = [
PREFIX_LIST = [
"de", "van", "von", "di", "le", "du", "dela", "della",
"des", "vande", "ten", "da", "af", "den", "das", "dello",
"del", "en", "ein", "el" "et", "les", "lo", "los", "un",
"um", "una", "uno", "der", "ter", "te", "die",
]
CONNECTOR_LIST = ['e', 'y', ]
CONNECTOR_LIST_NONSPLIT = ['de', 'van']
_title_re = re.compile(r"^ ([A-Za-z][A-Za-z]+\.) \s+ (.+) $", re.VERBOSE)
_nick_re = re.compile(r"(.+) \s* [(\"] (.+) [)\"]", re.VERBOSE)
# Find a prefix in the first_name
_fn_prefix_re = re.compile("(\S+)\s+(%s)\s*$" % '|'.join(prefix_list),
re.IGNORECASE)
# Find a prefix in the surname
_sn_prefix_re = re.compile("^\s*(%s)\s+(.+)" % '|'.join(prefix_list),
re.IGNORECASE)
#-------------------------------------------------------------------------
#
@@ -101,7 +96,11 @@ _sn_prefix_re = re.compile("^\s*(%s)\s+(.+)" % '|'.join(prefix_list),
class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
titleid = 1
nickid = 2
pref1id = 3
compid = 4
def __init__(self, dbstate, uistate, options_class, name, callback=None):
self.label = _('Name and title extraction tool')
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self.__class__)
@@ -110,12 +109,63 @@ class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
tool.BatchTool.__init__(self, dbstate, options_class, name)
if self.fail:
return
winprefix = gtk.Dialog("Default prefix and connector settings",
self.uistate.window,
gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
winprefix.set_has_separator(False)
winprefix.vbox.set_spacing(5)
hboxpref = gtk.HBox()
hboxpref.pack_start(gtk.Label(_('Prefixes to search for:')),
expand=False, padding=5)
self.prefixbox = gtk.Entry()
self.prefixbox.set_text(', '.join(PREFIX_LIST))
hboxpref.pack_start(self.prefixbox)
winprefix.vbox.pack_start(hboxpref)
hboxcon = gtk.HBox()
hboxcon.pack_start(gtk.Label(_('Connectors splitting surnames:')),
expand=False, padding=5)
self.conbox = gtk.Entry()
self.conbox.set_text(', '.join(CONNECTOR_LIST))
hboxcon.pack_start(self.conbox)
winprefix.vbox.pack_start(hboxcon)
hboxconns = gtk.HBox()
hboxconns.pack_start(gtk.Label(_('Connectors not splitting surnames:')),
expand=False, padding=5)
self.connsbox = gtk.Entry()
self.connsbox.set_text(', '.join(CONNECTOR_LIST_NONSPLIT))
hboxconns.pack_start(self.connsbox)
winprefix.vbox.pack_start(hboxconns)
winprefix.show_all()
winprefix.resize(700, 100)
response = winprefix.run()
self.prefix_list = self.prefixbox.get_text().split(',')
self.prefix_list = map(strip, self.prefix_list)
self.prefixbox = None
self.connector_list = self.conbox.get_text().split(',')
self.connector_list = map(strip, self.connector_list)
self.conbox = None
self.connector_list_nonsplit = self.connsbox.get_text().split(',')
self.connector_list_nonsplit = map(strip, self.connector_list_nonsplit)
self.connsbox = None
# Find a prefix in the first_name
self._fn_prefix_re = re.compile("(\S+)\s+(%s)\s*$" % '|'.join(self.prefix_list),
re.IGNORECASE)
# Find a prefix in the surname
self._sn_prefix_re = re.compile("^\s*(%s)\s+(.+)" % '|'.join(self.prefix_list),
re.IGNORECASE)
# Find a connector in the surname
self._sn_con_re = re.compile("^\s*(.+)\s+(%s)\s+(.+)" % '|'.join(self.connector_list),
re.IGNORECASE)
winprefix.destroy()
self.cb = callback
self.title_list = []
self.nick_list = []
self.prefix1_list = []
self.prefix2_list = []
self.handle_to_action = {}
self.progress = ProgressMeter(
_('Extracting Information from Names'), '')
@@ -127,6 +177,18 @@ class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
name = person.get_primary_name()
first = name.get_first_name()
sname = name.get_surname()
old_prefix = []
old_surn = []
old_con = []
old_prim = []
old_orig = []
for surn in name.get_surname_list():
old_prefix.append(surn.get_prefix())
old_surn.append(surn.get_surname())
old_con.append(surn.get_connector())
old_prim.append(surn.get_primary())
old_orig.append(surn.get_origintype())
if name.get_title():
old_title = [name.get_title()]
@@ -140,46 +202,160 @@ class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
first = groups[1]
new_title.append(groups[0])
match = _title_re.match(first)
matchnick = _nick_re.match(first)
if new_title:
self.title_list.append((key, " ".join(old_title+new_title),
first))
continue
match = _nick_re.match(first)
if match:
groups = match.groups()
self.nick_list.append((key, groups[0], groups[1]))
continue
old_prefix = name.get_surname_prefix()
# First try to find the name prefix in the first_name
match = _fn_prefix_re.match(first)
if match:
groups = match.groups()
if old_prefix:
# Put the found prefix before the old prefix
new_prefix = " ".join([groups[1], old_prefix])
titleval = (" ".join(old_title+new_title), first)
if key in self.handle_to_action:
self.handle_to_action[key][self.titleid] = titleval
else:
new_prefix = groups[1]
self.prefix1_list.append((key, groups[0], new_prefix))
continue
# Next, try to find the name prefix in the surname
match = _sn_prefix_re.match(sname)
if match:
groups = match.groups()
if old_prefix:
# Put the found prefix after the old prefix
new_prefix = " ".join([old_prefix, groups[0]])
self.handle_to_action[key] = {self.titleid: titleval}
elif matchnick:
# we check for nick, which changes given name like title
groups = matchnick.groups()
nickval = (groups[0], groups[1])
if key in self.handle_to_action:
self.handle_to_action[key][self.nickid] = nickval
else:
new_prefix = groups[0]
self.prefix2_list.append((key, groups[1], new_prefix))
self.handle_to_action[key] = {self.nickid: nickval}
else:
# Try to find the name prefix in the given name, also this
# changes given name
match = self._fn_prefix_re.match(first)
if match:
groups = match.groups()
if old_prefix[0]:
# Put the found prefix before the old prefix
new_prefix = " ".join([groups[1], old_prefix[0]])
else:
new_prefix = groups[1]
pref1val = (groups[0], new_prefix, groups[1])
if key in self.handle_to_action:
self.handle_to_action[key][self.pref1id] = pref1val
else:
self.handle_to_action[key] = {self.pref1id: pref1val}
#check for Gedcom import of compound surnames
if len(old_surn) == 1 and old_con[0] == '':
prefixes = old_prefix[0].split(',')
surnames = old_surn[0].split(',')
if len(prefixes) > 1 and len(prefixes) == len(surnames):
#assume a list of prefix and a list of surnames
prefixes = map(strip, prefixes)
surnames = map(strip, surnames)
primaries = [False] * len(prefixes)
primaries[0] = True
origs = []
for ind in range(len(prefixes)):
origs.append(gen.lib.NameOriginType())
origs[0] = old_orig[0]
compoundval = (surnames, prefixes, ['']*len(prefixes),
primaries, origs)
if key in self.handle_to_action:
self.handle_to_action[key][self.compid] = compoundval
else:
self.handle_to_action[key] = {self.compid: compoundval}
#we cannot check compound surnames, so continue the loop
continue
# Next, try to split surname in compounds: prefix surname connector
found = False
new_prefix_list = []
new_surname_list = []
new_connector_list = []
new_prim_list = []
new_orig_list = []
ind = 0
cont = True
for pref, surn, con, prim, orig in zip(old_prefix, old_surn,
old_con, old_prim, old_orig):
surnval = surn.split()
if surnval == []:
new_prefix_list.append(pref)
new_surname_list.append('')
new_connector_list.append(con)
new_prim_list.append(prim)
new_orig_list.append(orig)
cont = False
continue
val = surnval.pop(0)
while cont:
new_prefix_list.append(pref)
new_surname_list.append('')
new_connector_list.append(con)
new_prim_list.append(prim)
new_orig_list.append(orig)
while cont and (val.lower() in self.prefix_list):
found = True
if new_prefix_list[-1]:
new_prefix_list[-1] += ' ' + val
else:
new_prefix_list[-1] = val
try:
val = surnval.pop(0)
except IndexError:
val = ''
cont = False
#after prefix we have a surname
if cont:
new_surname_list[-1] = val
try:
val = surnval.pop(0)
except IndexError:
val = ''
cont = False
#if value after surname indicates continue, then continue
while cont and (val.lower() in self.connector_list_nonsplit):
#add this val to the current surname
new_surname_list[-1] += ' ' + val
try:
val = surnval.pop(0)
except IndexError:
val = ''
cont = False
# if previous is non-splitting connector, then add new val to
# current surname
if cont and (new_surname_list[-1].split()[-1].lower() \
in self.connector_list_nonsplit):
new_surname_list[-1] += ' ' + val
try:
val = surnval.pop(0)
except IndexError:
val = ''
cont = False
#if next is a connector, add it to the surname
if cont and val.lower() in self.connector_list:
found = True
if new_connector_list[-1]:
new_connector_list[-1] = ' ' + val
else:
new_connector_list[-1] = val
try:
val = surnval.pop(0)
except IndexError:
val = ''
cont = False
#initialize for a next surname in case there are still
#val
if cont:
found = True # we split surname
pref=''
con = ''
prim = False
orig = gen.lib.NameOriginType()
ind += 1
if found:
compoundval = (new_surname_list, new_prefix_list,
new_connector_list, new_prim_list, new_orig_list)
if key in self.handle_to_action:
self.handle_to_action[key][self.compid] = compoundval
else:
self.handle_to_action[key] = {self.compid: compoundval}
self.progress.step()
if self.nick_list or self.title_list or self.prefix1_list or self.prefix2_list:
if self.handle_to_action:
self.display()
else:
self.progress.close()
@@ -228,7 +404,7 @@ class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
c = gtk.TreeViewColumn(_('Value'), gtk.CellRendererText(), text=3)
self.list.append_column(c)
c = gtk.TreeViewColumn(_('Name'), gtk.CellRendererText(), text=4)
c = gtk.TreeViewColumn(_('Current Name'), gtk.CellRendererText(), text=4)
self.list.append_column(c)
self.list.set_model(self.model)
@@ -236,58 +412,65 @@ class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
self.nick_hash = {}
self.title_hash = {}
self.prefix1_hash = {}
self.prefix2_hash = {}
self.compound_hash = {}
self.progress.set_pass(_('Building display'),
len(self.nick_list)+len(self.title_list)
+len(self.prefix1_list)+len(self.prefix2_list))
len(self.handle_to_action.keys()))
for (pid, name, nick) in self.nick_list:
p = self.db.get_person_from_handle(pid)
for key, data in self.handle_to_action.items():
p = self.db.get_person_from_handle(key)
gid = p.get_gramps_id()
handle = self.model.append()
self.model.set_value(handle, 0, 1)
self.model.set_value(handle, 1, gid)
self.model.set_value(handle, 2, _('Nickname'))
self.model.set_value(handle, 3, nick)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.nick_hash[pid] = handle
self.progress.step()
for (pid, title, name) in self.title_list:
p = self.db.get_person_from_handle(pid)
gid = p.get_gramps_id()
handle = self.model.append()
self.model.set_value(handle, 0, 1)
self.model.set_value(handle, 1, gid)
self.model.set_value(handle, 2, _('Person|Title'))
self.model.set_value(handle, 3, title)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.title_hash[pid] = handle
self.progress.step()
for (pid, fname, prefix) in self.prefix1_list:
p = self.db.get_person_from_handle(pid)
gid = p.get_gramps_id()
handle = self.model.append()
self.model.set_value(handle, 0, 1)
self.model.set_value(handle, 1, gid)
self.model.set_value(handle, 2, _('Prefix'))
self.model.set_value(handle, 3, prefix)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.prefix1_hash[pid] = handle
self.progress.step()
for (pid, sname, prefix) in self.prefix2_list:
p = self.db.get_person_from_handle(pid)
gid = p.get_gramps_id()
handle = self.model.append()
self.model.set_value(handle, 0, 1)
self.model.set_value(handle, 1, gid)
self.model.set_value(handle, 2, _('Prefix'))
self.model.set_value(handle, 3, prefix)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.prefix2_hash[pid] = handle
if self.nickid in data:
given, nick = data[self.nickid]
handle = self.model.append()
self.model.set_value(handle, 0, 1)
self.model.set_value(handle, 1, gid)
self.model.set_value(handle, 2, _('Nickname'))
self.model.set_value(handle, 3, nick)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.nick_hash[key] = handle
if self.titleid in data:
title, given = data[self.titleid]
handle = self.model.append()
self.model.set_value(handle, 0, 1)
self.model.set_value(handle, 1, gid)
self.model.set_value(handle, 2, _('Person|Title'))
self.model.set_value(handle, 3, title)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.title_hash[key] = handle
if self.pref1id in data:
given, prefixtotal, new_prefix = data[self.pref1id]
handle = self.model.append()
self.model.set_value(handle, 0, 1)
self.model.set_value(handle, 1, gid)
self.model.set_value(handle, 2, _('Prefix in given name'))
self.model.set_value(handle, 3, prefixtotal)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.prefix1_hash[key] = handle
if self.compid in data:
surn_list, pref_list, con_list, prims, origs = data[self.compid]
handle = self.model.append()
self.model.set_value(handle, 0, 1)
self.model.set_value(handle, 1, gid)
self.model.set_value(handle, 2, _('Compound surname'))
newval = ''
for sur, pre, con in zip(surn_list, pref_list, con_list):
if newval:
newval += '-['
else:
newval = '['
newval += pre + ',' + sur
if con:
newval += ',' + con + ']'
else:
newval += ']'
self.model.set_value(handle, 3, newval)
self.model.set_value(handle, 4, p.get_primary_name().get_name())
self.compound_hash[key] = handle
self.progress.step()
self.progress.close()
@@ -300,49 +483,58 @@ class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
def on_ok_clicked(self, obj):
trans = self.db.transaction_begin("", batch=True)
self.db.disable_signals()
for grp in self.nick_list:
handle = self.nick_hash[grp[0]]
val = self.model.get_value(handle, 0)
if val:
p = self.db.get_person_from_handle(grp[0])
name = p.get_primary_name()
name.set_first_name(grp[1].strip())
nick_name = grp[2].strip()
attr = gen.lib.Attribute()
attr.set_type(gen.lib.AttributeType.NICKNAME)
attr.set_value(nick_name)
p.add_attribute(attr)
self.db.commit_person(p, trans)
for grp in self.title_list:
handle = self.title_hash[grp[0]]
val = self.model.get_value(handle, 0)
if val:
p = self.db.get_person_from_handle(grp[0])
name = p.get_primary_name()
name.set_first_name(grp[2].strip())
name.set_title(grp[1].strip())
self.db.commit_person(p, trans)
for grp in self.prefix1_list:
handle = self.prefix1_hash[grp[0]]
val = self.model.get_value(handle, 0)
if val:
p = self.db.get_person_from_handle(grp[0])
name = p.get_primary_name()
name.set_first_name(grp[1].strip())
name.set_surname_prefix(grp[2].strip())
self.db.commit_person(p, trans)
for grp in self.prefix2_list:
handle = self.prefix2_hash[grp[0]]
val = self.model.get_value(handle, 0)
if val:
p = self.db.get_person_from_handle(grp[0])
name = p.get_primary_name()
name.set_surname(grp[1].strip())
name.set_surname_prefix(grp[2].strip())
self.db.commit_person(p, trans)
for key, data in self.handle_to_action.items():
p = self.db.get_person_from_handle(key)
if self.nickid in data:
modelhandle = self.nick_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
given, nick = data[self.nickid]
name = p.get_primary_name()
name.set_first_name(given.strip())
name.set_nick_name(nick.strip())
if self.titleid in data:
modelhandle = self.title_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
title, given = data[self.titleid]
name = p.get_primary_name()
name.set_first_name(given.strip())
name.set_title(title.strip())
if self.pref1id in data:
modelhandle = self.prefix1_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
given, prefixtotal, prefix = data[self.pref1id]
name = p.get_primary_name()
name.set_first_name(given.strip())
oldpref = name.get_surname_list()[0].get_prefix().strip()
if oldpref == '' or oldpref == prefix.strip():
name.get_surname_list()[0].set_prefix(prefix)
else:
name.get_surname_list()[0].set_prefix('%s %s' % (prefix, oldpref))
if self.compid in data:
modelhandle = self.compound_hash[key]
val = self.model.get_value(modelhandle, 0)
if val:
surns, prefs, cons, prims, origs = data[self.compid]
name = p.get_primary_name()
new_surn_list = []
for surn, pref, con, prim, orig in zip(surns, prefs, cons,
prims, origs):
new_surn_list.append(gen.lib.Surname())
new_surn_list[-1].set_surname(surn.strip())
new_surn_list[-1].set_prefix(pref.strip())
new_surn_list[-1].set_connector(con.strip())
new_surn_list[-1].set_primary(prim)
new_surn_list[-1].set_origintype(orig)
name.set_surname_list(new_surn_list)
self.db.commit_person(p, trans)
self.db.transaction_commit(trans,
_("Extract information from names"))
@@ -351,7 +543,6 @@ class PatchNames(tool.BatchTool, ManagedWindow.ManagedWindow):
self.close()
self.cb()
class PatchNamesOptions(tool.ToolOptions):
"""
Defines options and provides handling interface.
@@ -359,3 +550,7 @@ class PatchNamesOptions(tool.ToolOptions):
def __init__(self, name, person_id=None):
tool.ToolOptions.__init__(self, name, person_id)
def strip(arg):
return arg.strip()
+11 -5
View File
@@ -12,12 +12,10 @@
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="title">
<property name="visible">True</property>
@@ -32,10 +30,18 @@
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="ypad">10</property>
<property name="label" translatable="yes">Below is a list of the nicknames, titles and family name prefixes that Gramps can extract from the
current database. If you accept the changes, Gramps will modify the entries
that have been selected.</property>
<property name="label" translatable="yes">Below is a list of the nicknames, titles, prefixes and compound surnames that Gramps can extract from the family tree.
If you accept the changes, Gramps will modify the entries that have been selected.
Compound surnames are shown as lists of [prefix, surname, connector].
For example, with the defaults, the name "de Mascarenhas da Silva e Lencastre" shows as:
[de, Mascarenhas]-[da, Silva, e]-[,Lencastre]
Run this tool several times to correct names that have multiple information that can be extracted.</property>
<property name="wrap">True</property>
<property name="max_width_chars">100</property>
</object>
<packing>
<property name="expand">False</property>
+16 -6
View File
@@ -158,17 +158,27 @@ class PersonTreeView(BasePersonView):
# attempt to get the current surname
(model, pathlist) = self.selection.get_selected_rows()
name = u""
name = gen.lib.Name()
basepers = None
if len(pathlist) == 1:
path = pathlist[0]
if len(path) == 1:
name = model.on_get_iter(path).name
else:
node = model.on_get_iter(path)
name = model.on_iter_parent(node).name
path = (path[0], 0)
node = model.get_iter(path)
handle = model.get_value(node, self.handle_col)
basepers = self.dbstate.db.get_person_from_handle(handle)
if basepers:
surnlist = []
primname = basepers.get_primary_name()
for surn in primname.get_surname_list():
surnlist.append(gen.lib.Surname(source=surn))
name.set_surname_list(surnlist)
name.set_family_nick_name(primname.get_family_nick_name())
name.set_group_as(primname.get_group_as())
name.set_sort_as(primname.get_sort_as())
try:
person.get_primary_name().set_surname(name)
person.set_primary_name(name)
EditPerson(self.dbstate, self.uistate, [], person)
except Errors.WindowActiveError:
pass