Update Gramps XML Import/Export to support Citations

svn: r18086
This commit is contained in:
Nick Hall 2011-08-30 12:34:46 +00:00
parent 5a3cef062c
commit afef197a57
5 changed files with 306 additions and 194 deletions

View File

@ -5,7 +5,7 @@
#
# Copyright (C) 2001 Graham J. Williams
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2010 Nick Hall
# Copyright (C) 2010-2011 Nick Hall
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -25,15 +25,15 @@
-->
<!--
This is the Document Type Definition file for v1.4.0
This is the Document Type Definition file for v1.5.0
of the GRAMPS XML genealogy data format.
Please use the following formal public identifier to identify it:
"-//GRAMPS//DTD GRAMPS XML V1.4.0//EN"
"-//GRAMPS//DTD GRAMPS XML V1.5.0//EN"
For example:
<!DOCTYPE database PUBLIC "-//GRAMPS//DTD GRAMPS XML V1.4.0//EN"
"http://gramps-project.org/xml/1.4.0/grampsxml.dtd"
<!DOCTYPE database PUBLIC "-//GRAMPS//DTD GRAMPS XML V1.5.0//EN"
"http://gramps-project.org/xml/1.5.0/grampsxml.dtd"
[...]>
-->
@ -48,6 +48,7 @@ DATABASE
families
events
places
citations
sources
objects
repositories
@ -59,9 +60,9 @@ DATABASE
-->
<!ELEMENT database (header, name-formats?, tags?, events?, people?, families?,
sources?, places?, objects?, repositories?, notes?,
bookmarks?, namemaps?)>
<!ATTLIST database xmlns CDATA #FIXED "http://gramps-project.org/xml/1.4.0/">
citations?, sources?, places?, objects?, repositories?,
notes?, bookmarks?, namemaps?)>
<!ATTLIST database xmlns CDATA #FIXED "http://gramps-project.org/xml/1.5.0/">
<!-- ************************************************************
@ -105,12 +106,11 @@ PEOPLE
<!ELEMENT person (gender, name*, eventref*, lds_ord*,
objref*, address*, attribute*, url*, childof*,
parentin*, personref*, noteref*, sourceref*, tagref*)>
parentin*, personref*, noteref*, citationref*, tagref*)>
<!ATTLIST person
id CDATA #IMPLIED
handle ID #REQUIRED
priv (0|1) #IMPLIED
marker CDATA #IMPLIED
change CDATA #REQUIRED
>
@ -119,8 +119,9 @@ GENDER has values of M, F, or U.
-->
<!ELEMENT gender (#PCDATA)>
<!ELEMENT name (first?, call?, surname*, nick?, familynick?, suffix?, title?, group?
(daterange|datespan|dateval|datestr)?, noteref*, sourceref*)>
<!ELEMENT name (first?, call?, surname*, nick?, familynick?, suffix?, title?,
group?, (daterange|datespan|dateval|datestr)?, noteref*,
citationref*)>
<!ATTLIST name
alt (0|1) #IMPLIED
type CDATA #IMPLIED
@ -151,7 +152,7 @@ GENDER has values of M, F, or U.
<!ELEMENT parentin EMPTY>
<!ATTLIST parentin hlink IDREF #REQUIRED>
<!ELEMENT personref (sourceref*, noteref*)>
<!ELEMENT personref (citationref*, noteref*)>
<!ATTLIST personref
hlink IDREF #REQUIRED
priv (0|1) #IMPLIED
@ -160,7 +161,7 @@ GENDER has values of M, F, or U.
<!ELEMENT address ((daterange|datespan|dateval|datestr)?, street?, city?,
county?, state?, country?, postal?, phone?, noteref*,
sourceref*)>
citationref*)>
<!ATTLIST address priv (0|1) #IMPLIED>
<!ELEMENT street (#PCDATA)>
@ -180,12 +181,11 @@ FAMILY
<!ELEMENT families (family)*>
<!ELEMENT family (rel?, father?, mother?, eventref*, lds_ord*, objref*,
childref*, attribute*, noteref*, sourceref*, tagref*)>
childref*, attribute*, noteref*, citationref*, tagref*)>
<!ATTLIST family
id CDATA #IMPLIED
handle ID #REQUIRED
priv (0|1) #IMPLIED
marker CDATA #IMPLIED
change CDATA #REQUIRED
>
@ -195,7 +195,7 @@ FAMILY
<!ELEMENT mother EMPTY>
<!ATTLIST mother hlink IDREF #REQUIRED>
<!ELEMENT childref (sourceref*,noteref*)>
<!ELEMENT childref (citationref*,noteref*)>
<!ATTLIST childref
hlink IDREF #REQUIRED
priv (0|1) #IMPLIED
@ -214,12 +214,11 @@ EVENT
<!ELEMENT events (event)*>
<!ELEMENT event (type?, (daterange|datespan|dateval|datestr)?, place?, cause?,
description?, attribute*, noteref*, sourceref*, objref*)>
description?, attribute*, noteref*, citationref*, objref*)>
<!ATTLIST event
id CDATA #IMPLIED
handle ID #REQUIRED
priv (0|1) #IMPLIED
marker CDATA #IMPLIED
change CDATA #REQUIRED
>
@ -234,7 +233,6 @@ SOURCES
id CDATA #IMPLIED
handle ID #REQUIRED
priv (0|1) #IMPLIED
marker CDATA #IMPLIED
change CDATA #REQUIRED
>
<!ELEMENT stitle (#PCDATA)>
@ -249,12 +247,11 @@ PLACES
<!ELEMENT places (placeobj)*>
<!ELEMENT placeobj (ptitle?, coord?, location*, objref*, url*, noteref*,
sourceref*)>
citationref*)>
<!ATTLIST placeobj
id CDATA #IMPLIED
handle ID #REQUIRED
priv (0|1) #IMPLIED
marker CDATA #IMPLIED
change CDATA #REQUIRED
>
@ -285,12 +282,11 @@ OBJECTS
<!ELEMENT objects (object)*>
<!ELEMENT object (file, attribute*, noteref*,
(daterange|datespan|dateval|datestr)?, sourceref*, tagref*)>
(daterange|datespan|dateval|datestr)?, citationref*, tagref*)>
<!ATTLIST object
id CDATA #IMPLIED
handle ID #REQUIRED
priv (0|1) #IMPLIED
marker CDATA #IMPLIED
change CDATA #REQUIRED
>
@ -312,7 +308,6 @@ REPOSITORIES
id CDATA #IMPLIED
handle ID #REQUIRED
priv (0|1) #IMPLIED
marker CDATA #IMPLIED
change CDATA #REQUIRED
>
@ -329,7 +324,6 @@ NOTES
id CDATA #IMPLIED
handle ID #REQUIRED
priv (0|1) #IMPLIED
marker CDATA #IMPLIED
change CDATA #REQUIRED
format (0|1) #IMPLIED
type CDATA #REQUIRED
@ -365,6 +359,21 @@ TAGS
change CDATA #REQUIRED
>
<!-- ************************************************************
CITATIONS
-->
<!ELEMENT citations (citation)*>
<!ELEMENT citation ((daterange|datespan|dateval|datestr)?, page?, confidence?,
noteref*, objref*, data_item*, sourceref)>
<!ATTLIST citation
id CDATA #IMPLIED
handle ID #REQUIRED
priv (0|1) #IMPLIED
change CDATA #REQUIRED
>
<!-- ************************************************************
BOOKMARKS
-->
@ -436,11 +445,14 @@ SHARED ELEMENTS
<!ELEMENT datestr EMPTY>
<!ATTLIST datestr val CDATA #REQUIRED>
<!ELEMENT sourceref (spage? ,noteref*, (daterange|datespan|dateval|datestr)?)>
<!ELEMENT citationref EMPTY>
<!ATTLIST citationref
hlink IDREF #REQUIRED
>
<!ELEMENT sourceref EMPTY>
<!ATTLIST sourceref
hlink IDREF #REQUIRED
priv (0|1) #IMPLIED
conf CDATA #IMPLIED
>
<!ELEMENT eventref (attribute*, noteref*)>
@ -468,9 +480,10 @@ SHARED ELEMENTS
hlink IDREF #REQUIRED
>
<!ELEMENT spage (#PCDATA)>
<!ELEMENT page (#PCDATA)>
<!ELEMENT confidence (#PCDATA)>
<!ELEMENT attribute (sourceref*, noteref*)>
<!ELEMENT attribute (citationref*, noteref*)>
<!ATTLIST attribute
priv (0|1) #IMPLIED
type CDATA #REQUIRED
@ -491,7 +504,7 @@ SHARED ELEMENTS
description CDATA #IMPLIED
>
<!ELEMENT objref (region?, attribute*, sourceref*, noteref*)>
<!ELEMENT objref (region?, attribute*, citationref*, noteref*)>
<!ATTLIST objref
hlink IDREF #REQUIRED
priv (0|1) #IMPLIED
@ -512,7 +525,7 @@ SHARED ELEMENTS
>
<!ELEMENT lds_ord ((daterange|datespan|dateval|datestr)?, temple?, place?,
status?, sealed_to?, noteref*, sourceref*)>
status?, sealed_to?, noteref*, citationref*)>
<!ATTLIST lds_ord
priv (0|1) #IMPLIED
type CDATA #REQUIRED

View File

@ -4,7 +4,7 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2005-2007 Donald N. Allingham
# Copyright (C) 2010 Nick Hall
# Copyright (C) 2010-2011 Nick Hall
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -32,7 +32,7 @@
<grammar
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
ns="http://gramps-project.org/xml/1.4.0/"
ns="http://gramps-project.org/xml/1.5.0/"
xmlns="http://relaxng.org/ns/structure/1.0">
<start><element name="database">
@ -82,6 +82,12 @@
</element></zeroOrMore>
</element></optional>
<optional><element name="citations">
<zeroOrMore><element name="citation">
<ref name="citation-content"/>
</element></zeroOrMore>
</element></optional>
<optional><element name="sources">
<zeroOrMore><element name="source">
<ref name="source-content"/>
@ -148,7 +154,6 @@
<value>0</value>
<value>1</value>
</choice></attribute></optional>
<optional><attribute name="marker"><text/></attribute></optional>
</define>
<define name="person-content">
@ -195,8 +200,8 @@
<zeroOrMore><element name="noteref">
<ref name="noteref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="tagref">
<ref name="tagref-content"/>
@ -234,20 +239,20 @@
<optional><attribute name="display"><text/></attribute></optional>
<optional><element name="first"><text/></element></optional>
<optional><element name="call"><text/></element></optional>
<zeroOrMore>
<ref name="surname-content"/>
</zeroOrMore>
<optional><element name="suffix"><text/></element></optional>
<optional><element name="title"><text/></element></optional>
<optional><element name="nick"><text/></element></optional>
<optional><element name="familynick"><text/></element></optional>
<optional><element name="group"><text/></element></optional>
<zeroOrMore><element name="surname">
<ref name="surname-content"/>
</element></zeroOrMore>
<optional><element name="suffix"><text/></element></optional>
<optional><element name="title"><text/></element></optional>
<optional><ref name="date-content"/></optional>
<zeroOrMore><element name="noteref">
<ref name="noteref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
</define>
@ -284,8 +289,8 @@
<zeroOrMore><element name="noteref">
<ref name="noteref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
</define>
@ -379,8 +384,8 @@
<ref name="noteref-content"/>
</element></zeroOrMore>
<optional><ref name="date-content"/></optional>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="tagref">
<ref name="tagref-content"/>
@ -401,14 +406,34 @@
<zeroOrMore><element name="noteref">
<ref name="noteref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="objref">
<ref name="objref-content"/>
</element></zeroOrMore>
</define>
<define name="citation-content">
<ref name="primary-object"/>
<optional><ref name="date-content"/></optional>
<optional><element name="page"><text/></element></optional>
<optional><element name="confidence"><text/></element></optional>
<zeroOrMore><element name="noteref">
<ref name="noteref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="objref">
<ref name="objref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="data_item">
<attribute name="key"><text/></attribute>
<attribute name="value"><text/></attribute>
</element></zeroOrMore>
<element name="sourceref">
<ref name="sourceref-content"/>
</element>
</define>
<define name="source-content">
<ref name="primary-object"/>
<optional><element name="stitle"><text/></element></optional>
@ -456,8 +481,8 @@
<zeroOrMore><element name="noteref">
<ref name="noteref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
</define>
@ -475,8 +500,8 @@
<ref name="noteref-content"/>
</element></zeroOrMore>
<optional><ref name="date-content"/></optional>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="tagref">
<ref name="tagref-content"/>
@ -564,17 +589,12 @@
</element></zeroOrMore>
</define>
<define name="citationref-content">
<attribute name="hlink"><data type="IDREF"/></attribute>
</define>
<define name="sourceref-content">
<attribute name="hlink"><data type="IDREF"/></attribute>
<optional><attribute name="priv">
<ref name="priv-content"/>
</attribute></optional>
<optional><attribute name="conf"><text/></attribute></optional>
<optional><element name="spage"><text/></element></optional>
<zeroOrMore><element name="noteref">
<ref name="noteref-content"/>
</element></zeroOrMore>
<optional><ref name="date-content"/></optional>
</define>
<define name="eventref-content">
@ -620,8 +640,8 @@
</attribute></optional>
<attribute name="type"><text/></attribute>
<attribute name="value"><text/></attribute>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="noteref">
<ref name="noteref-content"/>
@ -648,8 +668,8 @@
<zeroOrMore><element name="attribute">
<ref name="attribute-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="noteref">
<ref name="noteref-content"/>
@ -678,8 +698,8 @@
<ref name="noteref-content"/>
</element></zeroOrMore>
<optional><ref name="date-content"/></optional>
<zeroOrMore><element name="sourceref">
<ref name="sourceref-content"/>
<zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore>
</define>

View File

@ -7,7 +7,7 @@
# Copyright (C) 2008 Robert Cheramy <robert@cheramy.net>
# Copyright (C) 2009 Douglas S. Blank
# Copyright (C) 2010 Jakim Friant
# Copyright (C) 2010 Nick Hall
# Copyright (C) 2010-2011 Nick Hall
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -200,6 +200,7 @@ class GrampsXmlWriter(UpdateCallback):
person_len = self.db.get_number_of_people()
family_len = self.db.get_number_of_families()
event_len = self.db.get_number_of_events()
citation_len = self.db.get_number_of_citations()
source_len = self.db.get_number_of_sources()
place_len = self.db.get_number_of_places()
repo_len = self.db.get_number_of_repositories()
@ -207,8 +208,9 @@ class GrampsXmlWriter(UpdateCallback):
note_len = self.db.get_number_of_notes()
tag_len = self.db.get_number_of_tags()
total_steps = (person_len + family_len + event_len + source_len +
place_len + repo_len + obj_len + note_len + tag_len
total_steps = (person_len + family_len + event_len + citation_len +
source_len + place_len + repo_len + obj_len + note_len +
tag_len
)
self.set_total(total_steps)
@ -282,11 +284,20 @@ class GrampsXmlWriter(UpdateCallback):
self.update()
self.g.write(" </families>\n")
if citation_len > 0:
self.g.write(" <citations>\n")
for handle in self.db.get_citation_handles():
citation = self.db.get_citation_from_handle(handle)
self.write_citation(citation,2)
self.update()
self.g.write(" </citations>\n")
if source_len > 0:
self.g.write(" <sources>\n")
for handle in self.db.get_source_handles():
source = self.db.get_source_from_handle(handle)
self.write_source(source,2)
self.update()
self.g.write(" </sources>\n")
if place_len > 0:
@ -522,8 +533,8 @@ class GrampsXmlWriter(UpdateCallback):
self.write_note_list(person.get_note_list(),index+1)
for s in person.get_source_references():
self.dump_source_ref(s,index+2)
for citation_handle in person.get_citation_references():
self.write_ref("citationref", citation_handle, index+2)
for tag_handle in person.get_tag_list():
self.write_ref("tagref", tag_handle, index+1)
@ -550,14 +561,26 @@ class GrampsXmlWriter(UpdateCallback):
self.dump_child_ref(child_ref,index+1)
self.write_attribute_list(family.get_attribute_list())
self.write_note_list(family.get_note_list(),index+1)
for s in family.get_source_references():
self.dump_source_ref(s,index+1)
for citation_handle in family.get_citation_references():
self.write_ref("citationref", citation_handle, index+1)
for tag_handle in family.get_tag_list():
self.write_ref("tagref", tag_handle, index+1)
self.g.write("%s</family>\n" % sp)
def write_citation(self, citation, index=1):
sp = " " * index
self.write_primary_tag("citation", citation, index)
self.write_date(citation.get_date_object(), index+1)
self.write_line("page", citation.get_page(), index+1)
self.write_line("confidence", citation.get_confidence_level(), index+1)
self.write_note_list(citation.get_note_list(), index+1)
self.write_media_list(citation.get_media_list(), index+1)
self.write_data_map(citation.get_data_map())
self.write_ref("sourceref", citation.get_reference_handle(), index+1)
self.g.write("%s</citation>\n" % sp)
def write_source(self,source,index=1):
sp = " "*index
self.write_primary_tag("source",source,index)
@ -602,8 +625,8 @@ class GrampsXmlWriter(UpdateCallback):
self.write_line("postal",address.get_postal_code(),index+1)
self.write_line("phone",address.get_phone(),index+1)
self.write_note_list(address.get_note_list(),index+1)
for s in address.get_source_references():
self.dump_source_ref(s,index+2)
for citation_handle in address.get_citation_references():
self.write_ref("citationref", citation_handle, index+1)
self.g.write('%s</address>\n' % sp)
def dump_person_ref(self,personref,index=1):
@ -613,16 +636,17 @@ class GrampsXmlWriter(UpdateCallback):
priv_text = conf_priv(personref)
rel_text = ' rel="%s"' % escxml(personref.get_relation())
sreflist = personref.get_source_references()
citation_list = personref.get_citation_references()
nreflist = personref.get_note_list()
if (len(sreflist) + len(nreflist) == 0):
if (len(citation_list) + len(nreflist) == 0):
self.write_ref('personref',personref.ref,index,close=True,
extra_text=priv_text+rel_text)
else:
self.write_ref('personref',personref.ref,index,close=False,
extra_text=priv_text+rel_text)
for sref in sreflist:
self.dump_source_ref(sref,index+1)
for citation_handle in citation_list:
self.write_ref("citationref", citation_handle, index+1)
self.write_note_list(nreflist,index+1)
self.g.write('%s</personref>\n' % sp)
@ -639,16 +663,16 @@ class GrampsXmlWriter(UpdateCallback):
mrel_text = ''
else:
mrel_text = ' mrel="%s"' % escxml(childref.mrel.xml_str())
sreflist = childref.get_source_references()
citation_list = childref.get_citation_references()
nreflist = childref.get_note_list()
if (len(sreflist)+len(nreflist) == 0):
if (len(citation_list)+len(nreflist) == 0):
self.write_ref('childref',childref.ref,index,close=True,
extra_text=priv_text+mrel_text+frel_text)
else:
self.write_ref('childref',childref.ref,index,close=False,
extra_text=priv_text+mrel_text+frel_text)
for sref in sreflist:
self.dump_source_ref(sref,index+1)
for citation_handle in citation_list:
self.write_ref("citationref", citation_handle, index+1)
self.write_note_list(nreflist,index+1)
self.g.write('%s</childref>\n' % sp)
@ -690,8 +714,8 @@ class GrampsXmlWriter(UpdateCallback):
self.write_attribute_list(event.get_attribute_list(),index+1)
self.write_note_list(event.get_note_list(),index+1)
for s in event.get_source_references():
self.dump_source_ref(s,index+1)
for citation_handle in event.get_citation_references():
self.write_ref("citationref", citation_handle, index+1)
self.write_media_list(event.get_media_list(),index+1)
self.g.write("%s</event>\n" % sp)
@ -717,40 +741,10 @@ class GrampsXmlWriter(UpdateCallback):
self.g.write('%s<sealed_to hlink="%s"/>\n' %
(sp2,"_"+ord.get_family_handle()))
self.write_note_list(ord.get_note_list(),index+1)
for s in ord.get_source_references():
self.dump_source_ref(s,index+1)
for citation_handle in ord.get_citation_references():
self.write_ref("citationref", citation_handle, index+1)
self.g.write('%s</lds_ord>\n' % sp)
def dump_source_ref(self,source_ref,index=1):
source = self.db.get_source_from_handle(
source_ref.get_reference_handle())
if source:
p = source_ref.get_page()
n = source_ref.get_note_list()
d = source_ref.get_date_object()
q = source_ref.get_confidence_level()
self.g.write(" " * index)
priv = conf_priv(source_ref)
if p == "" and n == [] and d.is_empty() and q == 2:
self.g.write('<sourceref hlink="%s"%s/>\n'
% ("_"+source.get_handle(), priv)
)
else:
if q == 2:
self.g.write('<sourceref hlink="%s"%s>\n'
% ("_"+source.get_handle(), priv)
)
else:
self.g.write('<sourceref hlink="%s" conf="%d"%s>\n'
% ("_"+source.get_handle(), q, priv)
)
self.write_line("spage",p,index+1)
self.write_note_list(n,index+1)
self.write_date(d,index+1)
self.g.write("%s</sourceref>\n" % (" " * index))
def write_ref(self,tagname, handle,index=1,close=True,extra_text=''):
if handle:
if close:
@ -956,8 +950,8 @@ class GrampsXmlWriter(UpdateCallback):
if name.date:
self.write_date(name.date,4)
self.write_note_list(name.get_note_list(),index+1)
for s in name.get_source_references():
self.dump_source_ref(s,index+1)
for citation_handle in name.get_citation_references():
self.write_ref("citationref", citation_handle, index+1)
self.g.write('%s</name>\n' % sp)
@ -1037,14 +1031,14 @@ class GrampsXmlWriter(UpdateCallback):
(sp,conf_priv(attr),escxml(attr.get_type().xml_str()),
self.fix(attr.get_value()))
)
slist = attr.get_source_references()
citation_list = attr.get_citation_references()
nlist = attr.get_note_list()
if (len(nlist)+len(slist)) == 0:
if (len(nlist)+len(citation_list)) == 0:
self.g.write('/>\n')
else:
self.g.write('>\n')
for s in attr.get_source_references():
self.dump_source_ref(s,indent+1)
for citation_handle in citation_list:
self.write_ref("citationref", citation_handle, indent+1)
self.write_note_list(attr.get_note_list(),indent+1)
self.g.write('%s</attribute>\n' % sp)
@ -1056,7 +1050,7 @@ class GrampsXmlWriter(UpdateCallback):
if photo.get_privacy():
self.g.write(' priv="1"')
proplist = photo.get_attribute_list()
refslist = photo.get_source_references()
citation_list = photo.get_citation_references()
nreflist = photo.get_note_list()
rect = photo.get_rectangle()
if rect is not None :
@ -1073,7 +1067,7 @@ class GrampsXmlWriter(UpdateCallback):
corner1_x == corner1_y == 0 and
corner2_x == corner2_y == 100):
rect = None
if (len(proplist) + len(nreflist) + len(refslist) == 0 and
if (len(proplist) + len(nreflist) + len(citation_list) == 0 and
rect is None):
self.g.write("/>\n")
else:
@ -1089,8 +1083,8 @@ class GrampsXmlWriter(UpdateCallback):
)
)
self.write_attribute_list(proplist,indent+1)
for ref in refslist:
self.dump_source_ref(ref, indent+1)
for citation_handle in citation_list:
self.write_ref("citationref", citation_handle, indent+1)
self.write_note_list(nreflist, indent+1)
self.g.write('%s</objref>\n' % sp)
@ -1169,7 +1163,7 @@ class GrampsXmlWriter(UpdateCallback):
llen = (len(place.get_alternate_locations()) +
len(place.get_url_list()) +
len(place.get_media_list()) +
len(place.get_source_references())
len(place.get_citation_references())
)
ml_empty = main_loc.is_empty()
@ -1186,8 +1180,8 @@ class GrampsXmlWriter(UpdateCallback):
self.write_media_list(place.get_media_list(), index+1)
self.write_url_list(place.get_url_list())
self.write_note_list(place.get_note_list(), index+1)
for s in place.get_source_references():
self.dump_source_ref(s, index+1)
for citation_handle in place.get_citation_references():
self.write_ref("citationref", citation_handle, index+1)
self.g.write("%s</placeobj>\n" % (" "*index))
def write_object(self, obj, index=1):
@ -1216,8 +1210,8 @@ class GrampsXmlWriter(UpdateCallback):
dval = obj.get_date_object()
if not dval.is_empty():
self.write_date(dval, index+1)
for s in obj.get_source_references():
self.dump_source_ref(s, index+1)
for citation_handle in obj.get_citation_references():
self.write_ref("citationref", citation_handle, index+1)
for tag_handle in obj.get_tag_list():
self.write_ref("tagref", tag_handle, index+1)

View File

@ -3,7 +3,7 @@
#
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2009 Douglas S. Blank
# Copyright (C) 2010 Nick Hall
# Copyright (C) 2010-2011 Nick Hall
# Copyright (C) 2011 Michiel D. Nauta
#
# This program is free software; you can redistribute it and/or modify
@ -52,7 +52,7 @@ import DateHandler
from gen.display.name import displayer as name_displayer
from gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY,
MEDIA_KEY, PLACE_KEY, REPOSITORY_KEY, NOTE_KEY,
TAG_KEY)
TAG_KEY, CITATION_KEY)
from gen.updatecallback import UpdateCallback
import const
import libgrampsxml
@ -190,7 +190,7 @@ class ImportInfo(object):
Class object that can hold information about the import
"""
keyorder = [PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY, MEDIA_KEY,
PLACE_KEY, REPOSITORY_KEY, NOTE_KEY, TAG_KEY]
PLACE_KEY, REPOSITORY_KEY, NOTE_KEY, TAG_KEY, CITATION_KEY]
key2data = {
PERSON_KEY : 0,
FAMILY_KEY : 1,
@ -200,7 +200,8 @@ class ImportInfo(object):
PLACE_KEY: 5,
REPOSITORY_KEY: 6,
NOTE_KEY: 7,
TAG_KEY: 8
TAG_KEY: 8,
CITATION_KEY: 9
}
def __init__(self):
@ -209,8 +210,8 @@ class ImportInfo(object):
This creates the datastructures to hold info
"""
self.data_mergecandidate = [{}, {}, {}, {}, {}, {}, {}, {}, {}]
self.data_newobject = [0] * 9
self.data_mergecandidate = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
self.data_newobject = [0] * 10
self.data_relpath = False
def add(self, category, key, obj, sec_obj=None):
@ -260,6 +261,9 @@ class ImportInfo(object):
'id': obj.gramps_id, 'id2': sec_obj.gramps_id}
elif key == TAG_KEY:
pass # Tags can't be merged
elif key == CITATION_KEY:
return _(" Citation %(id)s with %(id2)s\n") % {
'id': obj.gramps_id, 'id2': sec_obj.gramps_id}
def info_text(self):
"""
@ -275,6 +279,7 @@ class ImportInfo(object):
REPOSITORY_KEY : _(' Repositories: %d\n'),
NOTE_KEY : _(' Notes: %d\n'),
TAG_KEY : _(' Tags: %d\n'),
CITATION_KEY : _(' Citations: %d\n'),
}
txt = _("Number of new objects imported:\n")
for key in self.keyorder:
@ -453,8 +458,9 @@ class GrampsParser(UpdateCallback):
self.person = None
self.family = None
self.address = None
self.citation = None
self.in_old_sourceref = False
self.source = None
self.source_ref = None
self.attribute = None
self.placeobj = None
self.locations = 0
@ -500,6 +506,7 @@ class GrampsParser(UpdateCallback):
self.idswap = {}
self.fidswap = {}
self.eidswap = {}
self.cidswap = {}
self.sidswap = {}
self.pidswap = {}
self.oidswap = {}
@ -540,10 +547,14 @@ class GrampsParser(UpdateCallback):
"childof": (self.start_childof, None),
"childref": (self.start_childref, self.stop_childref),
"personref": (self.start_personref, self.stop_personref),
"citation": (self.start_citation, self.stop_citation),
"citationref": (self.start_citationref, None),
"citations": (None, None),
"city": (None, self.stop_city),
"county": (None, self.stop_county),
"country": (None, self.stop_country),
"comment": (None, self.stop_comment),
"confidence": (None, self.stop_confidence),
"created": (self.start_created, None),
"ref": (None, self.stop_ref),
"database": (self.start_database, self.stop_database),
@ -576,6 +587,7 @@ class GrampsParser(UpdateCallback):
"objref": (self.start_objref, self.stop_objref),
"object": (self.start_object, self.stop_object),
"file": (self.start_file, None),
"page": (None, self.stop_page),
"place": (self.start_place, self.stop_place),
"dateval": (self.start_dateval, None),
"daterange": (self.start_daterange, None),
@ -1698,9 +1710,9 @@ class GrampsParser(UpdateCallback):
self.note.format = int(attrs.get('format', gen.lib.Note.FLOWED))
# The order in this long if-then statement should reflect the
# DTD: most deeply nested elements come first.
if self.source_ref:
self.note.type.set(gen.lib.NoteType.SOURCEREF)
self.note.private = self.source_ref.private
if self.citation:
self.note.type.set(gen.lib.NoteType.CITATION)
self.note.private = self.citation.private
elif self.address:
self.note.type.set(gen.lib.NoteType.ADDRESS)
self.note.private = self.address.private
@ -1774,8 +1786,8 @@ class GrampsParser(UpdateCallback):
# The order in this long if-then statement should reflect the
# DTD: most deeply nested elements come first.
if self.source_ref:
self.source_ref.add_note(handle)
if self.citation:
self.citation.add_note(handle)
elif self.address:
self.address.add_note(handle)
elif self.ord:
@ -1811,11 +1823,79 @@ class GrampsParser(UpdateCallback):
elif self.repo:
self.repo.add_note(handle)
def __add_citation(self, citation_handle):
"""
Add a citation to the object currently processed.
"""
if self.photo:
self.photo.add_citation(citation_handle)
elif self.ord:
self.ord.add_citation(citation_handle)
elif self.attribute:
self.attribute.add_citation(citation_handle)
elif self.object:
self.object.add_citation(citation_handle)
elif self.objref:
self.objref.add_citation(citation_handle)
elif self.event:
self.event.add_citation(citation_handle)
elif self.address:
self.address.add_citation(citation_handle)
elif self.name:
self.name.add_citation(citation_handle)
elif self.placeobj:
self.placeobj.add_citation(citation_handle)
elif self.childref:
self.childref.add_citation(citation_handle)
elif self.family:
self.family.add_citation(citation_handle)
elif self.personref:
self.personref.add_citation(citation_handle)
elif self.person:
self.person.add_citation(citation_handle)
def start_citationref(self, attrs):
"""
Add a citation reference to the object currently processed.
"""
handle = self.inaugurate(attrs['hlink'], gen.lib.Citation,
self.db.has_citation_handle,
self.db.add_citation,
self.db.get_raw_citation_data)
self.__add_citation(handle)
def start_citation(self, attrs):
"""
Add a citation object to db if it doesn't exist yet and assign
id, privacy and changetime.
"""
self.update(self.p.CurrentLineNumber)
self.citation = gen.lib.Citation()
orig_handle = attrs['handle'].replace('_', '')
is_merge_candidate = (self.replace_import_handle and
self.db.has_citation_handle(orig_handle))
self.inaugurate(orig_handle, self.citation,
self.db.has_citation_handle,
self.db.add_citation,
self.db.get_raw_citation_data)
gramps_id = self.legalize_id(attrs.get('id'), CITATION_KEY,
self.cidswap, self.db.cid2user_format,
self.db.find_next_citation_gramps_id)
self.citation.set_gramps_id(gramps_id)
if is_merge_candidate:
orig_citation = self.db.get_citation_from_handle(orig_handle)
self.info.add('merge-candidate', CITATION_KEY, orig_citation,
self.citation)
self.citation.private = bool(attrs.get("priv"))
self.citation.change = int(attrs.get('change', self.change))
self.citation.confidence = self.conf # default
self.info.add('new-object', CITATION_KEY, self.citation)
def start_sourceref(self, attrs):
"""
Add a source reference to the object currently processed.
"""
self.source_ref = gen.lib.SourceRef()
if 'hlink' in attrs:
handle = self.inaugurate(attrs['hlink'], gen.lib.Source,
self.db.has_source_handle,
@ -1824,36 +1904,22 @@ class GrampsParser(UpdateCallback):
else:
handle = self.inaugurate_id(attrs.get('ref'), SOURCE_KEY,
gen.lib.Source)
self.source_ref.ref = handle
self.source_ref.confidence = int(attrs.get("conf", self.conf))
self.source_ref.private = bool(attrs.get("priv"))
if self.photo:
self.photo.add_source_reference(self.source_ref)
elif self.ord:
self.ord.add_source_reference(self.source_ref)
elif self.attribute:
self.attribute.add_source_reference(self.source_ref)
elif self.object:
self.object.add_source_reference(self.source_ref)
elif self.objref:
self.objref.add_source_reference(self.source_ref)
elif self.event:
self.event.add_source_reference(self.source_ref)
elif self.address:
self.address.add_source_reference(self.source_ref)
elif self.name:
self.name.add_source_reference(self.source_ref)
elif self.placeobj:
self.placeobj.add_source_reference(self.source_ref)
elif self.childref:
self.childref.add_source_reference(self.source_ref)
elif self.family:
self.family.add_source_reference(self.source_ref)
elif self.personref:
self.personref.add_source_reference(self.source_ref)
elif self.person:
self.person.add_source_reference(self.source_ref)
if self.citation:
self.citation.set_reference_handle(handle)
else:
# GRAMPS LEGACY: Prior to v1.5.0 there were no citation objects.
# We need to copy the contents of the old SourceRef into a new
# Citation object.
self.in_old_sourceref = True
self.citation = gen.lib.Citation()
self.citation.set_reference_handle(handle)
self.citation.confidence = int(attrs.get("conf", self.conf))
self.citation.private = bool(attrs.get("priv"))
citation_handle = self.db.add_citation(self.citation, self.trans)
self.__add_citation(citation_handle)
def start_source(self, attrs):
"""
@ -2066,8 +2132,8 @@ class GrampsParser(UpdateCallback):
self.start_compound_date(attrs, gen.lib.Date.MOD_SPAN)
def start_compound_date(self, attrs, mode):
if self.source_ref:
date_value = self.source_ref.get_date_object()
if self.citation:
date_value = self.citation.get_date_object()
elif self.ord:
date_value = self.ord.get_date_object()
elif self.object:
@ -2148,8 +2214,8 @@ class GrampsParser(UpdateCallback):
newyear=newyear)
def start_dateval(self, attrs):
if self.source_ref:
date_value = self.source_ref.get_date_object()
if self.citation:
date_value = self.citation.get_date_object()
elif self.ord:
date_value = self.ord.get_date_object()
elif self.object:
@ -2227,8 +2293,8 @@ class GrampsParser(UpdateCallback):
newyear=newyear)
def start_datestr(self, attrs):
if self.source_ref:
date_value = self.source_ref.get_date_object()
if self.citation:
date_value = self.citation.get_date_object()
elif self.ord:
date_value = self.ord.get_date_object()
elif self.object:
@ -2531,13 +2597,23 @@ class GrampsParser(UpdateCallback):
self.source.title = tag
def stop_sourceref(self, *tag):
self.source_ref = None
# if we are in an old style sourceref we need to commit the citation
if self.in_old_sourceref:
self.db.commit_citation(self.citation, self.trans,
self.citation.get_change_time())
self.citation = None
self.in_old_sourceref = False
def stop_source(self, *tag):
self.db.commit_source(self.source, self.trans,
self.source.get_change_time())
self.source = None
def stop_citation(self, *tag):
self.db.commit_citation(self.citation, self.trans,
self.citation.get_change_time())
self.citation = None
def stop_sauthor(self, tag):
self.source.author = tag
@ -2566,7 +2642,16 @@ class GrampsParser(UpdateCallback):
self.address.set_postal_code(tag)
def stop_spage(self, tag):
self.source_ref.set_page(tag)
# Valid for version <= 1.4.0
self.citation.set_page(tag)
def stop_page(self, tag):
# Valid for version >= 1.5.0
self.citation.set_page(tag)
def stop_confidence(self, tag):
# Valid for version >= 1.5.0
self.citation.set_confidence_level(int(tag))
def stop_lds_ord(self, *tag):
self.ord = None
@ -2587,14 +2672,14 @@ class GrampsParser(UpdateCallback):
# So we create a new note, commit, and add the handle to note list.
note = gen.lib.Note()
note.handle = Utils.create_id()
note.private = self.source_ref.private
note.private = self.citation.private
note.set(text)
note.type.set(gen.lib.NoteType.SOURCE_TEXT)
self.db.add_note(note, self.trans)
#set correct change time
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.source_ref.add_note(note.handle)
self.citation.add_note(note.handle)
def stop_scomments(self, tag):
if self.use_p:
@ -2604,14 +2689,14 @@ class GrampsParser(UpdateCallback):
text = tag
note = gen.lib.Note()
note.handle = Utils.create_id()
note.private = self.source_ref.private
note.private = self.citation.private
note.set(text)
note.type.set(gen.lib.NoteType.SOURCEREF)
note.type.set(gen.lib.NoteType.CITATION)
self.db.add_note(note, self.trans)
#set correct change time
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.source_ref.add_note(note.handle)
self.citation.add_note(note.handle)
def stop_last(self, tag):
if self.surname:

View File

@ -35,5 +35,5 @@
# Public Constants
#
#------------------------------------------------------------------------
GRAMPS_XML_VERSION = "1.4.0"
GRAMPS_XML_VERSION = "1.5.0"