2332: Allow reorder of Data in the Data tab of Source: make Data SourceAttribute, which have sourcetype,

link with GEPS 018: Evidence
This is step 1 needed for GEPS 018. All types are defined needed to evidence style references
This commit also contains fix for 6777: Crash on export to GEDCOM when there are addresses


svn: r22423
This commit is contained in:
Benny Malengier 2013-05-26 19:28:57 +00:00
parent 3d9559cfae
commit bf29e57039
38 changed files with 10286 additions and 419 deletions

19
data/evidencestyle/README Normal file
View File

@ -0,0 +1,19 @@
* Original evidence_style downloaded from
http://jytangledweb.org/genealogy/evidencestyle/ which are given there
for use in genealogy programs
* Several fixes done in the csv file which I believe were errors
* Run
$ python evidencefield.py
to generate two files with python code usable in srcattrtype.py in Gramps.
* If in the future one wants to insert _NEW_ evidence styles, add them at the
bottom of the csv file, generate the data, and copy to srcattrtype.py
* CAREFUL: When adding or changing things, DON'T change the type of already
released versions in Gramps! That means the integer indexes used must remain
the same! If only styles are added at the bottom and no lines removed,
this should not be a problem.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2013 Benny Malengier
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"""
This module parses the evidence csv file and generates the code we need in
Gramps to use the evidence style.
"""
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
import csv
#-------------------------------------------------------------------------
#
# Code
#
#-------------------------------------------------------------------------
csvfilename = "evidence_style.csv"
NRCOL = 0
CATCOL = 1
CATTYPECOL = 2
TYPECOL = 3
DESCRCOL= 4
CITETYPECOL = 5
IDENTCOL = 6
LDELCOL = 7 # left delimiter
FIELDCOL = 8
RDELCOL = 9 # right delimiter
STYLECOL = 10
PRIVACYCOL = 11
OPTCOL = 12
nr = -1
cat = ''
cattype = ''
type = ''
descr = ''
cite_type = ''
ident = ''
TYPE2CITEMAP = {}
FIELDTYPEMAP = {}
index = 10
indexval = 10
first = True
with open(csvfilename, 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=',')
for row in reader:
if first:
#skip first row with headers
first=False
continue
if row[CATCOL]:
cat = row[CATCOL]
cattype = row[CATTYPECOL]
type = row[TYPECOL]
descr = row[DESCRCOL]
source_type = row[IDENTCOL]
if descr:
source_descr = '%s - %s - %s (%s)' % (type, cattype, cat, descr)
source_descr_code = "_('%(first)s - %(sec)s - %(third)s (%(fourth)s)') % { "\
" 'first': _('" + type + "'),"\
" 'sec': _('" + cattype + "'),"\
" 'third': _('" + cat + "'),"\
" 'fourth': _('" + descr + "')}"
else:
source_descr = '%s - %s - %s' % (type, cattype, cat)
source_descr_code = "_('%(first)s - %(sec)s - %(third)s') % { "\
" 'first': _('" + type + "'),"\
" 'sec': _('" + cattype + "'),"\
" 'third': _('" + cat + "')}"
if source_type in TYPE2CITEMAP:
assert TYPE2CITEMAP[source_type] ['descr'] == source_descr, source_type + ' ' + TYPE2CITEMAP[source_type] ['descr'] + ' NOT ' + source_descr
else:
TYPE2CITEMAP[source_type] = {'L': [], 'F': [], 'S': [],
'i': indexval, 'descr': source_descr,
'descrcode': source_descr_code}
indexval += 1
if row[CITETYPECOL]:
#new citation type,
cite_type = row[CITETYPECOL]
#add field for template to evidence style
field = row[FIELDCOL]
field_type = field.replace(' ', '_').replace("'","")\
.replace('&','AND').replace('(', '6').replace(')','9')\
.replace('[', '').replace(']','').replace('/', '_OR_')\
.replace(',', '').replace('.', '').replace(':', '')\
.replace('-', '_')
field_descr = field.replace('[', '').replace(']','').lower().capitalize()
if field_type in FIELDTYPEMAP:
assert field_descr == FIELDTYPEMAP[field_type][1], 'Problem %s %s %s' % (field_type, field_descr, FIELDTYPEMAP[field_type][1])
else:
FIELDTYPEMAP[field_type] = (index, field_descr)
index += 1
fielddata = []
private = 'False'
if row[PRIVACYCOL]:
private = 'True'
optional = 'False'
if row[OPTCOL]:
optional = 'True'
TYPE2CITEMAP[source_type][cite_type] += [(row[LDELCOL], field_type,
row[RDELCOL], row[STYLECOL], private, optional)]
#now generate the python code we need in source attr types
code = ""
datamap = "\n _DATAMAP += [\n"
allkeys = sorted(FIELDTYPEMAP.keys())
for field_type in allkeys:
code += " " + field_type + ' = %d\n' % FIELDTYPEMAP[field_type][0]
datamap += ' (' + field_type + ', _("' + FIELDTYPEMAP[field_type][1] \
+'"), "' + FIELDTYPEMAP[field_type][1] + '"),\n'
code += '\n' + datamap + ' ]\n'
with open('srcattrtype_extra.py', 'wb') as srcattrfile:
srcattrfile.write(code)
#now generate the python code we need in evidencestyle
# we have predefined sourcetypes, and these have a template for formatting
#
#first an English to internationalized map
code = " #SRCTYPE has some predefined values which map to citation styles\n"
datamap = " _SRCTYPEVAL_MAP = [\n"
allkeys = sorted(TYPE2CITEMAP.keys())
for source_type in allkeys:
code += " " + source_type + ' = %d\n' % TYPE2CITEMAP[source_type]['i']
# we use descrcode in to translate string to reduce work for translators
datamap += ' (' + source_type + ', ' + TYPE2CITEMAP[source_type]['descrcode'] \
+', "' + TYPE2CITEMAP[source_type]['descr'] + '"),\n'
code += '\n # Localization of the different source types\n'\
+ datamap + ' ]\n'
code += "\n #templates for the source types defined\n"
code += ' EVIDENCETEMPLATES = {\n'
for source_type in allkeys:
code += " '" + source_type + "': {\n"
for val in ['F', 'L', 'S']:
code += " '" + val + "': [\n"
for field in TYPE2CITEMAP[source_type][val]:
# field is tuple (row[LDELCOL], field_type, row[RDELCOL], row[STYLECOL]
# , private, optional)
code += " ('"+ field[0] + "', " + field[1] + ", '" + field[2] + \
"', '" + field[3] + "', " + field[4] + ", " + field[5] + "),\n"
code += " ],\n"
code += " },\n"
code += " }\n"
with open('srcattrtype_extraevidence.py', 'wb') as srcattrfile:
srcattrfile.write(code)

View File

@ -230,7 +230,7 @@ SOURCES
<!ELEMENT sources (source)*>
<!ELEMENT source (stitle?, sauthor?, spubinfo?, sabbrev?,
noteref*, objref*, data_item*, reporef*, tagref*)>
noteref*, objref*, srcattribute*, reporef*, tagref*)>
<!ATTLIST source
id CDATA #IMPLIED
handle ID #REQUIRED
@ -369,7 +369,7 @@ CITATIONS
<!ELEMENT citations (citation)*>
<!ELEMENT citation ((daterange|datespan|dateval|datestr)?, page?, confidence?,
noteref*, objref*, data_item*, sourceref, tagref*)>
noteref*, objref*, srcattribute*, sourceref, tagref*)>
<!ATTLIST citation
id CDATA #IMPLIED
handle ID #REQUIRED
@ -494,6 +494,13 @@ SHARED ELEMENTS
value CDATA #REQUIRED
>
<!ELEMENT srcattribute EMPTY>
<!ATTLIST srcattribute
priv (0|1) #IMPLIED
type CDATA #REQUIRED
value CDATA #REQUIRED
>
<!ELEMENT place EMPTY>
<!ATTLIST place hlink IDREF #REQUIRED>

View File

@ -438,9 +438,8 @@
<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>
<zeroOrMore><element name="srcattribute">
<ref name="srcattribute-content"/>
</element></zeroOrMore>
<element name="sourceref">
<ref name="sourceref-content"/>
@ -459,9 +458,8 @@
<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>
<zeroOrMore><element name="srcattribute">
<ref name="srcattribute-content"/>
</element></zeroOrMore>
<zeroOrMore><element name="reporef">
<ref name="reporef-content"/>
@ -671,6 +669,14 @@
<ref name="noteref-content"/>
</element></zeroOrMore>
</define>
<define name="srcattribute-content">
<optional><attribute name="priv">
<ref name="priv-content"/>
</attribute></optional>
<attribute name="type"><text/></attribute>
<attribute name="value"><text/></attribute>
</define>
<define name="url-content">
<optional><attribute name="priv">

View File

@ -542,6 +542,13 @@ class DbReadBase(object):
"""
raise NotImplementedError
def get_source_attribute_types(self):
"""
Return a list of all Attribute types associated with Source/Citation
instances in the database.
"""
raise NotImplementedError
def get_place_bookmarks(self):
"""
Return the list of Place handles in the bookmarks.

View File

@ -368,6 +368,7 @@ class DbBsddbRead(DbReadBase, Callback):
self.individual_event_names = set()
self.individual_attributes = set()
self.family_attributes = set()
self.source_attributes = set()
self.child_ref_types = set()
self.family_rel_types = set()
self.event_role_names = set()
@ -1554,6 +1555,13 @@ class DbBsddbRead(DbReadBase, Callback):
"""
return list(self.note_types)
def get_source_attribute_types(self):
"""
Return a list of all Attribute types assocated with Source/Citation
instances in the database.
"""
return list(self.source_attributes)
def get_source_media_types(self):
"""
Return a list of all custom source media types assocated with Source

View File

@ -120,6 +120,7 @@ class DbTest(object):
"get_repository_types",
"get_researcher",
"get_save_path",
"get_source_attribute_types",
"get_source_bookmarks",
"get_source_cursor",
"get_source_from_gramps_id",

View File

@ -51,8 +51,10 @@ from .dbconst import (PERSON_KEY, FAMILY_KEY, EVENT_KEY,
from gramps.gui.dialog import (InfoDialog)
def gramps_upgrade_17(self):
"""Upgrade database from version 16 to 17. This upgrade adds tags to
event, place, repository, source and citation objects.
"""Upgrade database from version 16 to 17.
1. This upgrade adds tags to event, place, repository, source and
citation objects.
2. Data of Source becomes SourceAttributes Secondary Object
"""
length = (len(self.event_map) + len(self.place_map) +
len(self.repository_map) + len(self.source_map) +
@ -134,10 +136,54 @@ def gramps_upgrade_17(self):
txn.put(handle, new_citation)
self.update()
# -------------------------------------------------------
# Upgrade Source and Citation datamap to SrcAttributeBase
# -------------------------------------------------------
for handle in self.source_map.keys():
source = self.source_map[handle]
(handle, gramps_id, title, author, pubinfo,
notelist, medialist, abbrev, change, datamap, reporef_list,
taglist, private) = source
srcattributelist = upgrade_datamap_17(datamap)
new_source = (handle, gramps_id, title, author, pubinfo,
notelist, medialist, abbrev, change, srcattributelist, reporef_list,
taglist, private)
with BSDDBTxn(self.env, self.source_map) as txn:
if isinstance(handle, UNITYPE):
handle = handle.encode('utf-8')
txn.put(handle, new_source)
self.update()
for handle in self.citation_map.keys():
citation = self.citation_map[handle]
(handle, gramps_id, datelist, page, confidence, source_handle,
notelist, medialist, datamap, change, taglist, private) = citation
srcattributelist = upgrade_datamap_17(datamap)
new_citation = (handle, gramps_id, datelist, page, confidence, source_handle,
notelist, medialist, srcattributelist, change, taglist, private)
with BSDDBTxn(self.env, self.citation_map) as txn:
if isinstance(handle, UNITYPE):
handle = handle.encode('utf-8')
txn.put(handle, new_citation)
self.update()
# Bump up database version. Separate transaction to save metadata.
with BSDDBTxn(self.env, self.metadata) as txn:
txn.put(b'version', 17)
def upgrade_datamap_17(datamap):
"""
In version 16 key value pairs are stored in source and citation. These become
SrcAttribute
"""
new_srcattr_list = []
private = False
from ..lib.srcattrtype import SrcAttributeType
for (key, value) in datamap.iteritems():
the_type = SrcAttributeType(key).serialize()
new_srcattr_list.append((private, the_type, value))
return new_srcattr_list
def gramps_upgrade_16(self):
"""Upgrade database from version 15 to 16. This upgrade converts all
SourceRef child objects to Citation Primary objects.

View File

@ -819,6 +819,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
self.individual_event_names = set(meta(b'pevent_names'))
self.family_attributes = set(meta(b'fattr_names'))
self.individual_attributes = set(meta(b'pattr_names'))
self.source_attributes = set(meta(b'sattr_names'))
self.marker_names = set(meta(b'marker_names'))
self.child_ref_types = set(meta(b'child_refs'))
self.family_rel_types = set(meta(b'family_rels'))
@ -1252,6 +1253,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
txn.put(b'pevent_names', list(self.individual_event_names))
txn.put(b'fattr_names', list(self.family_attributes))
txn.put(b'pattr_names', list(self.individual_attributes))
txn.put(b'sattr_names', list(self.source_attributes))
txn.put(b'marker_names', list(self.marker_names))
txn.put(b'child_refs', list(self.child_ref_types))
txn.put(b'family_rels', list(self.family_rel_types))
@ -1815,6 +1817,10 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
if attr.type.is_custom() and str(attr.type)]
self.media_attributes.update(attr_list)
self.source_attributes.update(
[str(attr.type) for attr in source.attribute_list
if attr.type.is_custom() and str(attr.type)])
def commit_citation(self, citation, transaction, change_time=None):
"""
Commit the specified Citation to the database, storing the changes as
@ -1829,6 +1835,10 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
if attr.type.is_custom() and str(attr.type)]
self.media_attributes.update(attr_list)
self.source_attributes.update(
[str(attr.type) for attr in citation.attribute_list
if attr.type.is_custom() and str(attr.type)])
def commit_place(self, place, transaction, change_time=None):
"""
Commit the specified Place to the database, storing the changes as

View File

@ -31,6 +31,7 @@ from .secondaryobj import SecondaryObject
from .address import Address
from .location import Location
from .attribute import Attribute
from .srcattribute import SrcAttribute
from .eventref import EventRef
from .ldsord import LdsOrd
from .mediaref import MediaRef
@ -65,6 +66,7 @@ from .researcher import Researcher
from .grampstype import GrampsType
from .nametype import NameType
from .attrtype import AttributeType
from .srcattrtype import SrcAttributeType
from .urltype import UrlType
from .childreftype import ChildRefType
from .repotype import RepositoryType

View File

@ -31,6 +31,7 @@ AttributeBase class for GRAMPS.
#
#-------------------------------------------------------------------------
from .attribute import Attribute
from .srcattribute import SrcAttribute
from .const import IDENTICAL, EQUAL
from ..constfunc import STRTYPE
@ -39,23 +40,24 @@ from ..constfunc import STRTYPE
# AttributeBase class
#
#-------------------------------------------------------------------------
class AttributeBase(object):
class AttributeRootBase(object):
"""
Base class for attribute-aware objects.
"""
_CLASS = None
def __init__(self, source=None):
"""
Initialize a AttributeBase.
Initialize a AttributeBase.
If the source is not None, then object is initialized from values of
If the source is not None, then object is initialized from values of
the source object.
:param source: Object used to initialize the new object
:type source: AttributeBase
"""
if source:
self.attribute_list = [Attribute(attribute)
self.attribute_list = [self._CLASS(attribute)
for attribute in source.attribute_list]
else:
self.attribute_list = []
@ -92,7 +94,7 @@ class AttributeBase(object):
"""
Convert a serialized tuple of data to an object.
"""
self.attribute_list = [Attribute().unserialize(item) for item in data]
self.attribute_list = [self._CLASS().unserialize(item) for item in data]
def add_attribute(self, attribute):
"""
@ -162,3 +164,10 @@ class AttributeBase(object):
break
else:
self.attribute_list.append(addendum)
class AttributeBase(AttributeRootBase):
_CLASS = Attribute
class SrcAttributeBase(AttributeRootBase):
_CLASS = SrcAttribute

View File

@ -40,10 +40,10 @@ from .const import IDENTICAL, EQUAL, DIFFERENT
#-------------------------------------------------------------------------
#
# Attribute for Person/Family/MediaObject/MediaRef
# Root object for Attribute
#
#-------------------------------------------------------------------------
class Attribute(SecondaryObject, PrivacyBase, CitationBase, NoteBase):
class AttributeRoot(SecondaryObject, PrivacyBase):
"""
Provide a simple key/value pair for describing properties.
Used to store descriptive information.
@ -64,23 +64,16 @@ class Attribute(SecondaryObject, PrivacyBase, CitationBase, NoteBase):
Create a new Attribute object, copying from the source if provided.
"""
PrivacyBase.__init__(self, source)
CitationBase.__init__(self, source)
NoteBase.__init__(self, source)
if source:
self.type = AttributeType(source.type)
self.value = source.value
else:
self.type = AttributeType()
self.value = ""
#type structure depends on inheriting classes
self.type = None
self.value = None
def serialize(self):
"""
Convert the object to a serialized tuple of data.
"""
return (PrivacyBase.serialize(self),
CitationBase.serialize(self),
NoteBase.serialize(self),
self.type.serialize(), self.value)
def to_struct(self):
@ -104,8 +97,6 @@ class Attribute(SecondaryObject, PrivacyBase, CitationBase, NoteBase):
:rtype: dict
"""
return {"private": PrivacyBase.serialize(self),
"citation_list": CitationBase.to_struct(self),
"note_list": NoteBase.to_struct(self),
"type": self.type.to_struct(),
"value": self.value}
@ -113,10 +104,8 @@ class Attribute(SecondaryObject, PrivacyBase, CitationBase, NoteBase):
"""
Convert a serialized tuple of data to an object.
"""
(privacy, citation_list, note_list, the_type, self.value) = data
(privacy, the_type, self.value) = data
PrivacyBase.unserialize(self, privacy)
CitationBase.unserialize(self, citation_list)
NoteBase.unserialize(self, note_list)
self.type.unserialize(the_type)
return self
@ -166,8 +155,7 @@ class Attribute(SecondaryObject, PrivacyBase, CitationBase, NoteBase):
:returns: List of (classname, handle) tuples for referenced objects.
:rtype: list
"""
return self.get_referenced_note_handles() + \
self.get_referenced_citation_handles()
return []
def is_equivalent(self, other):
"""
@ -197,8 +185,6 @@ class Attribute(SecondaryObject, PrivacyBase, CitationBase, NoteBase):
:rtype acquisition: Attribute
"""
self._merge_privacy(acquisition)
self._merge_citation_list(acquisition)
self._merge_note_list(acquisition)
def set_type(self, val):
"""Set the type (or key) of the Attribute instance."""
@ -215,3 +201,94 @@ class Attribute(SecondaryObject, PrivacyBase, CitationBase, NoteBase):
def get_value(self):
"""Return the value of the Attribute instance."""
return self.value
#-------------------------------------------------------------------------
#
# Attribute for Person/Family/MediaObject/MediaRef
#
#-------------------------------------------------------------------------
class Attribute(AttributeRoot, CitationBase, NoteBase):
def __init__(self, source=None):
"""
Create a new Attribute object, copying from the source if provided.
"""
AttributeRoot.__init__(self, source)
CitationBase.__init__(self, source)
NoteBase.__init__(self, source)
if source:
self.type = AttributeType(source.type)
self.value = source.value
else:
self.type = AttributeType()
self.value = ""
def serialize(self):
"""
Convert the object to a serialized tuple of data.
"""
return (PrivacyBase.serialize(self),
CitationBase.serialize(self),
NoteBase.serialize(self),
self.type.serialize(), self.value)
def to_struct(self):
"""
Convert the data held in this object to a structure (eg,
struct) that represents all the data elements.
This method is used to recursively convert the object into a
self-documenting form that can easily be used for various
purposes, including diffs and queries.
These structures may be primitive Python types (string,
integer, boolean, etc.) or complex Python types (lists,
tuples, or dicts). If the return type is a dict, then the keys
of the dict match the fieldname of the object. If the return
struct (or value of a dict key) is a list, then it is a list
of structs. Otherwise, the struct is just the value of the
attribute.
:returns: Returns a struct containing the data of the object.
:rtype: dict
"""
return {"private": PrivacyBase.serialize(self),
"citation_list": CitationBase.to_struct(self),
"note_list": NoteBase.to_struct(self),
"type": self.type.to_struct(),
"value": self.value}
def unserialize(self, data):
"""
Convert a serialized tuple of data to an object.
"""
(privacy, citation_list, note_list, the_type, self.value) = data
PrivacyBase.unserialize(self, privacy)
CitationBase.unserialize(self, citation_list)
NoteBase.unserialize(self, note_list)
self.type.unserialize(the_type)
return self
def get_referenced_handles(self):
"""
Return the list of (classname, handle) tuples for all directly
referenced primary objects.
:returns: List of (classname, handle) tuples for referenced objects.
:rtype: list
"""
return self.get_referenced_note_handles() + \
self.get_referenced_citation_handles()
def merge(self, acquisition):
"""
Merge the content of acquisition into this attribute.
Lost: type and value of acquisition.
:param acquisition: the attribute to merge with the present attribute.
:rtype acquisition: Attribute
"""
AttributeRoot.merge(self, acquisition)
self._merge_citation_list(acquisition)
self._merge_note_list(acquisition)

View File

@ -44,6 +44,7 @@ from .mediabase import MediaBase
from .notebase import NoteBase
from .datebase import DateBase
from .tagbase import TagBase
from .attrbase import SrcAttributeBase
from ..constfunc import cuni
from .handle import Handle
@ -52,7 +53,7 @@ from .handle import Handle
# Citation class
#
#-------------------------------------------------------------------------
class Citation(MediaBase, NoteBase, PrimaryObject, DateBase):
class Citation(MediaBase, NoteBase, SrcAttributeBase, PrimaryObject, DateBase):
"""
A record of a citation of a source of information.
@ -76,7 +77,7 @@ class Citation(MediaBase, NoteBase, PrimaryObject, DateBase):
self.source_handle = None # 5
self.page = "" # 3
self.confidence = Citation.CONF_NORMAL # 4
self.datamap = {} # 8
SrcAttributeBase.__init__(self) # 8
def serialize(self, no_text_date = False):
"""
@ -90,7 +91,7 @@ class Citation(MediaBase, NoteBase, PrimaryObject, DateBase):
self.source_handle, # 5
NoteBase.serialize(self), # 6
MediaBase.serialize(self), # 7
self.datamap, # 8
SrcAttributeBase.serialize(self), # 8
self.change, # 9
TagBase.serialize(self), # 10
self.private) # 11
@ -123,7 +124,7 @@ class Citation(MediaBase, NoteBase, PrimaryObject, DateBase):
"source_handle": Handle("Source", self.source_handle), # 5
"note_list": NoteBase.to_struct(self), # 6
"media_list": MediaBase.to_struct(self), # 7
"datamap": self.datamap, # 8
"srcattr_list": SrcAttributeBase.to_struct(self),# 8
"change": self.change, # 9
"tag_list": TagBase.to_struct(self), # 10
"private": self.private} # 11
@ -141,7 +142,7 @@ class Citation(MediaBase, NoteBase, PrimaryObject, DateBase):
self.source_handle, # 5
note_list, # 6
media_list, # 7
self.datamap, # 8
srcattr_list, # 8
self.change, # 9
tag_list, # 10
self.private # 11
@ -151,6 +152,7 @@ class Citation(MediaBase, NoteBase, PrimaryObject, DateBase):
NoteBase.unserialize(self, note_list)
MediaBase.unserialize(self, media_list)
TagBase.unserialize(self, tag_list)
SrcAttributeBase.unserialize(self, srcattr_list)
return self
def _has_handle_reference(self, classname, handle):
@ -209,8 +211,7 @@ class Citation(MediaBase, NoteBase, PrimaryObject, DateBase):
:returns: Returns the list of all textual attributes of the object.
:rtype: list
"""
return [self.page,
self.gramps_id] + list(self.datamap.keys()) + list(self.datamap.values())
return [self.page, self.gramps_id]
def get_text_data_child_list(self):
"""
@ -219,7 +220,7 @@ class Citation(MediaBase, NoteBase, PrimaryObject, DateBase):
:returns: Returns the list of child objects that may carry textual data.
:rtype: list
"""
return self.media_list
return self.media_list + self.attribute_list
def get_note_child_list(self):
"""
@ -271,26 +272,10 @@ class Citation(MediaBase, NoteBase, PrimaryObject, DateBase):
idx = min(level_priority.index(self.confidence),
level_priority.index(acquisition.confidence))
self.confidence = level_priority[idx]
my_datamap = self.get_data_map()
acquisition_map = acquisition.get_data_map()
for key in acquisition.get_data_map():
if key not in my_datamap:
self.datamap[key] = acquisition_map[key]
self._merge_attribute_list(acquisition)
# N.B. a Citation can refer to only one 'Source', so the
# 'Source' from acquisition cannot be merged in
def get_data_map(self):
"""Return the data map of attributes for the source."""
return self.datamap
def set_data_map(self, datamap):
"""Set the data map of attributes for the source."""
self.datamap = datamap
def set_data_item(self, key, value):
"""Set the particular data item in the attribute data map."""
self.datamap[key] = value
def set_confidence_level(self, val):
"""Set the confidence level."""
self.confidence = val

View File

@ -35,6 +35,7 @@ from .primaryobj import PrimaryObject
from .mediabase import MediaBase
from .notebase import NoteBase
from .tagbase import TagBase
from .attrbase import SrcAttributeBase
from .reporef import RepoRef
from .const import DIFFERENT, EQUAL, IDENTICAL
from ..constfunc import cuni
@ -45,7 +46,7 @@ from .handle import Handle
# Source class
#
#-------------------------------------------------------------------------
class Source(MediaBase, NoteBase, PrimaryObject):
class Source(MediaBase, NoteBase, SrcAttributeBase, PrimaryObject):
"""A record of a source of information."""
def __init__(self):
@ -53,10 +54,10 @@ class Source(MediaBase, NoteBase, PrimaryObject):
PrimaryObject.__init__(self)
MediaBase.__init__(self)
NoteBase.__init__(self)
SrcAttributeBase.__init__(self)
self.title = ""
self.author = ""
self.pubinfo = ""
self.datamap = {}
self.abbrev = ""
self.reporef_list = []
@ -64,13 +65,19 @@ class Source(MediaBase, NoteBase, PrimaryObject):
"""
Convert the object to a serialized tuple of data.
"""
return (self.handle, self.gramps_id, cuni(self.title),
cuni(self.author), cuni(self.pubinfo),
NoteBase.serialize(self),
MediaBase.serialize(self), cuni(self.abbrev),
self.change, self.datamap,
[rr.serialize() for rr in self.reporef_list],
TagBase.serialize(self), self.private)
return (self.handle, # 0
self.gramps_id, # 1
cuni(self.title), # 2
cuni(self.author), # 3
cuni(self.pubinfo), # 4
NoteBase.serialize(self), # 5
MediaBase.serialize(self), # 6
cuni(self.abbrev), # 7
self.change, # 8
SrcAttributeBase.serialize(self), # 9
[rr.serialize() for rr in self.reporef_list], # 10
TagBase.serialize(self), # 11
self.private) # 12
def to_struct(self):
"""
@ -100,8 +107,8 @@ class Source(MediaBase, NoteBase, PrimaryObject):
"note_list": NoteBase.to_struct(self),
"media_list": MediaBase.to_struct(self),
"abbrev": cuni(self.abbrev),
"change": self.change,
"datamap": {"dict": self.datamap},
"change": self.change,
"srcattr_list": SrcAttributeBase.to_struct(self),
"reporef_list": [rr.to_struct() for rr in self.reporef_list],
"tag_list": TagBase.to_struct(self),
"private": self.private}
@ -111,14 +118,25 @@ class Source(MediaBase, NoteBase, PrimaryObject):
Convert the data held in a tuple created by the serialize method
back into the data in an Event structure.
"""
(self.handle, self.gramps_id, self.title, self.author,
self.pubinfo, note_list, media_list,
self.abbrev, self.change, self.datamap, reporef_list,
tag_list, self.private) = data
(self.handle, # 0
self.gramps_id, # 1
self.title, # 2
self.author, # 3
self.pubinfo, # 4
note_list, # 5
media_list, # 6
self.abbrev, # 7
self.change, # 8
srcattr_list, # 9
reporef_list, # 10
tag_list, # 11
self.private # 12
) = data
NoteBase.unserialize(self, note_list)
MediaBase.unserialize(self, media_list)
TagBase.unserialize(self, tag_list)
SrcAttributeBase.unserialize(self, srcattr_list)
self.reporef_list = [RepoRef().unserialize(item) for item in reporef_list]
return self
@ -179,7 +197,7 @@ class Source(MediaBase, NoteBase, PrimaryObject):
:rtype: list
"""
return [self.title, self.author, self.pubinfo, self.abbrev,
self.gramps_id] + list(self.datamap.keys()) + list(self.datamap.values())
self.gramps_id]
def get_text_data_child_list(self):
"""
@ -188,7 +206,7 @@ class Source(MediaBase, NoteBase, PrimaryObject):
:returns: Returns the list of child objects that may carry textual data.
:rtype: list
"""
return self.media_list + self.reporef_list
return self.media_list + self.reporef_list + self.attribute_list
def get_citation_child_list(self):
"""
@ -242,25 +260,9 @@ class Source(MediaBase, NoteBase, PrimaryObject):
self._merge_note_list(acquisition)
self._merge_media_list(acquisition)
self._merge_tag_list(acquisition)
my_datamap = self.get_data_map()
acquisition_map = acquisition.get_data_map()
for key in acquisition.get_data_map():
if key not in my_datamap:
self.datamap[key] = acquisition_map[key]
self._merge_attribute_list(acquisition)
self._merge_reporef_list(acquisition)
def get_data_map(self):
"""Return the data map of attributes for the source."""
return self.datamap
def set_data_map(self, datamap):
"""Set the data map of attributes for the source."""
self.datamap = datamap
def set_data_item(self, key, value):
"""Set the particular data item in the attribute data map."""
self.datamap[key] = value
def set_title(self, title):
"""
Set the descriptive title of the Source object.

View File

@ -0,0 +1,78 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2013 Benny Malengier
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"""
Source Attribute class for GRAMPS.
"""
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from .secondaryobj import SecondaryObject
from .privacybase import PrivacyBase
from .citationbase import CitationBase
from .notebase import NoteBase
from .attribute import AttributeRoot
from .srcattrtype import SrcAttributeType
from .const import IDENTICAL, EQUAL, DIFFERENT
#-------------------------------------------------------------------------
#
# Attribute for Source/Citation
#
#-------------------------------------------------------------------------
class SrcAttribute(AttributeRoot):
"""
Provide a simple key/value pair for describing properties.
Used to store descriptive information.
"""
def __init__(self, source=None):
"""
Create a new Attribute object, copying from the source if provided.
"""
AttributeRoot.__init__(self, source)
if source:
self.type = SrcAttributeType(source.type)
self.value = source.value
else:
self.type = SrcAttributeType()
self.value = ""
def get_text_data_list(self):
"""
Return the list of all textual attributes of the object.
:returns: Returns the list of all textual attributes of the object.
:rtype: list
"""
sat = SrcAttributeType()
if self.type == sat.SRCTYPE:
#we convert to the native language if possible
if self.value and self.value in sat.E2I_SRCTYPEMAP:
return [sat.I2S_SRCTYPEMAP[sat.E2I_SRCTYPEMAP[self.value]]]
return [self.value]

File diff suppressed because it is too large Load Diff

View File

@ -1549,13 +1549,34 @@ class SourceCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest,
pass
def test_merge_datamap(self):
self.phoenix.set_data_item('A', 'a')
self.phoenix.set_data_item('B', 'b')
self.titanic.set_data_item('B', 'bb')
self.titanic.set_data_item('C', 'c')
self.ref_obj.set_data_item('A', 'a')
self.ref_obj.set_data_item('B', 'b')
self.ref_obj.set_data_item('C', 'c')
sattr = SrcAttribute()
sattr.set_type('A')
sattr.set_value('a')
self.phoenix.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('B')
sattr.set_value('b')
self.phoenix.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('B')
sattr.set_value('bb')
self.titanic.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('C')
sattr.set_value('c')
self.titanic.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('A')
sattr.set_value('a')
self.ref_obj.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('B')
sattr.set_value('b')
self.ref_obj.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('C')
sattr.set_value('c')
self.ref_obj.add_attribute(sattr)
self.phoenix.merge(self.titanic)
self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize())
@ -1739,13 +1760,34 @@ class CitationCheck(unittest.TestCase, PrivacyBaseTest, MediaBaseTest,
self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize())
def test_merge_datamap(self):
self.phoenix.set_data_item('A', 'a')
self.phoenix.set_data_item('B', 'b')
self.titanic.set_data_item('B', 'bb')
self.titanic.set_data_item('C', 'c')
self.ref_obj.set_data_item('A', 'a')
self.ref_obj.set_data_item('B', 'b')
self.ref_obj.set_data_item('C', 'c')
sattr = SrcAttribute()
sattr.set_type('A')
sattr.set_value('a')
self.phoenix.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('B')
sattr.set_value('b')
self.phoenix.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('B')
sattr.set_value('bb')
self.titanic.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('C')
sattr.set_value('c')
self.titanic.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('A')
sattr.set_value('a')
self.ref_obj.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('B')
sattr.set_value('b')
self.ref_obj.add_attribute(sattr)
sattr = SrcAttribute()
sattr.set_type('C')
sattr.set_value('c')
self.ref_obj.add_attribute(sattr)
self.phoenix.merge(self.titanic)
self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize())

View File

@ -43,7 +43,8 @@ LOG = logging.getLogger(".citation")
#-------------------------------------------------------------------------
from ..lib import (MediaRef, Attribute, Address, EventRef,
Person, Name, Source, RepoRef, MediaObject, Place, Event,
Family, ChildRef, Repository, LdsOrd, Surname, Citation)
Family, ChildRef, Repository, LdsOrd, Surname, Citation,
SrcAttribute)
from .proxybase import ProxyDbBase
class PrivateProxyDb(ProxyDbBase):
@ -527,7 +528,7 @@ def copy_associations(db, original_obj, clean_obj):
if associated_person and not associated_person.get_privacy():
new_person_ref_list.append(person_ref)
clean_obj.set_person_ref_list(new_person_ref_list)
def copy_attributes(db, original_obj, clean_obj):
"""
Copies attributes from one object to another - excluding references to
@ -549,7 +550,27 @@ def copy_attributes(db, original_obj, clean_obj):
copy_notes(db, attribute, new_attribute)
copy_citation_ref_list(db, attribute, new_attribute)
clean_obj.add_attribute(new_attribute)
def copy_srcattributes(db, original_obj, clean_obj):
"""
Copies srcattributes from one object to another - excluding references to
private srcattributes.
@param db: GRAMPS database to which the references belongs
@type db: DbBase
@param original_obj: Object that may have private references
@type original_obj: SrcAttributeBase
@param clean_obj: Object that will have only non-private references
@type original_obj: SrcAttributeBase
@returns: Nothing
"""
for attribute in original_obj.get_attribute_list():
if attribute and not attribute.get_privacy():
new_attribute = SrcAttribute()
new_attribute.set_type(attribute.get_type())
new_attribute.set_value(attribute.get_value())
clean_obj.add_attribute(new_attribute)
def copy_urls(db, original_obj, clean_obj):
"""
Copies urls from one object to another - excluding references to
@ -744,10 +765,10 @@ def sanitize_citation(db, citation):
new_citation.set_page(citation.get_page())
new_citation.set_confidence_level(citation.get_confidence_level())
new_citation.set_reference_handle(citation.get_reference_handle())
new_citation.set_data_map(citation.get_data_map())
new_citation.set_gramps_id(citation.get_gramps_id())
new_citation.set_handle(citation.get_handle())
new_citation.set_change_time(citation.get_change_time())
copy_srcattributes(db, citation, new_citation)
copy_notes(db, citation, new_citation)
copy_media_ref_list(db, citation, new_citation)
@ -892,7 +913,6 @@ def sanitize_source(db, source):
new_source.set_gramps_id(source.get_gramps_id())
new_source.set_handle(source.get_handle())
new_source.set_change_time(source.get_change_time())
new_source.set_data_map(source.get_data_map())
for repo_ref in source.get_reporef_list():
if repo_ref and not repo_ref.get_privacy():
@ -901,6 +921,7 @@ def sanitize_source(db, source):
if repo and not repo.get_privacy():
new_source.add_repo_reference(RepoRef(repo_ref))
copy_srcattributes(db, source, new_source)
copy_media_ref_list(db, source, new_source)
copy_notes(db, source, new_source)

View File

@ -784,6 +784,11 @@ class ProxyDbBase(DbReadBase):
Note instances in the database"""
return self.db.get_note_types()
def get_source_attribute_types(self):
"""returns a list of all Attribute types associated with Source/Citation
instances in the database"""
return self.db.get_source_attribute_types()
def get_source_media_types(self):
"""returns a list of all custom source media types associated with
Source instances in the database"""

View File

@ -152,6 +152,7 @@ class _DdTargets(object):
self.PERSONREF = _DdType(self, 'personref')
self.SOURCEREF = _DdType(self, 'srcref')
self.SOURCE_LINK = _DdType(self, 'source-link')
self.SRCATTRIBUTE = _DdType(self, 'sattr')
self.URL = _DdType(self, 'url')
self.SURNAME = _DdType(self, 'surname')
self.CITATION_LINK = _DdType(self, 'citation-link')
@ -181,6 +182,7 @@ class _DdTargets(object):
self.REPOREF,
self.SOURCEREF,
self.SOURCE_LINK,
self.SRCATTRIBUTE,
self.URL,
self.SURNAME,
self.CITATION_LINK

View File

@ -23,7 +23,7 @@
#
from .editaddress import EditAddress
from .editattribute import EditAttribute, EditFamilyAttribute
from .editattribute import EditAttribute, EditFamilyAttribute, EditSrcAttribute
from .editchildref import EditChildRef
from .editcitation import EditCitation, DeleteCitationQuery
from .editdate import EditDate

View File

@ -39,7 +39,6 @@ from .embeddedlist import EmbeddedList
from .addrembedlist import AddrEmbedList
from .attrembedlist import AttrEmbedList
from .backreflist import BackRefList
from .dataembedlist import DataEmbedList
from .eventbackreflist import EventBackRefList
from .eventembedlist import EventEmbedList
from .familyattrembedlist import FamilyAttrEmbedList
@ -60,4 +59,5 @@ from .placebackreflist import PlaceBackRefList
from .repoembedlist import RepoEmbedList
from .surnametab import SurnameTab
from .sourcebackreflist import SourceBackRefList
from .srcattrembedlist import SrcAttrEmbedList
from .webembedlist import WebEmbedList

View File

@ -66,6 +66,12 @@ class AttrEmbedList(EmbeddedList):
]
def __init__(self, dbstate, uistate, track, data):
"""
Initialize the displaytab. The dbstate and uistate is needed
track is the list of parent windows
data is an attribute_list (as obtained by AttributeBase) to display and
edit
"""
self.data = data
EmbeddedList.__init__(self, dbstate, uistate, track, _('_Attributes'),
AttrModel, move_buttons=True)

View File

@ -1,132 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Python classes
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
#-------------------------------------------------------------------------
#
# GRAMPS classes
#
#-------------------------------------------------------------------------
from .datamodel import DataModel
from .embeddedlist import EmbeddedList
from gramps.gen.constfunc import cuni
#-------------------------------------------------------------------------
#
# DataEmbedList
#
#-------------------------------------------------------------------------
class DataEmbedList(EmbeddedList):
_HANDLE_COL = 0
_DND_TYPE = None
_MSG = {
'add' : _('Create and add a new data entry'),
'del' : _('Remove the existing data entry'),
'edit' : _('Edit the selected data entry'),
'up' : _('Move the selected data entry upwards'),
'down' : _('Move the selected data entry downwards'),
}
#index = column in model. Value =
# (name, sortcol in model, width, markup/text
_column_names = [
(_('Key'), 0, 150, 0, -1),
(_('Value'), 1, 250, 0, -1),
]
def __init__(self, dbstate, uistate, track, obj):
self.obj = obj
EmbeddedList.__init__(self, dbstate, uistate, track, _('_Data'),
DataModel, move_buttons=False)
def build_columns(self):
EmbeddedList.build_columns(self)
# Need to add attributes to renderers
# and connect renderers to the 'edited' signal
for colno in range(len(self.columns)):
for renderer in self.columns[colno].get_cells():
renderer.set_property('editable', not self.dbstate.db.readonly)
renderer.connect('edited',self.edit_inline,colno)
def get_data(self):
return self.obj.get_data_map()
def is_empty(self):
return len(self.model)==0
def _get_map_from_model(self):
new_map = {}
for idx in range(len(self.model)):
node = self.model.get_iter(idx)
key = cuni(self.model.get_value(node, 0))
value = cuni(self.model.get_value(node, 1))
if key.strip():
new_map[key] = value
return new_map
def update(self):
new_map = self._get_map_from_model()
self.obj.set_data_map(new_map)
self._set_label()
def column_order(self):
return ((1, 0), (1, 1))
def add_button_clicked(self, obj):
node = self.model.append(row=['',''])
self.selection.select_iter(node)
path = self.model.get_path(node)
self.tree.set_cursor_on_cell(path,
focus_column=self.columns[0],
focus_cell=None,
start_editing=True)
def del_button_clicked(self, obj):
(model, node) = self.selection.get_selected()
if node:
self.model.remove(node)
self.update()
def edit_inline(self, cell, path, new_text, data):
node = self.model.get_iter(path)
self.model.set_value(node,data, new_text)
self.update()
def edit_button_clicked(self, obj):
(model, node) = self.selection.get_selected()
if node:
path = self.model.get_path(node)
self.tree.set_cursor_on_cell(path,
focus_column=self.columns[0],
focus_cell=None,
start_editing=True)

View File

@ -1,49 +0,0 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# GTK libraries
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# GRAMPS classes
#
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#
# DataModel
#
#-------------------------------------------------------------------------
class DataModel(Gtk.ListStore):
def __init__(self, attr_list, db):
Gtk.ListStore.__init__(self, str, str)
self.db = db
for key,value in list(attr_list.items()):
self.append(row=[key,value])

View File

@ -0,0 +1,125 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Python classes
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gi.repository import GObject
#-------------------------------------------------------------------------
#
# GRAMPS classes
#
#-------------------------------------------------------------------------
from gramps.gen.lib import SrcAttribute
from gramps.gen.errors import WindowActiveError
from ...ddtargets import DdTargets
from .attrmodel import AttrModel
from .embeddedlist import EmbeddedList
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
class SrcAttrEmbedList(EmbeddedList):
_HANDLE_COL = 2
_DND_TYPE = DdTargets.SRCATTRIBUTE
_MSG = {
'add' : _('Create and add a new attribute'),
'del' : _('Remove the existing attribute'),
'edit' : _('Edit the selected attribute'),
'up' : _('Move the selected attribute upwards'),
'down' : _('Move the selected attribute downwards'),
}
#index = column in model. Value =
# (name, sortcol in model, width, markup/text, weigth_col
_column_names = [
(_('Type'), 0, 250, 0, -1),
(_('Value'), 1, 200, 0, -1),
]
def __init__(self, dbstate, uistate, track, data):
"""
Initialize the displaytab. The dbstate and uistate is needed
track is the list of parent windows
data is an srcattribute_list (as obtained by SrcAttributeBase) to
display and edit
"""
self.data = data
EmbeddedList.__init__(self, dbstate, uistate, track, _('_Attributes'),
AttrModel, move_buttons=True)
def get_editor(self):
from .. import EditSrcAttribute
return EditSrcAttribute
def get_user_values(self):
return self.dbstate.db.get_source_attribute_types()
def get_icon_name(self):
return 'gramps-attribute'
def get_data(self):
return self.data
def column_order(self):
return ((1, 0), (1, 1))
def add_button_clicked(self, obj):
pname = ''
attr = SrcAttribute()
try:
self.get_editor()(
self.dbstate, self.uistate, self.track, attr,
pname, self.get_user_values(), self.add_callback)
except WindowActiveError:
pass
def add_callback(self, name):
data = self.get_data()
data.append(name)
self.changed = True
self.rebuild()
GObject.idle_add(self.tree.scroll_to_cell, len(data)-1)
def edit_button_clicked(self, obj):
attr = self.get_selected()
if attr:
pname = ''
try:
self.get_editor()(
self.dbstate, self.uistate, self.track, attr,
pname, self.get_user_values(), self.edit_callback)
except WindowActiveError:
pass
def edit_callback(self, name):
self.changed = True
self.rebuild()

View File

@ -58,19 +58,22 @@ from ..widgets import MonitoredEntry, PrivacyButton, MonitoredDataType
# EditAttribute class
#
#-------------------------------------------------------------------------
class EditAttribute(EditSecondary):
class EditAttributeRoot(EditSecondary):
"""
Displays a dialog that allows the user to edit an attribute.
Root baseclass for the root Attribute data editor
"""
def __init__(self, state, uistate, track, attrib, title, data_list, callback):
"""
Displays the dialog box.
parent - The class that called the Address editor.
state - dbstate
uistate - the uistate
track - list of parent windows
attrib - The attribute that is to be edited
title - The title of the dialog box
list - list of options for the pop down menu
data_list - list of options for the pop down menu to help selection of a
attribute type
"""
self.alist = data_list
EditSecondary.__init__(self, state, uistate, track, attrib, callback)
@ -78,7 +81,7 @@ class EditAttribute(EditSecondary):
def _local_init(self):
self.width_key = 'interface.attribute-width'
self.height_key = 'interface.attribute-height'
self.top = Glade()
self.top = Glade('editattribute.glade')
self.set_window(self.top.toplevel,
self.top.get_object('title'),
@ -109,18 +112,6 @@ class EditAttribute(EditSecondary):
def _create_tabbed_pages(self):
notebook = Gtk.Notebook()
self.srcref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_citation_list())
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype = NoteType.ATTRIBUTE)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs( notebook)
notebook.show_all()
@ -153,6 +144,76 @@ class EditAttribute(EditSecondary):
self.callback(self.obj)
self.close()
#-------------------------------------------------------------------------
#
# EditSrcAttribute class
#
#-------------------------------------------------------------------------
class EditSrcAttribute(EditAttributeRoot):
"""
Source attribute are minimal attributes. This Displays the editor to
edit these.
"""
def __init__(self, state, uistate, track, attrib, title, data_list, callback):
"""
Displays the dialog box.
state - dbstate
uistate - the uistate
track - list of parent windows
attrib - The attribute that is to be edited
title - The title of the dialog box
data_list - list of options for the pop down menu to help selection of a
attribute type
"""
EditAttributeRoot.__init__(self, state, uistate, track, attrib, title,
data_list, callback)
#-------------------------------------------------------------------------
#
# EditAttribute class
#
#-------------------------------------------------------------------------
class EditAttribute(EditAttributeRoot):
"""
Displays a dialog that allows the user to edit an attribute.
"""
def __init__(self, state, uistate, track, attrib, title, data_list, callback):
"""
Displays the dialog box.
state - dbstate
uistate - the uistate
track - list of parent windows
attrib - The attribute that is to be edited
title - The title of the dialog box
data_list - list of options for the pop down menu to help selection of a
attribute type
"""
EditAttributeRoot.__init__(self, state, uistate, track, attrib, title,
data_list, callback)
def _create_tabbed_pages(self):
notebook = Gtk.Notebook()
self.srcref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_citation_list())
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype = NoteType.ATTRIBUTE)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs( notebook)
notebook.show_all()
self.top.get_object('vbox').pack_start(notebook, True, True, 0)
#-------------------------------------------------------------------------
#
# EditFamilyAttribute class

View File

@ -45,7 +45,7 @@ from gramps.gen.lib import Citation, NoteType, Source
from gramps.gen.db import DbTxn
from .editprimary import EditPrimary
from .displaytabs import (NoteTab, GalleryTab, DataEmbedList,
from .displaytabs import (NoteTab, GalleryTab, SrcAttrEmbedList,
SourceBackRefList, RepoEmbedList, CitationBackRefList)
from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredMenu,
MonitoredDate, MonitoredTagList)
@ -347,10 +347,10 @@ class EditCitation(EditPrimary):
self._add_tab(notebook_ref, self.gallery_tab)
self.track_ref_for_deletion("gallery_tab")
self.data_tab = DataEmbedList(self.dbstate, self.uistate, self.track,
self.obj)
self._add_tab(notebook_ref, self.data_tab)
self.track_ref_for_deletion("data_tab")
self.attr_tab = SrcAttrEmbedList(self.dbstate, self.uistate, self.track,
self.obj.get_attribute_list())
self._add_tab(notebook_ref, self.attr_tab)
self.track_ref_for_deletion("attr_tab")
self.citationref_list = CitationBackRefList(self.dbstate, self.uistate,
self.track,
@ -377,10 +377,10 @@ class EditCitation(EditPrimary):
self._add_tab(notebook_src, self.gallery_tab)
self.track_ref_for_deletion("gallery_tab")
self.data_tab = DataEmbedList(self.dbstate, self.uistate, self.track,
self.source)
self._add_tab(notebook_src, self.data_tab)
self.track_ref_for_deletion("data_tab")
self.sattr_tab = SrcAttrEmbedList(self.dbstate, self.uistate, self.track,
self.source.get_attribute_list())
self._add_tab(notebook_src, self.sattr_tab)
self.track_ref_for_deletion("sattr_tab")
self.repo_tab = RepoEmbedList(self.dbstate, self.uistate, self.track,
self.source.get_reporef_list())

View File

@ -49,7 +49,7 @@ from gramps.gen.lib import NoteType, Source
from gramps.gen.db import DbTxn
from .editprimary import EditPrimary
from .displaytabs import (NoteTab, GalleryTab, DataEmbedList,
from .displaytabs import (NoteTab, GalleryTab, SrcAttrEmbedList,
CitationBackRefList, RepoEmbedList)
from ..widgets import MonitoredEntry, PrivacyButton, MonitoredTagList
from ..dialog import ErrorDialog
@ -155,12 +155,12 @@ class EditSource(EditPrimary):
self._add_tab(notebook, self.gallery_tab)
self.track_ref_for_deletion("gallery_tab")
self.data_tab = DataEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj)
self._add_tab(notebook, self.data_tab)
self.track_ref_for_deletion("data_tab")
self.attr_tab = SrcAttrEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_attribute_list())
self._add_tab(notebook, self.attr_tab)
self.track_ref_for_deletion("attr_tab")
self.repo_tab = RepoEmbedList(self.dbstate,
self.uistate,

View File

@ -663,8 +663,8 @@ class GedcomWriter(UpdateCallback):
"""
for addr in person.get_address_list():
self._writeln(1, 'RESI')
self.__date(2, addr.get_date_object())
self._write_addr(2, addr)
self._date(2, addr.get_date_object())
self.__write_addr(2, addr)
if addr.get_phone():
self._writeln(2, 'PHON', addr.get_phone())
@ -1307,13 +1307,18 @@ class GedcomWriter(UpdateCallback):
if n and n.get_type() != NoteType.SOURCE_TEXT]
self._note_references(note_list, level+1)
self._photos(citation.get_media_list(), level+1)
if "EVEN" in list(citation.get_data_map().keys()):
self._writeln(level+1, "EVEN", citation.get_data_map()["EVEN"])
if "EVEN:ROLE" in list(citation.get_data_map().keys()):
self._writeln(level+2, "ROLE",
citation.get_data_map()["EVEN:ROLE"])
even = None
for srcattr in citation.get_attribute_list():
if srcattr.type == SrcAttributeType.EVEN_CITED:
even = srcattr.value
self._writeln(level+1, "EVEN", even)
break
if even:
for srcattr in citation.get_attribute_list():
if srcattr.type == SrcAttributeType.EVEN_ROLE:
self._writeln(level+2, "ROLE", srcattr.value)
break
def _photo(self, photo, level):
"""

View File

@ -8,6 +8,7 @@
# Copyright (C) 2009 Douglas S. Blank
# Copyright (C) 2010 Jakim Friant
# Copyright (C) 2010-2011 Nick Hall
# Copyright (C) 2013 Benny Malengier
#
# 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
@ -582,7 +583,7 @@ class GrampsXmlWriter(UpdateCallback):
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_srcattribute_list(citation.get_attribute_list(), index+1)
self.write_ref("sourceref", citation.get_reference_handle(), index+1)
for tag_handle in citation.get_tag_list():
@ -590,17 +591,17 @@ class GrampsXmlWriter(UpdateCallback):
self.g.write("%s</citation>\n" % sp)
def write_source(self,source,index=1):
def write_source(self, source, index=1):
sp = " "*index
self.write_primary_tag("source",source,index)
self.write_force_line("stitle",source.get_title(),index+1)
self.write_line("sauthor",source.get_author(),index+1)
self.write_line("spubinfo",source.get_publication_info(),index+1)
self.write_line("sabbrev",source.get_abbreviation(),index+1)
self.write_note_list(source.get_note_list(),index+1)
self.write_media_list(source.get_media_list(),index+1)
self.write_data_map(source.get_data_map())
self.write_reporef_list(source.get_reporef_list(),index+1)
self.write_primary_tag("source", source, index)
self.write_force_line("stitle", source.get_title(), index+1)
self.write_line("sauthor", source.get_author(), index+1)
self.write_line("spubinfo", source.get_publication_info(), index+1)
self.write_line("sabbrev", source.get_abbreviation(), index+1)
self.write_note_list(source.get_note_list(), index+1)
self.write_media_list(source.get_media_list(), index+1)
self.write_srcattribute_list(source.get_attribute_list(), index+1)
self.write_reporef_list(source.get_reporef_list(), index+1)
for tag_handle in source.get_tag_list():
self.write_ref("tagref", tag_handle, index+1)
@ -1063,6 +1064,15 @@ class GrampsXmlWriter(UpdateCallback):
self.write_note_list(attr.get_note_list(),indent+1)
self.g.write('%s</attribute>\n' % sp)
def write_srcattribute_list(self, list, indent=3):
sp = ' ' * indent
for srcattr in list:
self.g.write('%s<srcattribute%s type="%s" value="%s"' %
(sp, conf_priv(srcattr), escxml(srcattr.get_type().xml_str()),
self.fix(srcattr.get_value()))
)
self.g.write('/>\n')
def write_media_list(self,list,indent=3):
sp = ' '*indent
for photo in list:
@ -1109,15 +1119,6 @@ class GrampsXmlWriter(UpdateCallback):
self.write_note_list(nreflist, indent+1)
self.g.write('%s</objref>\n' % sp)
def write_data_map(self,datamap,indent=3):
if len(datamap) == 0:
return
sp = ' '*indent
for key in list(datamap.keys()):
self.g.write('%s<data_item key="%s" value="%s"/>\n' %
(sp,self.fix(key), self.fix(datamap[key])))
def write_reporef_list(self, rrlist, index=1):
for reporef in rrlist:
if not reporef or not reporef.ref:

View File

@ -619,7 +619,10 @@ class ProgenParser(object):
citation = Citation()
citation.set_reference_handle(source.get_handle())
if aktenr:
citation.set_data_item("REFN", aktenr)
sattr = SrcAttribute()
sattr.set_type("REFN")
sattr.set_value(aktenr)
citation.add_attribute(sattr)
if source_text:
note = Note()
note_type = NoteType()

View File

@ -2,6 +2,7 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 200?-2013 Benny Malengier
# Copyright (C) 2009 Douglas S. Blank
# Copyright (C) 2010-2011 Nick Hall
# Copyright (C) 2011 Michiel D. Nauta
@ -52,6 +53,7 @@ from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef,
MediaObject, MediaRef, Name, NameOriginType,
NameType, Note, NoteType, Person, PersonRef,
Place, RepoRef, Repository, Researcher, Source,
SrcAttribute, SrcAttributeType,
StyledText, StyledTextTag, StyledTextTagType,
Surname, Tag, Url)
from gramps.gen.db import DbTxn
@ -533,6 +535,7 @@ class GrampsParser(UpdateCallback):
self.in_old_sourceref = False
self.source = None
self.attribute = None
self.srcattribute = None
self.placeobj = None
self.locations = 0
self.place_map = {}
@ -622,6 +625,7 @@ class GrampsParser(UpdateCallback):
"attribute": (self.start_attribute, self.stop_attribute),
"attr_type": (None, self.stop_attr_type),
"attr_value": (None, self.stop_attr_value),
"srcattribute": (self.start_srcattribute, self.stop_srcattribute),
"bookmark": (self.start_bmark, None),
"bookmarks": (None, None),
"format": (self.start_format, None),
@ -648,7 +652,7 @@ class GrampsParser(UpdateCallback):
"type": (None, self.stop_type),
"witness": (self.start_witness, self.stop_witness),
"eventref": (self.start_eventref, self.stop_eventref),
"data_item": (self.start_data_item, None),
"data_item": (self.start_data_item, None), #deprecated in 1.6.0
"families": (None, self.stop_families),
"family": (self.start_family, self.stop_family),
"rel": (self.start_rel, None),
@ -1075,10 +1079,17 @@ class GrampsParser(UpdateCallback):
self.ord.set_temple(attrs['val'])
def start_data_item(self, attrs):
"""
Deprecated in 1.6.0, replaced by srcattribute
"""
sat = SrcAttributeType(attrs['key'])
sa = SrcAttribute()
sa.set_type(sat)
sa.set_value(attrs['value'])
if self.source:
self.source.set_data_item(attrs['key'], attrs['value'])
self.source.add_attribute(sa)
else:
self.citation.set_data_item(attrs['key'], attrs['value'])
self.citation.add_attribute(sa)
def start_status(self, attrs):
try:
@ -1306,6 +1317,18 @@ class GrampsParser(UpdateCallback):
elif self.family:
self.family.add_attribute(self.attribute)
def start_srcattribute(self, attrs):
self.srcattribute = SrcAttribute()
self.srcattribute.private = bool(attrs.get("priv"))
self.srcattribute.type = SrcAttributeType()
if 'type' in attrs:
self.srcattribute.type.set_from_xml_str(attrs["type"])
self.srcattribute.value = attrs.get("value", '')
if self.source:
self.source.add_attribute(self.srcattribute)
elif self.citation:
self.citation.add_attribute(self.srcattribute)
def start_address(self, attrs):
self.address = Address()
self.address.private = bool(attrs.get("priv"))
@ -2420,6 +2443,9 @@ class GrampsParser(UpdateCallback):
def stop_attribute(self, *tag):
self.attribute = None
def stop_srcattribute(self, *tag):
self.srcattribute = None
def stop_comment(self, tag):
# Parse witnesses created by older gramps
if tag.strip():

View File

@ -129,8 +129,9 @@ from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef,
ChildRefType, Citation, Date, Event, EventRef, EventRoleType,
EventType, Family, FamilyRelType, LdsOrd, Location, MediaObject,
MediaRef, Name, NameType, Note, NoteType, Person, PersonRef, Place,
RepoRef, Repository, RepositoryType, Researcher, Source, Tag,
SourceMediaType, Surname, Url, UrlType)
RepoRef, Repository, RepositoryType, Researcher,
Source, SourceMediaType, SrcAttribute, SrcAttributeType,
Surname, Tag, Url, UrlType)
from gramps.gen.db import DbTxn
from gramps.gen.updatecallback import UpdateCallback
from gramps.gen.mime import get_type
@ -5956,7 +5957,10 @@ class GedcomParser(UpdateCallback):
@param state: The current state
@type state: CurrentState
"""
state.citation.set_data_item("EVEN", line.data)
sattr = SrcAttribute()
sattr.set_type(SrcAttributeType.EVEN_CITED)
sattr.set_value(line.data)
state.citation.add_attribute(sattr)
sub_state = CurrentState(level=state.level+1)
sub_state.citation = state.citation
@ -5972,7 +5976,10 @@ class GedcomParser(UpdateCallback):
@param state: The current state
@type state: CurrentState
"""
state.citation.set_data_item("EVEN:ROLE", line.data)
sattr = SrcAttribute()
sattr.set_type(SrcAttributeType.EVEN_ROLE)
sattr.set_value(line.data)
state.citation.add_attribute(sattr)
def __citation_quay(self, line, state):
"""
@ -6054,7 +6061,10 @@ class GedcomParser(UpdateCallback):
@param state: The current state
@type state: CurrentState
"""
state.source.set_data_item(line.token_text, line.data)
sattr = SrcAttribute()
sattr.set_type(line.token_text)
sattr.set_value(line.data)
state.source.add_attribute(sattr)
def __source_object(self, line, state):
"""
@ -6724,8 +6734,10 @@ class GedcomParser(UpdateCallback):
# software, in case we do not get the name in the proper place
self.genby = line.data
if self.use_def_src:
self.def_src.set_data_item(_("Approved system identification"),
"%s" % self.genby)
sattr = SrcAttribute()
sattr.set_type(_("Approved system identification"))
sattr.set_value("%s" % self.genby)
self.def_src.add_attribute(sattr)
sub_state = CurrentState(level=state.level+1)
self.__parse_level(sub_state, self.header_sour_parse_tbl,
self.__undefined)
@ -6734,8 +6746,10 @@ class GedcomParser(UpdateCallback):
# level, because the name and version may come in any order
if self.use_def_src:
# feature request 2356: avoid genitive form
self.def_src.set_data_item(_("Generated by"), "%s %s" %
(self.genby, self.genvers))
sattr = SrcAttribute()
sattr.set_type(SrcAttributeType.GEN_BY)
sattr.set_value("%s %s" % (self.genby, self.genvers))
self.def_src.add_attribute(sattr)
def __header_sour_name(self, line, state):
"""
@ -6748,8 +6762,10 @@ class GedcomParser(UpdateCallback):
# should appear, and this will overwrite the approved system ID (if any)
self.genby = line.data
if self.use_def_src:
self.def_src.set_data_item(_("Name of software product"),
self.genby)
sattr = SrcAttribute()
sattr.set_type(_("Name of software product"))
sattr.set_value(self.genby)
self.def_src.add_attribute(sattr)
def __header_sour_vers(self, line, state):
"""
@ -6760,8 +6776,10 @@ class GedcomParser(UpdateCallback):
"""
self.genvers = line.data
if self.use_def_src:
self.def_src.set_data_item(_("Version number of software product"),
self.genvers)
sattr = SrcAttribute()
sattr.set_type(_("Version number of software product"))
sattr.set_value(self.genvers)
self.source.add_attribute(sattr)
def __header_sour_corp(self, line, state):
"""
@ -6798,7 +6816,10 @@ class GedcomParser(UpdateCallback):
@type state: CurrentState
"""
if self.use_def_src:
self.def_src.set_data_item(_("Name of source data"), line.data)
sattr = SrcAttribute()
sattr.set_type(_("Name of source data"))
sattr.set_value(line.data)
self.def_src.add_attribute(sattr)
sub_state = CurrentState(level=state.level+1)
self.__parse_level(sub_state, self.header_sour_data,
self.__undefined)
@ -6812,8 +6833,11 @@ class GedcomParser(UpdateCallback):
@type state: CurrentState
"""
if self.use_def_src:
self.def_src.set_data_item(_("Copyright of source data"), line.data)
sattr = SrcAttribute()
sattr.set_type(_("Copyright of source data"))
sattr.set_value(line.data)
self.def_src.add_attribute(sattr)
def __header_sour_date(self, line, state):
"""
@param line: The current line in GedLine format
@ -6826,8 +6850,10 @@ class GedcomParser(UpdateCallback):
# to a Date object before getting to this point, so it has to be
# converted back to a string
text_date = str(line.data)
self.def_src.set_data_item(_("Publication date of source data"),
text_date)
sattr = SrcAttribute()
sattr.set_type(_("Publication date of source data"))
sattr.set_value(text_date)
self.def_src.add_attribute(sattr)
def __header_file(self, line, state):
"""
@ -6877,8 +6903,10 @@ class GedcomParser(UpdateCallback):
@type state: CurrentState
"""
if self.use_def_src:
self.def_src.set_data_item(_('Submission record identifier'),
line.token_text)
sattr = SrcAttribute()
sattr.set_type(_('Submission record identifier'))
sattr.set_value(line.token_text)
self.def_src.add_attribute(sattr)
def __header_lang(self, line, state):
"""
@ -6888,7 +6916,10 @@ class GedcomParser(UpdateCallback):
@type state: CurrentState
"""
if self.use_def_src:
self.def_src.set_data_item(_('Language of GEDCOM text'), line.data)
sattr = SrcAttribute()
sattr.set_type(_('Language of GEDCOM text'))
sattr.set_value(line.data)
self.def_src.add_attribute(sattr)
def __header_dest(self, line, state):
"""
@ -6938,11 +6969,16 @@ class GedcomParser(UpdateCallback):
if self.use_def_src:
if version == "":
self.def_src.set_data_item(_('Character set'), encoding)
sattr = SrcAttribute()
sattr.set_type(_('Character set'))
sattr.set_value(encoding)
self.def_src.add_attribute(sattr)
else:
self.def_src.set_data_item(_('Character set and version'),
"%s %s" % (encoding, version))
sattr = SrcAttribute()
sattr.set_type(_('Character set and version'))
sattr.set_value("%s %s" % (encoding, version))
self.def_src.add_attribute(sattr)
def __header_gedc(self, line, state):
"""
@param line: The current line in GedLine format
@ -6959,12 +6995,18 @@ class GedcomParser(UpdateCallback):
self.__add_msg(_("GEDCOM version not supported"),
line, state)
if self.use_def_src:
self.def_src.set_data_item(_('GEDCOM version'), line.data)
sattr = SrcAttribute()
sattr.set_type(_('GEDCOM version'))
sattr.set_value(line.data)
self.def_src.add_attribute(sattr)
elif line.token == TOKEN_FORM:
if line.data != "LINEAGE-LINKED":
self.__add_msg(_("GEDCOM form not supported"), line, state)
if self.use_def_src:
self.def_src.set_data_item(_('GEDCOM form'), line.data)
sattr = SrcAttribute()
sattr.set_type(_('GEDCOM form'))
sattr.set_value(line.data)
self.def_src.add_attribute(sattr)
def __header_plac(self, line, state):
"""
@ -7010,12 +7052,15 @@ class GedcomParser(UpdateCallback):
if self.use_def_src:
if tx_time == "":
self.def_src.set_data_item(_('Creation date of GEDCOM'),
tx_date)
sattr = SrcAttribute()
sattr.set_type(_('Creation date of GEDCOM'))
sattr.set_value(tx_date)
self.def_src.add_attribute(sattr)
else:
self.def_src.set_data_item(
_('Creation date and time of GEDCOM'),
"%s %s" % (tx_date, tx_time))
sattr = SrcAttribute()
sattr.set_type(_('Creation date and time of GEDCOM'))
sattr.set_value("%s %s" % (tx_date, tx_time))
self.def_src.add_attribute(sattr)
def __header_note(self, line, state):
"""
@ -7172,7 +7217,10 @@ class GedcomParser(UpdateCallback):
continue
if self.use_def_src and msg != "":
self.def_src.set_data_item(msg, line.data)
sattr = SrcAttribute()
sattr.set_type(msg)
sattr.set_value(line.data)
self.def_src.add_attribute(sattr)
def handle_source(self, line, level, state):
"""

View File

@ -35,5 +35,5 @@
# Public Constants
#
#------------------------------------------------------------------------
GRAMPS_XML_VERSION = "1.6.0"
GRAMPS_XML_VERSION = "1.6.0" # version for Gramps 4.1

View File

@ -51,7 +51,13 @@ from gi.repository import Gtk
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import Address, Attribute, AttributeType, ChildRef, ChildRefType, Citation, Date, Event, EventRef, EventRoleType, EventType, Family, FamilyRelType, GrampsType, LdsOrd, Location, MediaObject, MediaRef, Name, NameOriginType, NameType, Note, NoteType, Person, PersonRef, Place, RepoRef, Repository, RepositoryType, Source, SourceMediaType, Surname, Tag, Url, UrlType
from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef,
ChildRefType, Citation, Date, Event, EventRef, EventRoleType,
EventType, Family, FamilyRelType, GrampsType, LdsOrd, Location,
MediaObject, MediaRef, Name, NameOriginType, NameType, Note, NoteType,
Person, PersonRef, Place, RepoRef, Repository, RepositoryType,
Source, SourceMediaType, SrcAttribute, SrcAttributeType,
Surname, Tag, Url, UrlType)
from gramps.gen.lib import StyledText, StyledTextTag, StyledTextTagType
from gramps.gen.db import DbTxn
from gramps.gen.mime import get_type
@ -356,7 +362,10 @@ class TestcaseGenerator(tool.BatchTool):
if randint(0,1) == 1:
o.set_abbreviation( self.rand_text(self.SHORT))
while randint(0,1) == 1:
o.set_data_item( self.rand_text(self.SHORT), self.rand_text(self.SHORT))
sattr = SrcAttribute()
sattr.set_type(self.rand_text(self.SHORT))
sattr.set_value(self.rand_text(self.SHORT))
o.add_attribute(sattr)
o.set_handle(handle)
self.db.add_source(o, self.trans)
print("object %s, handle %s, Gramps_Id %s" % (o, o.handle,
@ -1692,7 +1701,10 @@ class TestcaseGenerator(tool.BatchTool):
if randint(0,1) == 1:
o.set_abbreviation( self.rand_text(self.SHORT))
while randint(0,1) == 1:
o.set_data_item( self.rand_text(self.SHORT), self.rand_text(self.SHORT))
sattr = SrcAttribute()
sattr.set_type(self.rand_text(self.SHORT))
sattr.set_value(self.rand_text(self.SHORT))
o.add_attribute(sattr)
while randint(0,1) == 1:
r = RepoRef()
self.fill_object(r)

View File

@ -14,6 +14,7 @@
# Copyright (C) 2010 Jakim Friant
# Copyright (C) 2010 Serge Noiraud
# Copyright (C) 2011 Tim G L Lyons
# Copyright (C) 2013 Benny Malengier
#
# 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
@ -601,15 +602,6 @@ class BasePage(object):
def display_pages(self, *param):
pass
# for use in write_data_map()
def fix(self, line):
try:
l = cuni(line)
except:
l = conv_to_unicode(str(line),errors = 'replace')
l = l.strip().translate(strip_dict)
return html_escape(l)
def get_nav_menu_hyperlink(self, url_fname, nav_text):
"""
returns the navigation menu hyperlink
@ -867,7 +859,7 @@ class BasePage(object):
(self.dump_notes(attr.get_note_list()), "ColumnNotes"),
(self.get_citation_links(attr.get_citation_list()), "ColumnSources")
]
)
)
return trow
def get_citation_links(self, citation_handle_list):
@ -1294,16 +1286,16 @@ class BasePage(object):
tbody += trow
return table
def write_data_map(self, data_map):
def write_srcattr(self, srcattr_list):
"""
writes out the data map for the different objects
writes out the srcattr for the different objects
"""
if len(data_map) == 0:
if len(srcattr_list) == 0:
return None
# begin data map division and section title...
with Html("div", class_ = "subsection", id = "data_map") as section:
section += Html("h4", _("Data Map"), inline = True)
section += Html("h4", _("Attributes"), inline = True)
with Html("table", class_ = "infolist") as table:
section += table
@ -1320,10 +1312,10 @@ class BasePage(object):
tbody = Html("tbody")
table += tbody
for key in data_map.keys():
for srcattr in srcattr_list:
trow = Html("tr") + (
Html("td", self.fix(key), class_ = "ColumnAttribute", inline = True),
Html("td", self.fix(data_map[key]), class_ = "ColumnValue", inline = True)
Html("td", str(srcattr.get_type()), class_ = "ColumnAttribute", inline = True),
Html("td", srcattr.get_value(), class_ = "ColumnValue", inline = True)
)
tbody += trow
return section
@ -1581,7 +1573,7 @@ class BasePage(object):
tbody.extend(
self.dump_attribute(attr) for attr in attrlist
)
def write_footer(self):
"""
Will create and display the footer section of each page...
@ -4312,7 +4304,7 @@ class SourcePages(BasePage):
sourcedetail += sourcemedia
# Source Data Map...
src_data_map = self.write_data_map(source.get_data_map())
src_data_map = self.write_srcattr(source.get_attribute_list())
if src_data_map is not None:
sourcedetail += src_data_map