Add citations to event references

This commit is contained in:
Christopher Horn 2022-09-05 19:23:19 -04:00 committed by Nick Hall
parent 3a8b087969
commit 6b52bccea9
9 changed files with 126 additions and 46 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2001 Graham J. Williams # Copyright (C) 2001 Graham J. Williams
@ -24,15 +24,15 @@
--> -->
<!-- <!--
This is the Document Type Definition file for v1.7.1 This is the Document Type Definition file for v1.7.2
of the GRAMPS XML genealogy data format. of the GRAMPS XML genealogy data format.
Please use the following formal public identifier to identify it: Please use the following formal public identifier to identify it:
"-//GRAMPS//DTD GRAMPS XML V1.7.1//EN" "-//GRAMPS//DTD GRAMPS XML V1.7.2//EN"
For example: For example:
<!DOCTYPE database PUBLIC "-//GRAMPS//DTD GRAMPS XML V1.7.1//EN" <!DOCTYPE database PUBLIC "-//GRAMPS//DTD GRAMPS XML V1.7.2//EN"
"http://gramps-project.org/xml/1.7.1/grampsxml.dtd" "http://gramps-project.org/xml/1.7.2/grampsxml.dtd"
[...]> [...]>
--> -->
@ -61,7 +61,7 @@ DATABASE
<!ELEMENT database (header, name-formats?, tags?, events?, people?, families?, <!ELEMENT database (header, name-formats?, tags?, events?, people?, families?,
citations?, sources?, places?, objects?, repositories?, citations?, sources?, places?, objects?, repositories?,
notes?, bookmarks?, namemaps?)> notes?, bookmarks?, namemaps?)>
<!ATTLIST database xmlns CDATA #FIXED "http://gramps-project.org/xml/1.7.1/"> <!ATTLIST database xmlns CDATA #FIXED "http://gramps-project.org/xml/1.7.2/">
<!-- ************************************************************ <!-- ************************************************************
@ -99,7 +99,7 @@ PEOPLE
--> -->
<!ELEMENT people (person)*> <!ELEMENT people (person)*>
<!ATTLIST people <!ATTLIST people
default CDATA #IMPLIED default CDATA #IMPLIED
home IDREF #IMPLIED home IDREF #IMPLIED
> >
@ -122,7 +122,7 @@ GENDER has values of M, F, or U.
<!ELEMENT name (first?, call?, surname*, suffix?, title?, nick?, familynick?, group?, <!ELEMENT name (first?, call?, surname*, suffix?, title?, nick?, familynick?, group?,
(daterange|datespan|dateval|datestr)?, noteref*, citationref*)> (daterange|datespan|dateval|datestr)?, noteref*, citationref*)>
<!-- (Unknown|Also Know As|Birth Name|Married Name|Other Name) --> <!-- (Unknown|Also Know As|Birth Name|Married Name|Other Name) -->
<!ATTLIST name <!ATTLIST name
alt (0|1) #IMPLIED alt (0|1) #IMPLIED
type CDATA #IMPLIED type CDATA #IMPLIED
priv (0|1) #IMPLIED priv (0|1) #IMPLIED
@ -155,15 +155,15 @@ Pseudonym|Patrilineal|Matrilineal|Occupation|Location) -->
<!ATTLIST parentin hlink IDREF #REQUIRED> <!ATTLIST parentin hlink IDREF #REQUIRED>
<!ELEMENT personref (citationref*, noteref*)> <!ELEMENT personref (citationref*, noteref*)>
<!ATTLIST personref <!ATTLIST personref
hlink IDREF #REQUIRED hlink IDREF #REQUIRED
priv (0|1) #IMPLIED priv (0|1) #IMPLIED
rel CDATA #REQUIRED rel CDATA #REQUIRED
> >
<!ELEMENT address ((daterange|datespan|dateval|datestr)?, street?, <!ELEMENT address ((daterange|datespan|dateval|datestr)?, street?,
locality?, city?, county?, state?, country?, postal?, locality?, city?, county?, state?, country?, postal?,
phone?, noteref*,citationref*)> phone?, noteref*, citationref*)>
<!ATTLIST address priv (0|1) #IMPLIED> <!ATTLIST address priv (0|1) #IMPLIED>
<!ELEMENT street (#PCDATA)> <!ELEMENT street (#PCDATA)>
@ -220,7 +220,7 @@ EVENT
<!ELEMENT event (type?, (daterange|datespan|dateval|datestr)?, place?, cause?, <!ELEMENT event (type?, (daterange|datespan|dateval|datestr)?, place?, cause?,
description?, attribute*, noteref*, citationref*, objref*, description?, attribute*, noteref*, citationref*, objref*,
tagref*)> tagref*)>
<!ATTLIST event <!ATTLIST event
id CDATA #IMPLIED id CDATA #IMPLIED
handle ID #REQUIRED handle ID #REQUIRED
priv (0|1) #IMPLIED priv (0|1) #IMPLIED
@ -396,7 +396,7 @@ BOOKMARKS
<!ELEMENT bookmarks (bookmark)*> <!ELEMENT bookmarks (bookmark)*>
<!ELEMENT bookmark EMPTY> <!ELEMENT bookmark EMPTY>
<!ATTLIST bookmark <!ATTLIST bookmark
target (person|family|event|source|citation|place|media|repository| target (person|family|event|source|citation|place|media|repository|
note) #REQUIRED note) #REQUIRED
hlink IDREF #REQUIRED hlink IDREF #REQUIRED
@ -407,7 +407,7 @@ NAME MAPS
--> -->
<!ELEMENT namemaps (map)*> <!ELEMENT namemaps (map)*>
<!ELEMENT map EMPTY> <!ELEMENT map EMPTY>
<!ATTLIST map <!ATTLIST map
type CDATA #REQUIRED type CDATA #REQUIRED
key CDATA #REQUIRED key CDATA #REQUIRED
value CDATA #REQUIRED value CDATA #REQUIRED
@ -436,7 +436,7 @@ SHARED ELEMENTS
quality (estimated|calculated) #IMPLIED quality (estimated|calculated) #IMPLIED
cformat CDATA #IMPLIED cformat CDATA #IMPLIED
dualdated (0|1) #IMPLIED dualdated (0|1) #IMPLIED
newyear CDATA #IMPLIED newyear CDATA #IMPLIED
> >
<!ELEMENT datespan EMPTY> <!ELEMENT datespan EMPTY>
@ -446,7 +446,7 @@ SHARED ELEMENTS
quality (estimated|calculated) #IMPLIED quality (estimated|calculated) #IMPLIED
cformat CDATA #IMPLIED cformat CDATA #IMPLIED
dualdated (0|1) #IMPLIED dualdated (0|1) #IMPLIED
newyear CDATA #IMPLIED newyear CDATA #IMPLIED
> >
<!ELEMENT dateval EMPTY> <!ELEMENT dateval EMPTY>
@ -456,7 +456,7 @@ SHARED ELEMENTS
quality (estimated|calculated) #IMPLIED quality (estimated|calculated) #IMPLIED
cformat CDATA #IMPLIED cformat CDATA #IMPLIED
dualdated (0|1) #IMPLIED dualdated (0|1) #IMPLIED
newyear CDATA #IMPLIED newyear CDATA #IMPLIED
> >
<!ELEMENT datestr EMPTY> <!ELEMENT datestr EMPTY>
@ -472,7 +472,7 @@ SHARED ELEMENTS
hlink IDREF #REQUIRED hlink IDREF #REQUIRED
> >
<!ELEMENT eventref (attribute*, noteref*)> <!ELEMENT eventref (attribute*, noteref*, citationref*)>
<!ATTLIST eventref <!ATTLIST eventref
hlink IDREF #REQUIRED hlink IDREF #REQUIRED
priv (0|1) #IMPLIED priv (0|1) #IMPLIED
@ -529,7 +529,7 @@ SHARED ELEMENTS
> >
<!ELEMENT objref (region?, attribute*, citationref*, noteref*)> <!ELEMENT objref (region?, attribute*, citationref*, noteref*)>
<!ATTLIST objref <!ATTLIST objref
hlink IDREF #REQUIRED hlink IDREF #REQUIRED
priv (0|1) #IMPLIED priv (0|1) #IMPLIED
> >

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2005-2007 Donald N. Allingham # Copyright (C) 2005-2007 Donald N. Allingham
@ -30,12 +30,12 @@
<grammar <grammar
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
ns="http://gramps-project.org/xml/1.7.1/" ns="http://gramps-project.org/xml/1.7.2/"
xmlns="http://relaxng.org/ns/structure/1.0"> xmlns="http://relaxng.org/ns/structure/1.0">
<start><element name="database"> <start><element name="database">
<element name="header"> <element name="header">
<element name="created"> <element name="created">
<attribute name="date"><data type="date"/></attribute> <attribute name="date"><data type="date"/></attribute>
@ -547,7 +547,7 @@
</choice></attribute> </choice></attribute>
<attribute name="hlink"><data type="IDREF"/></attribute> <attribute name="hlink"><data type="IDREF"/></attribute>
</define> </define>
<define name="map-content"> <define name="map-content">
<attribute name="type"><choice> <attribute name="type"><choice>
<value>group_as</value> <value>group_as</value>
@ -604,7 +604,7 @@
<define name="citationref-content"> <define name="citationref-content">
<attribute name="hlink"><data type="IDREF"/></attribute> <attribute name="hlink"><data type="IDREF"/></attribute>
</define> </define>
<define name="personref-content"> <define name="personref-content">
<attribute name="hlink"><data type="IDREF"/></attribute> <attribute name="hlink"><data type="IDREF"/></attribute>
<optional><attribute name="priv"> <optional><attribute name="priv">
@ -618,11 +618,11 @@
<ref name="noteref-content"/> <ref name="noteref-content"/>
</element></zeroOrMore></optional> </element></zeroOrMore></optional>
</define> </define>
<define name="sourceref-content"> <define name="sourceref-content">
<attribute name="hlink"><data type="IDREF"/></attribute> <attribute name="hlink"><data type="IDREF"/></attribute>
</define> </define>
<define name="eventref-content"> <define name="eventref-content">
<attribute name="hlink"><data type="IDREF"/></attribute> <attribute name="hlink"><data type="IDREF"/></attribute>
<optional><attribute name="priv"> <optional><attribute name="priv">
@ -635,6 +635,9 @@
<zeroOrMore><element name="noteref"> <zeroOrMore><element name="noteref">
<ref name="noteref-content"/> <ref name="noteref-content"/>
</element></zeroOrMore> </element></zeroOrMore>
<optional><zeroOrMore><element name="citationref">
<ref name="citationref-content"/>
</element></zeroOrMore></optional>
</define> </define>
<define name="reporef-content"> <define name="reporef-content">
@ -659,7 +662,7 @@
<value>1</value> <value>1</value>
</choice> </choice>
</define> </define>
<define name="attribute-content"> <define name="attribute-content">
<optional><attribute name="priv"> <optional><attribute name="priv">
<ref name="priv-content"/> <ref name="priv-content"/>
@ -673,7 +676,7 @@
<ref name="noteref-content"/> <ref name="noteref-content"/>
</element></zeroOrMore> </element></zeroOrMore>
</define> </define>
<define name="srcattribute-content"> <define name="srcattribute-content">
<optional><attribute name="priv"> <optional><attribute name="priv">
<ref name="priv-content"/> <ref name="priv-content"/>
@ -698,7 +701,7 @@
</attribute></optional> </attribute></optional>
<optional><element name="region"> <optional><element name="region">
<ref name="region-content"/> <ref name="region-content"/>
</element></optional> </element></optional>
<zeroOrMore><element name="attribute"> <zeroOrMore><element name="attribute">
<ref name="attribute-content"/> <ref name="attribute-content"/>
</element></zeroOrMore> </element></zeroOrMore>

View File

@ -28352,6 +28352,7 @@
<attribute type="Father Age" value="28"> <attribute type="Father Age" value="28">
<citationref hlink="_c140d7c7bdc1fedb030"/> <citationref hlink="_c140d7c7bdc1fedb030"/>
</attribute> </attribute>
<citationref hlink="_c140d5e5dbf300411bf"/>
</eventref> </eventref>
<eventref hlink="_a5af0ecb11f5ac3110e" role="Primary"/> <eventref hlink="_a5af0ecb11f5ac3110e" role="Primary"/>
<eventref hlink="_a5af0ecb12e29af8a5d" role="Primary"/> <eventref hlink="_a5af0ecb12e29af8a5d" role="Primary"/>

View File

@ -57,11 +57,65 @@ def gramps_upgrade_20(self):
# uid and place upgrade code goes here # uid and place upgrade code goes here
#----------------------------------------
# Modify Person
#----------------------------------------
# Add citation_list to person eventref objects
for person_handle in self.get_person_handles():
person = self.get_raw_person_data(person_handle)
(handle, gramps_id, gender, primary_name, alternate_names,
death_ref_index, birth_ref_index, event_ref_list, family_list,
parent_family_list, media_list, address_list, attribute_list,
urls, lds_seal_list, citation_list, note_list, change, tag_list,
private, person_ref_list) = person
if event_ref_list:
event_ref_list = upgrade_event_ref_list_20(event_ref_list)
new_person = (handle, gramps_id, gender, primary_name,
alternate_names, death_ref_index,
birth_ref_index, event_ref_list, family_list,
parent_family_list, media_list, address_list,
attribute_list, urls, lds_seal_list,
citation_list, note_list, change, tag_list,
private, person_ref_list)
self._commit_raw(new_person, PERSON_KEY)
self.update()
#----------------------------------------
# Modify Family
#----------------------------------------
# Add citation_list to family eventref objects
for family_handle in self.get_family_handles():
family = self.get_raw_family_data(family_handle)
(handle, gramps_id, father_handle, mother_handle,
child_ref_list, the_type, event_ref_list, media_list,
attribute_list, lds_seal_list, citation_list, note_list,
change, marker, private) = family
if event_ref_list:
event_ref_list = upgrade_event_ref_list_20(event_ref_list)
new_family = (handle, gramps_id, father_handle, mother_handle,
child_ref_list, the_type, event_ref_list,
media_list, attribute_list, lds_seal_list,
citation_list, note_list, change, marker, private)
self._commit_raw(new_family, FAMILY_KEY)
self.update()
self._txn_commit() self._txn_commit()
# Bump up database version. Separate transaction to save metadata. # Bump up database version. Separate transaction to save metadata.
self._set_metadata('version', 20) self._set_metadata('version', 20)
def upgrade_event_ref_list_20(event_ref_list):
"""
Insert citation_list into eventref objects
"""
new_event_ref_list = []
for event_ref in event_ref_list:
(privacy, note_list, attribute_list, ref, role) = event_ref
new_event_ref = (privacy, [], note_list, attribute_list, ref, role)
new_event_ref_list.append((new_event_ref))
return new_event_ref_list
def gramps_upgrade_19(self): def gramps_upgrade_19(self):
""" """
Upgrade database from version 18 to 19. Upgrade database from version 18 to 19.

View File

@ -38,7 +38,7 @@ from .attrbase import AttributeBase
from .refbase import RefBase from .refbase import RefBase
from .eventroletype import EventRoleType from .eventroletype import EventRoleType
from .const import IDENTICAL, EQUAL, DIFFERENT from .const import IDENTICAL, EQUAL, DIFFERENT
from .citationbase import IndirectCitationBase from .citationbase import CitationBase
from ..const import GRAMPS_LOCALE as glocale from ..const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
@ -48,7 +48,7 @@ _ = glocale.translation.gettext
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class EventRef(PrivacyBase, NoteBase, AttributeBase, RefBase, class EventRef(PrivacyBase, NoteBase, AttributeBase, RefBase,
IndirectCitationBase, SecondaryObject): CitationBase, SecondaryObject):
""" """
Event reference class. Event reference class.
@ -61,6 +61,7 @@ class EventRef(PrivacyBase, NoteBase, AttributeBase, RefBase,
Create a new EventRef instance, copying from the source if present. Create a new EventRef instance, copying from the source if present.
""" """
PrivacyBase.__init__(self, source) PrivacyBase.__init__(self, source)
CitationBase.__init__(self, source)
NoteBase.__init__(self, source) NoteBase.__init__(self, source)
AttributeBase.__init__(self, source) AttributeBase.__init__(self, source)
RefBase.__init__(self, source) RefBase.__init__(self, source)
@ -75,6 +76,7 @@ class EventRef(PrivacyBase, NoteBase, AttributeBase, RefBase,
""" """
return ( return (
PrivacyBase.serialize(self), PrivacyBase.serialize(self),
CitationBase.serialize(self),
NoteBase.serialize(self), NoteBase.serialize(self),
AttributeBase.serialize(self), AttributeBase.serialize(self),
RefBase.serialize(self), RefBase.serialize(self),
@ -97,6 +99,10 @@ class EventRef(PrivacyBase, NoteBase, AttributeBase, RefBase,
"_class": {"enum": [cls.__name__]}, "_class": {"enum": [cls.__name__]},
"private": {"type": "boolean", "private": {"type": "boolean",
"title": _("Private")}, "title": _("Private")},
"citation_list": {"type": "array",
"title": _("Citations"),
"items": {"type": "string",
"maxLength": 50}},
"note_list": {"type": "array", "note_list": {"type": "array",
"items": {"type": "string", "items": {"type": "string",
"maxLength": 50}, "maxLength": 50},
@ -115,8 +121,9 @@ class EventRef(PrivacyBase, NoteBase, AttributeBase, RefBase,
""" """
Convert a serialized tuple of data to an object. Convert a serialized tuple of data to an object.
""" """
(privacy, note_list, attribute_list, ref, role) = data (privacy, citation_list, note_list, attribute_list, ref, role) = data
PrivacyBase.unserialize(self, privacy) PrivacyBase.unserialize(self, privacy)
CitationBase.unserialize(self, citation_list)
NoteBase.unserialize(self, note_list) NoteBase.unserialize(self, note_list)
AttributeBase.unserialize(self, attribute_list) AttributeBase.unserialize(self, attribute_list)
RefBase.unserialize(self, ref) RefBase.unserialize(self, ref)
@ -171,7 +178,8 @@ class EventRef(PrivacyBase, NoteBase, AttributeBase, RefBase,
objects. objects.
:rtype: list :rtype: list
""" """
ret = self.get_referenced_note_handles() ret = self.get_referenced_citation_handles() + \
self.get_referenced_note_handles()
if self.ref: if self.ref:
ret += [('Event', self.ref)] ret += [('Event', self.ref)]
return ret return ret
@ -215,6 +223,7 @@ class EventRef(PrivacyBase, NoteBase, AttributeBase, RefBase,
""" """
self._merge_privacy(acquisition) self._merge_privacy(acquisition)
self._merge_attribute_list(acquisition) self._merge_attribute_list(acquisition)
self._merge_citation_list(acquisition)
self._merge_note_list(acquisition) self._merge_note_list(acquisition)
def get_role(self): def get_role(self):

View File

@ -210,6 +210,13 @@ class EditEventRef(EditReference):
self._add_tab(notebook, self.srcref_list) self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list") self.track_ref_for_deletion("srcref_list")
self.srcref_ref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.source_ref.get_citation_list())
self._add_tab(notebook_ref, self.srcref_ref_list)
self.track_ref_for_deletion("srcref_ref_list")
self.attr_list = EventAttrEmbedList(self.dbstate, self.attr_list = EventAttrEmbedList(self.dbstate,
self.uistate, self.uistate,
self.track, self.track,
@ -217,6 +224,14 @@ class EditEventRef(EditReference):
self._add_tab(notebook, self.attr_list) self._add_tab(notebook, self.attr_list)
self.track_ref_for_deletion("attr_list") self.track_ref_for_deletion("attr_list")
self.attr_ref_list = EventAttrEmbedList(
self.dbstate,
self.uistate,
self.track,
self.source_ref.get_attribute_list())
self._add_tab(notebook_ref, self.attr_ref_list)
self.track_ref_for_deletion("attr_ref_list")
self.note_tab = NoteTab(self.dbstate, self.note_tab = NoteTab(self.dbstate,
self.uistate, self.uistate,
self.track, self.track,
@ -248,14 +263,6 @@ class EditEventRef(EditReference):
self._add_tab(notebook, self.backref_tab) self._add_tab(notebook, self.backref_tab)
self.track_ref_for_deletion("backref_tab") self.track_ref_for_deletion("backref_tab")
self.attr_ref_list = EventAttrEmbedList(
self.dbstate,
self.uistate,
self.track,
self.source_ref.get_attribute_list())
self._add_tab(notebook_ref, self.attr_ref_list)
self.track_ref_for_deletion("attr_ref_list")
self._setup_notebook_tabs( notebook) self._setup_notebook_tabs( notebook)
self._setup_notebook_tabs( notebook_ref) self._setup_notebook_tabs( notebook_ref)

View File

@ -782,8 +782,9 @@ class GrampsXmlWriter(UpdateCallback):
role_text = "" role_text = ""
attribute_list = eventref.get_attribute_list() attribute_list = eventref.get_attribute_list()
citation_list = eventref.get_citation_list()
note_list = eventref.get_note_list() note_list = eventref.get_note_list()
if len(attribute_list) + len(note_list) == 0: if (len(citation_list) + len(attribute_list) + len(note_list) == 0):
self.write_ref( self.write_ref(
"eventref", "eventref",
eventref.ref, eventref.ref,
@ -801,6 +802,8 @@ class GrampsXmlWriter(UpdateCallback):
) )
self.write_attribute_list(attribute_list, index + 1) self.write_attribute_list(attribute_list, index + 1)
self.write_note_list(note_list, index + 1) self.write_note_list(note_list, index + 1)
for citation_handle in citation_list:
self.write_ref("citationref", citation_handle, index+1)
self.g.write("%s</eventref>\n" % sp) self.g.write("%s</eventref>\n" % sp)
def dump_place_ref(self, placeref, index=1): def dump_place_ref(self, placeref, index=1):

View File

@ -2217,6 +2217,8 @@ class GrampsParser(UpdateCallback):
self.objref.add_citation(citation_handle) self.objref.add_citation(citation_handle)
elif self.event: elif self.event:
self.event.add_citation(citation_handle) self.event.add_citation(citation_handle)
elif self.eventref:
self.eventref.add_citation(citation_handle)
elif self.address: elif self.address:
self.address.add_citation(citation_handle) self.address.add_citation(citation_handle)
elif self.name: elif self.name:

View File

@ -138,6 +138,7 @@ class ToolControl(unittest.TestCase):
"-y", "-a", "tool", "-p", "name=check") "-y", "-a", "tool", "-p", "name=check")
expect = ["7 broken child/family links were fixed", expect = ["7 broken child/family links were fixed",
"4 broken spouse/family links were fixed", "4 broken spouse/family links were fixed",
"1 corrupted family relationship fixed",
"1 place alternate name fixed", "1 place alternate name fixed",
"10 media objects were referenced, but not found", "10 media objects were referenced, but not found",
"References to 10 missing media objects were kept", "References to 10 missing media objects were kept",
@ -145,8 +146,8 @@ class ToolControl(unittest.TestCase):
"1 invalid birth event name was fixed", "1 invalid birth event name was fixed",
"1 invalid death event name was fixed", "1 invalid death event name was fixed",
"2 places were referenced, but not found", "2 places were referenced, but not found",
"14 citations were referenced, but not found", "12 citations were referenced, but not found",
"17 sources were referenced, but not found", "15 sources were referenced, but not found",
"9 Duplicated Gramps IDs fixed", "9 Duplicated Gramps IDs fixed",
"7 empty objects removed", "7 empty objects removed",
"1 person objects", "1 person objects",