- update exportxml and importxml for templates,

- move TemplateElement into separate module,
- remove redundant srctemplatelist module,
- fix editsource so source attribute tab updates when template fields are input,
- fix importcsv so it uses map names defined in citeref module,

svn: r22880
This commit is contained in:
Tim G L Lyons 2013-08-19 22:31:52 +00:00
parent 367de337a4
commit 9037f827a5
12 changed files with 469 additions and 359 deletions

View File

@ -1859,6 +1859,11 @@ class DbBsddbRead(DbReadBase, Callback):
return self.metadata.get(b'mediapath', None) return self.metadata.get(b'mediapath', None)
return None return None
def set_GEDCOM_template_handle(self, handle):
"""Set the default GEDCOM template handle for database"""
if (self.metadata is not None) and (not self.readonly):
self.metadata[b'gedcom_template'] = handle
def find_backlink_handles(self, handle, include_classes=None): def find_backlink_handles(self, handle, include_classes=None):
""" """
Find all objects that hold a reference to the object handle. Find all objects that hold a reference to the object handle.

View File

@ -393,17 +393,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
txn.put(b'default', handle) txn.put(b'default', handle)
self.emit('home-person-changed') self.emit('home-person-changed')
@catch_db_error
def set_GEDCOM_template_handle(self, handle):
"""Set the handle of the GEDCOM template to the passed instance."""
#we store a byte string!
if isinstance(handle, UNITYPE):
handle = handle.encode('utf-8')
if not self.readonly:
# Start transaction
with BSDDBTxn(self.env, self.metadata) as txn:
txn.put(b'gedcom_template', handle)
@catch_db_error @catch_db_error
def get_default_person(self): def get_default_person(self):
"""Return the default Person of the database.""" """Return the default Person of the database."""
@ -416,6 +405,17 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
txn.put(b'default', None) txn.put(b'default', None)
return None return None
@catch_db_error
def set_GEDCOM_template_handle(self, handle):
"""Set the handle of the GEDCOM template to the passed instance."""
#we store a byte string!
if isinstance(handle, UNITYPE):
handle = handle.encode('utf-8')
if not self.readonly:
# Start transaction
with BSDDBTxn(self.env, self.metadata) as txn:
txn.put(b'gedcom_template', handle)
def set_mediapath(self, path): def set_mediapath(self, path):
"""Set the default media path for database, path should be utf-8.""" """Set the default media path for database, path should be utf-8."""
if self.metadata and not self.readonly: if self.metadata and not self.readonly:

View File

@ -79,6 +79,7 @@ from .markertype import MarkerType
from .nameorigintype import NameOriginType from .nameorigintype import NameOriginType
from .notetype import NoteType from .notetype import NoteType
from .styledtexttagtype import StyledTextTagType from .styledtexttagtype import StyledTextTagType
from .templateelement import TemplateElement
# Text # Text
from .styledtexttag import StyledTextTag from .styledtexttag import StyledTextTag

View File

@ -36,8 +36,6 @@ from .mediabase import MediaBase
from .notebase import NoteBase from .notebase import NoteBase
from .tagbase import TagBase from .tagbase import TagBase
from .srcattrbase import SrcAttributeBase from .srcattrbase import SrcAttributeBase
from .srctemplate import SrcTemplate
from .srctemplatelist import SrcTemplateList
from .reporef import RepoRef from .reporef import RepoRef
from .const import DIFFERENT, EQUAL, IDENTICAL from .const import DIFFERENT, EQUAL, IDENTICAL
from ..constfunc import cuni, deprecated from ..constfunc import cuni, deprecated

View File

@ -48,9 +48,9 @@ LOG = logging.getLogger('.template')
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from .tableobj import TableObject from .tableobj import TableObject
from .secondaryobj import SecondaryObject
from .handle import Handle from .handle import Handle
from ..constfunc import cuni from ..constfunc import cuni
from .templateelement import TemplateElement
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -224,191 +224,3 @@ class SrcTemplate(TableObject):
def add_template_element(self, template_element): def add_template_element(self, template_element):
self.template_element_list.append(template_element) self.template_element_list.append(template_element)
class TemplateElement(SecondaryObject):
"""
TemplateEelement class.
This class is for keeping information about each template-element.
TemplateElement:
- template_element_name - English name of the element exactly as it appears
in Yates e.g. [WRITER FIRST]
- name to be displayed in the user interface e.g. 'Name of the first
author'
- hint e.g. "Doe, D.P. & Cameron, E."
- tooltip e.g. "Give names in following form: 'FirstAuthorSurname, Given
Names & SecondAuthorSurname, Given Names'. Like this Gramps can parse the
name and shorten as needed."
- citation - True if this element appears in a citation (false for a source
element)
- short - True if this element is an optional short element
- short_alg - algorithm to shorten the field.
- list of Mappings - there would always be a GEDCOM mapping. Also we would
expect a CSL mapping
"""
def __init__(self, source=None):
"""
Create a new TemplateEelement instance, copying from the source if present.
"""
if source:
self.name = source.name
self.display = source.display
self.hint = source.hint
self.tooltip = source.tooltip
self.citation = source.citation
self.short - source.short
self.short_alg = source.short_alg
else:
self.name = ""
self.display = ""
self.hint = ""
self.tooltip = ""
self.citation = False
self.short = False
self.short_alg = ""
def serialize(self):
"""
Convert the object to a serialized tuple of data.
"""
return (self.name,
self.display,
self.hint,
self.tooltip,
self.citation,
self.short,
self.short_alg
)
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 {"name": cuni(self.name),
"display": cuni(self.display),
"hint": cuni(self.hint),
"tooltip": cuni(self.tooltip),
"citation": cuni(self.citation),
"short": cuni(self.short),
"short_alg": cuni(self.short_alg),
}
def unserialize(self, data):
"""
Convert a serialized tuple of data to an object.
"""
(self.name, self.display, self.hint, self.tooltip, self.citation,
self.short, self.short_alg) = data
return self
def get_name(self):
"""
Return the name for the Template element.
"""
return self.name
def set_name(self, name):
"""
Set the name for the Template element according to the given argument.
"""
self.name = name
def get_hint(self):
"""
Return the hint for the Template element.
"""
return self.hint
def set_hint(self, hint):
"""
Set the hint for the Template element according to the given argument.
"""
self.hint = hint
def get_display(self):
"""
Return the display form for the Template element.
"""
return self.display
def set_display(self, display):
"""
Set the display form for the Template element according to the given
argument.
"""
self.display = display
def get_tooltip(self):
"""
Return the tooltip for the Template element.
"""
return self.tooltip
def set_tooltip(self, tooltip):
"""
Set the tooltip for the Template element according to the given argument.
"""
self.tooltip = tooltip
def get_citation(self):
"""
Return the citation for the Template element.
"""
return self.citation
def set_citation(self, citation):
"""
Set the citation for the Template element according to the given argument.
"""
self.citation = citation
def get_short(self):
"""
Return the short for the Template element.
"""
return self.short
def set_short(self, short):
"""
Set the short for the Template element according to the given argument.
"""
self.short = short
def get_short_alg(self):
"""
Return the short_alg for the Template element.
"""
return self.short_alg
def set_short_alg(self, short_alg):
"""
Set the short_alg for the Template element according to the given argument.
"""
self.short_alg = short_alg

View File

@ -1,116 +0,0 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2013 Benny Malengier
# Copyright (C) 2013 Tim G L Lyons
#
# 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$
"""
SrcTemplateList class for GRAMPS.
"""
from __future__ import print_function
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import sys
#------------------------------------------------------------------------
#
# Set up logging
#
#------------------------------------------------------------------------
import logging
LOG = logging.getLogger('.template')
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
# Pattern from http://stackoverflow.com/questions/13789235/how-to-initialize-singleton-derived-object-once
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
# See http://stackoverflow.com/questions/17237857/python3-singleton-metaclass-
# method-not-working the syntax has changed
# http://mikewatkins.ca/2008/11/29/python-2-and-3-metaclasses/
# http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python/17840539
STL = Singleton('STL', (object, ), {})
class SrcTemplateList(STL):
"""
Manages a singleton list of the source templates.
This should be replaced by access to the database when the templates are
stored in the database.
I would expect the TemplateList object to contain a dictionary of Template
objects, with the template ID as a key. It needs a method to return a list
of keys, and another method to return the Template object for a given key.
In this way it would act like a database table.
"""
# __metaclass__ = Singleton
def __init__(self):
self.clear()
def clear(self):
self.template_list = {}
self.GEDCOM_handle = None
self.UNKNOWN_handle = None
def add_template(self, handle, template):
self.template_list[handle] = template
# def get_template_from_handle(self, handle):
# if handle in self.template_list:
# return self.template_list[handle]
# else:
# return self.template_list[self.get_UNKNOWN_handle()]
# def get_template_list(self):
# return self.template_list
#
# def template_defined(self, handle):
# if self.get_template_from_handle(handle) is None:
# return False
# else:
# return True
#
# def set_GEDCOM_handle(self, handle):
# self.GEDCOM_handle = handle
#
# def get_GEDCOM_handle(self):
# return self.GEDCOM_handle
#
# def set_UNKNOWN_handle(self, handle):
# self.UNKNOWN_handle = handle
#
# def get_UNKNOWN_handle(self):
# return self.UNKNOWN_handle

View File

@ -0,0 +1,244 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2013 Benny Malengier
# Copyright (C) 2013 Tim G L Lyons
#
# 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$
"""
SrcTemplate class for GRAMPS.
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from __future__ import print_function
#------------------------------------------------------------------------
#
# Set up logging
#
#------------------------------------------------------------------------
import logging
LOG = logging.getLogger('.template')
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from .secondaryobj import SecondaryObject
from ..constfunc import cuni
#-------------------------------------------------------------------------
#
# TemplateElement class
#
#-------------------------------------------------------------------------
class TemplateElement(SecondaryObject):
"""
TemplateEelement class.
This class is for keeping information about each template-element.
TemplateElement:
- template_element_name - English name of the element exactly as it appears
in Yates e.g. [WRITER FIRST]
- name to be displayed in the user interface e.g. 'Name of the first
author'
- hint e.g. "Doe, D.P. & Cameron, E."
- tooltip e.g. "Give names in following form: 'FirstAuthorSurname, Given
Names & SecondAuthorSurname, Given Names'. Like this Gramps can parse the
name and shorten as needed."
- citation - True if this element appears in a citation (false for a source
element)
- short - True if this element is an optional short element
- short_alg - algorithm to shorten the field.
- list of Mappings - there would always be a GEDCOM mapping. Also we would
expect a CSL mapping
"""
def __init__(self, source=None):
"""
Create a new TemplateEelement instance, copying from the source if present.
"""
if source:
self.name = source.name
self.display = source.display
self.hint = source.hint
self.tooltip = source.tooltip
self.citation = source.citation
self.short - source.short
self.short_alg = source.short_alg
else:
self.name = ""
self.display = ""
self.hint = ""
self.tooltip = ""
self.citation = False
self.short = False
self.short_alg = ""
def serialize(self):
"""
Convert the object to a serialized tuple of data.
"""
return (self.name,
self.display,
self.hint,
self.tooltip,
self.citation,
self.short,
self.short_alg
)
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 {"name": cuni(self.name),
"display": cuni(self.display),
"hint": cuni(self.hint),
"tooltip": cuni(self.tooltip),
"citation": cuni(self.citation),
"short": cuni(self.short),
"short_alg": cuni(self.short_alg),
}
def unserialize(self, data):
"""
Convert a serialized tuple of data to an object.
"""
(self.name, self.display, self.hint, self.tooltip, self.citation,
self.short, self.short_alg) = data
return self
def get_name(self):
"""
Return the name for the Template element.
"""
return self.name
def set_name(self, name):
"""
Set the name for the Template element according to the given argument.
"""
self.name = name
def get_hint(self):
"""
Return the hint for the Template element.
"""
return self.hint
def set_hint(self, hint):
"""
Set the hint for the Template element according to the given argument.
"""
self.hint = hint
def get_display(self):
"""
Return the display form for the Template element.
"""
return self.display
def set_display(self, display):
"""
Set the display form for the Template element according to the given
argument.
"""
self.display = display
def get_tooltip(self):
"""
Return the tooltip for the Template element.
"""
return self.tooltip
def set_tooltip(self, tooltip):
"""
Set the tooltip for the Template element according to the given argument.
"""
self.tooltip = tooltip
def get_citation(self):
"""
Return the citation for the Template element.
"""
return self.citation
def set_citation(self, citation):
"""
Set the citation for the Template element according to the given argument.
"""
self.citation = citation
def get_short(self):
"""
Return the short for the Template element.
"""
return self.short
def set_short(self, short):
"""
Set the short for the Template element according to the given argument.
"""
self.short = short
def get_short_alg(self):
"""
Return the short_alg for the Template element.
"""
return self.short_alg
def set_short_alg(self, short_alg):
"""
Set the short_alg for the Template element according to the given argument.
"""
self.short_alg = short_alg

View File

@ -89,7 +89,8 @@ class EditSource(EditPrimary):
self.db = dbstate.db self.db = dbstate.db
self.citation = citation self.citation = citation
self.template_tab = None self.template_tab = None
self.attr_tab = None self.citn_attr_tab = None
self.src_attr_tab = None
self.citation_loaded = True self.citation_loaded = True
if not source and not citation: if not source and not citation:
raise NotImplementedError raise NotImplementedError
@ -381,8 +382,10 @@ class EditSource(EditPrimary):
if templatechanged and self.tmplfields: if templatechanged and self.tmplfields:
#the citation template fields must be changed! #the citation template fields must be changed!
self.tmplfields.reset_template_fields(self.obj.get_template()) self.tmplfields.reset_template_fields(self.obj.get_template())
if self.attr_tab: if self.citn_attr_tab:
self.attr_tab.rebuild_callback() self.citn_attr_tab.rebuild_callback()
if self.src_attr_tab:
self.src_attr_tab.rebuild_callback()
self.update_attr() self.update_attr()
def callback_cite_changed(self): def callback_cite_changed(self):
@ -451,12 +454,12 @@ class EditSource(EditPrimary):
self._add_tab(notebook, self.repo_tab) self._add_tab(notebook, self.repo_tab)
self.track_ref_for_deletion("repo_tab") self.track_ref_for_deletion("repo_tab")
self.attr_tab = SrcAttrEmbedList(self.dbstate, self.src_attr_tab = SrcAttrEmbedList(self.dbstate,
self.uistate, self.uistate,
self.track, self.track,
self.obj.get_attribute_list()) self.obj.get_attribute_list())
self._add_tab(notebook, self.attr_tab) self._add_tab(notebook, self.src_attr_tab)
self.track_ref_for_deletion("attr_tab") self.track_ref_for_deletion("src_attr_tab")
self.citedin_tab = CitedInTab(self.dbstate, self.uistate, self.citedin_tab = CitedInTab(self.dbstate, self.uistate,
self.track, self.obj, self.cite_apply_callback, self.track, self.obj, self.cite_apply_callback,
@ -509,10 +512,10 @@ class EditSource(EditPrimary):
self._add_tab(notebook_ref, self.gallery_tab) self._add_tab(notebook_ref, self.gallery_tab)
self.track_ref_for_deletion("gallery_tab") self.track_ref_for_deletion("gallery_tab")
self.attr_tab = SrcAttrEmbedList(self.dbstate, self.uistate, self.track, self.citn_attr_tab = SrcAttrEmbedList(self.dbstate, self.uistate, self.track,
self.citation.get_attribute_list()) self.citation.get_attribute_list())
self._add_tab(notebook_ref, self.attr_tab) self._add_tab(notebook_ref, self.citn_attr_tab)
self.track_ref_for_deletion("attr_tab") self.track_ref_for_deletion("citn_attr_tab")
self.citationref_list = CitationBackRefList(self.dbstate, self.uistate, self.citationref_list = CitationBackRefList(self.dbstate, self.uistate,
self.track, self.track,
@ -837,7 +840,7 @@ class EditSource(EditPrimary):
#trigger update of the tab fields #trigger update of the tab fields
self.comment_tab.rebuild_callback(self.citation.get_note_list()) self.comment_tab.rebuild_callback(self.citation.get_note_list())
self.gallery_tab.rebuild_callback(self.citation.get_media_list()) self.gallery_tab.rebuild_callback(self.citation.get_media_list())
self.attr_tab.rebuild_callback(self.citation.get_attribute_list()) self.citn_attr_tab.rebuild_callback(self.citation.get_attribute_list())
self.citationref_list.rebuild_callback( self.citationref_list.rebuild_callback(
self.db.find_backlink_handles(self.citation.handle)) self.db.find_backlink_handles(self.citation.handle))

View File

@ -208,11 +208,12 @@ class GrampsXmlWriter(UpdateCallback):
repo_len = self.db.get_number_of_repositories() repo_len = self.db.get_number_of_repositories()
obj_len = self.db.get_number_of_media_objects() obj_len = self.db.get_number_of_media_objects()
note_len = self.db.get_number_of_notes() note_len = self.db.get_number_of_notes()
tag_len = self.db.get_number_of_tags() tag_len = self.db.get_number_of_tags()
template_len = self.db.get_number_of_templates()
total_steps = (person_len + family_len + event_len + citation_len + total_steps = (person_len + family_len + event_len + citation_len +
source_len + place_len + repo_len + obj_len + note_len + source_len + place_len + repo_len + obj_len + note_len +
tag_len tag_len + template_len
) )
self.set_total(total_steps) self.set_total(total_steps)
@ -256,6 +257,14 @@ class GrampsXmlWriter(UpdateCallback):
self.update() self.update()
self.g.write(" </tags>\n") self.g.write(" </tags>\n")
if template_len > 0:
self.g.write(" <SourceTemplates>\n")
for key in sorted(self.db.get_template_handles()):
template = self.db.get_template_from_handle(key)
self.write_template(template, 2)
self.update()
self.g.write(" </SourceTemplates>\n")
# Write primary objects # Write primary objects
if event_len > 0: if event_len > 0:
self.g.write(" <events>\n") self.g.write(" <events>\n")
@ -350,6 +359,9 @@ class GrampsXmlWriter(UpdateCallback):
mediapath= self.db.get_mediapath() mediapath= self.db.get_mediapath()
if mediapath is not None: if mediapath is not None:
self.write_line("mediapath", mediapath, 2) self.write_line("mediapath", mediapath, 2)
gedcom_handle = self.db.get_GEDCOM_template_handle()
if gedcom_handle is not None:
self.write_line("gedcom_template", gedcom_handle, 2)
def write_namemaps(self): def write_namemaps(self):
group_map = self.db.get_name_group_keys() group_map = self.db.get_name_group_keys()
@ -435,6 +447,22 @@ class GrampsXmlWriter(UpdateCallback):
self.g.write(' priority="%d"' % tag.get_priority()) self.g.write(' priority="%d"' % tag.get_priority())
self.g.write('/>\n') self.g.write('/>\n')
def write_template(self, template, index=2):
"""
Write a template definition.
"""
if not template:
return
sp = " "*index
self.write_template_tag('template', template, index)
self.write_force_line("tname", template.get_name(), index+1)
self.write_line("tdescription", template.get_descr(), index+1)
self.write_map_list(template.get_map_dict(), index+1)
self.write_te_list(template.get_template_element_list(), index+1)
self.g.write("%s</template>\n" % sp)
def fix(self,line): def fix(self,line):
try: try:
l = cuni(line) l = cuni(line)
@ -595,7 +623,7 @@ class GrampsXmlWriter(UpdateCallback):
sp = " "*index sp = " "*index
self.write_primary_tag("source", source, index) self.write_primary_tag("source", source, index)
self.write_force_line("sname", source.get_name(), index+1) self.write_force_line("sname", source.get_name(), index+1)
self.write_line("stemplate", source.get_template(), index+1) self.write_ref("stemplate", source.get_template(), index+1)
self.write_line("sabbrev", source.get_abbreviation(), index+1) self.write_line("sabbrev", source.get_abbreviation(), index+1)
self.write_note_list(source.get_note_list(), index+1) self.write_note_list(source.get_note_list(), index+1)
self.write_media_list(source.get_media_list(), index+1) self.write_media_list(source.get_media_list(), index+1)
@ -809,6 +837,25 @@ class GrampsXmlWriter(UpdateCallback):
if close: if close:
self.g.write('>\n') self.g.write('>\n')
def write_template_tag(self, templatename, obj, index=1, close=True):
"""
Write the template attributes common to all table objects.
"""
if not obj:
return
sp = " " * index
try:
change_text = ' change="%d"' % obj.get_change_time()
except:
change_text = ' change="%d"' % 0
handle_text = ' handle="_%s"' % obj.get_handle()
obj_text = '%s<%s' % (sp, templatename)
self.g.write(obj_text + handle_text + change_text)
if close:
self.g.write('>\n')
def write_family_handle(self,family,index=1): def write_family_handle(self,family,index=1):
sp = " "*index sp = " "*index
self.write_primary_tag('family',family,index) self.write_primary_tag('family',family,index)
@ -1174,6 +1221,27 @@ class GrampsXmlWriter(UpdateCallback):
) )
) )
def write_map_list(self, map_dict, indent=3):
sp = ' ' * indent
for (key, value) in list(map_dict.items()):
self.g.write('%s<tmap key="%s" value="%s"' %
(sp, escxml(key), self.fix(value))
)
self.g.write('/>\n')
def write_te_list(self, te_list, index=1):
sp = " "*index
for te in te_list:
self.g.write('%s<tefield type="text" citation="%s" short="%s" short_alg="%s" >\n' %
(sp, te.get_citation(), te.get_short(), te.get_short_alg())
)
self.write_line("tename", te.get_name(), index+1)
self.write_line("Display", te.get_display(), index+1)
self.write_line("Hint", te.get_hint(), index+1)
self.write_line("Tooltip", te.get_tooltip(), index+1)
self.g.write('%s</tefield>\n' % sp)
pass
def write_place_obj(self, place, index=1): def write_place_obj(self, place, index=1):
self.write_primary_tag("placeobj", place, index) self.write_primary_tag("placeobj", place, index)

View File

@ -55,7 +55,7 @@ from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef,
Place, RepoRef, Repository, Researcher, Source, Place, RepoRef, Repository, Researcher, Source,
SrcAttribute, SrcAttributeType, SrcAttribute, SrcAttributeType,
StyledText, StyledTextTag, StyledTextTagType, StyledText, StyledTextTag, StyledTextTagType,
Surname, Tag, Url) Surname, Tag, Url, SrcTemplate, TemplateElement)
from gramps.gen.db import DbTxn from gramps.gen.db import DbTxn
from gramps.gen.db.write import CLASS_TO_KEY_MAP from gramps.gen.db.write import CLASS_TO_KEY_MAP
from gramps.gen.errors import GrampsImportError from gramps.gen.errors import GrampsImportError
@ -67,7 +67,7 @@ from gramps.gen.display.name import displayer as name_displayer
from gramps.gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY, from gramps.gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY,
EVENT_KEY, MEDIA_KEY, PLACE_KEY, EVENT_KEY, MEDIA_KEY, PLACE_KEY,
REPOSITORY_KEY, NOTE_KEY, TAG_KEY, REPOSITORY_KEY, NOTE_KEY, TAG_KEY,
CITATION_KEY) CITATION_KEY, TEMPLATE_KEY)
from gramps.gen.updatecallback import UpdateCallback from gramps.gen.updatecallback import UpdateCallback
from gramps.version import VERSION from gramps.version import VERSION
from gramps.gen.config import config from gramps.gen.config import config
@ -215,7 +215,8 @@ class ImportInfo(object):
Class object that can hold information about the import Class object that can hold information about the import
""" """
keyorder = [PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY, MEDIA_KEY, keyorder = [PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY, MEDIA_KEY,
PLACE_KEY, REPOSITORY_KEY, NOTE_KEY, TAG_KEY, CITATION_KEY] PLACE_KEY, REPOSITORY_KEY, NOTE_KEY, TAG_KEY, CITATION_KEY,
TEMPLATE_KEY]
key2data = { key2data = {
PERSON_KEY : 0, PERSON_KEY : 0,
FAMILY_KEY : 1, FAMILY_KEY : 1,
@ -226,7 +227,8 @@ class ImportInfo(object):
REPOSITORY_KEY: 6, REPOSITORY_KEY: 6,
NOTE_KEY: 7, NOTE_KEY: 7,
TAG_KEY: 8, TAG_KEY: 8,
CITATION_KEY: 9 CITATION_KEY: 9,
TEMPLATE_KEY: 10
} }
def __init__(self): def __init__(self):
@ -235,9 +237,9 @@ class ImportInfo(object):
This creates the datastructures to hold info This creates the datastructures to hold info
""" """
self.data_mergecandidate = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}] self.data_mergecandidate = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
self.data_newobject = [0] * 10 self.data_newobject = [0] * 11
self.data_unknownobject = [0] * 10 self.data_unknownobject = [0] * 11
self.data_families = '' self.data_families = ''
self.expl_note = '' self.expl_note = ''
self.data_relpath = False self.data_relpath = False
@ -315,6 +317,7 @@ class ImportInfo(object):
NOTE_KEY : _(' Notes: %d\n'), NOTE_KEY : _(' Notes: %d\n'),
TAG_KEY : _(' Tags: %d\n'), TAG_KEY : _(' Tags: %d\n'),
CITATION_KEY : _(' Citations: %d\n'), CITATION_KEY : _(' Citations: %d\n'),
TEMPLATE_KEY : _(' Source Templates; %d\n'),
} }
txt = _("Number of new objects imported:\n") txt = _("Number of new objects imported:\n")
for key in self.keyorder: for key in self.keyorder:
@ -537,6 +540,7 @@ class GrampsParser(UpdateCallback):
self.attribute = None self.attribute = None
self.srcattribute = None self.srcattribute = None
self.placeobj = None self.placeobj = None
self.template = None
self.locations = 0 self.locations = 0
self.place_map = {} self.place_map = {}
@ -708,18 +712,28 @@ class GrampsParser(UpdateCallback):
"source": (self.start_source, self.stop_source), "source": (self.start_source, self.stop_source),
"sourceref": (self.start_sourceref, self.stop_sourceref), "sourceref": (self.start_sourceref, self.stop_sourceref),
"sources": (None, None), "sources": (None, None),
"SourceTemplates": (None, None),
"spage": (None, self.stop_spage), #deprecated "spage": (None, self.stop_spage), #deprecated
"spubinfo": (None, self.stop_spubinfo), #deprecated in 1.6.0 "spubinfo": (None, self.stop_spubinfo), #deprecated in 1.6.0
"state": (None, self.stop_state), "state": (None, self.stop_state),
"stext": (None, self.stop_stext), "stext": (None, self.stop_stext),
"stitle": (None, self.stop_stitle), #deprecated in 1.6.0 "stitle": (None, self.stop_stitle), #deprecated in 1.6.0
"sname": (None, self.stop_sname), #new in 1.6.0 "sname": (None, self.stop_sname), #new in 1.6.0
"stemplate": (None, self.stop_stemplate), #new in 1.6.0 "stemplate": (self.start_stemplate, None), #new in 1.6.0
"street": (None, self.stop_street), "street": (None, self.stop_street),
"style": (self.start_style, None), "style": (self.start_style, None),
"tag": (self.start_tag, self.stop_tag), "tag": (self.start_tag, self.stop_tag),
"tagref": (self.start_tagref, None), "tagref": (self.start_tagref, None),
"tags": (None, None), "tags": (None, None),
"tdescription": (None, self.stop_tdescription),
"tefield": (self.start_tefield, self.stop_tefield),
"tename": (None, self.stop_tename),
"tedisplay": (None, self.stop_tedisplay),
"tehint": (None, self.stop_tehint),
"tetooltip": (None, self.stop_tetooltip),
"template": (self.start_template, self.stop_template),
"tmap": (self.start_tmap, None),
"tname": (None, self.stop_tname), # Template name
"text": (None, self.stop_text), "text": (None, self.stop_text),
"url": (self.start_url, None), "url": (self.start_url, None),
"repository": (self.start_repo, self.stop_repo), "repository": (self.start_repo, self.stop_repo),
@ -767,7 +781,8 @@ class GrampsParser(UpdateCallback):
"repository": self.db.get_raw_repository_data, "repository": self.db.get_raw_repository_data,
"media": self.db.get_raw_object_data, "media": self.db.get_raw_object_data,
"note": self.db.get_raw_note_data, "note": self.db.get_raw_note_data,
"tag": self.db.get_raw_tag_data}[target] "tag": self.db.get_raw_tag_data,
"template": self.db.get_raw_template_data}[target]
raw = get_raw_obj_data(handle) raw = get_raw_obj_data(handle)
prim_obj.unserialize(raw) prim_obj.unserialize(raw)
self.import_handles[orig_handle][target][INSTANTIATED] = True self.import_handles[orig_handle][target][INSTANTIATED] = True
@ -795,7 +810,8 @@ class GrampsParser(UpdateCallback):
"repository": self.db.has_repository_handle, "repository": self.db.has_repository_handle,
"media": self.db.has_object_handle, "media": self.db.has_object_handle,
"note": self.db.has_note_handle, "note": self.db.has_note_handle,
"tag": self.db.has_tag_handle}[target] "tag": self.db.has_tag_handle,
"template": self.db.has_template_handle}[target]
while has_handle_func(handle): while has_handle_func(handle):
handle = create_id() handle = create_id()
self.import_handles[orig_handle] = {target: [handle, False]} self.import_handles[orig_handle] = {target: [handle, False]}
@ -806,6 +822,8 @@ class GrampsParser(UpdateCallback):
prim_obj.set_handle(handle) prim_obj.set_handle(handle)
if target == "tag": if target == "tag":
self.db.add_tag(prim_obj, self.trans) self.db.add_tag(prim_obj, self.trans)
elif target == "template":
self.db.add_template(prim_obj, self.trans)
else: else:
add_func = {"person": self.db.add_person, add_func = {"person": self.db.add_person,
"family": self.db.add_family, "family": self.db.add_family,
@ -1807,6 +1825,68 @@ class GrampsParser(UpdateCallback):
self.note_tags[-1].ranges.append((int(attrs['start']), self.note_tags[-1].ranges.append((int(attrs['start']),
int(attrs['end']))) int(attrs['end'])))
def start_template(self, attrs):
"""
Template definition.
"""
# Tag defintion
self.template = SrcTemplate()
self.inaugurate(attrs['handle'], "template", self.template)
self.template.change = int(attrs.get('change', self.change))
self.info.add('new-object', TEMPLATE_KEY, self.template)
self.template.set_name(attrs.get('tname', _('Unknown when imported')))
self.template.set_descr(attrs.get('tdescription', _('Unknown when imported')))
return self.template
def stop_template(self, *tag):
self.db.commit_template(self.template, self.trans, self.template.get_change_time())
self.template = None
def stop_tname(self, tag):
self.template.set_name(tag)
def stop_tdescription(self, tag):
self.template.set_descr(tag)
def start_tmap(self, attrs):
self.template.set_map_element(attrs["key"], attrs["value"])
@staticmethod
def _conv_bool(val, default):
"""
Converts a string attribute to True or False. If the attribute is absent
(val is None) the default value is returned. If the value is "True" then
True is returned and vice-versa for False
"""
if val is None:
return default
if val == "True":
return True
else:
return False
def start_tefield(self, attrs):
self.template_element = TemplateElement()
self.template_element.set_citation(self._conv_bool(attrs.get("citation"), False))
self.template_element.set_short(self._conv_bool(attrs.get("short"), False))
self.template_element.set_short_alg(attrs.get("short_alg", None))
def stop_tename(self, tag):
self.template_element.set_name(tag)
def stop_tedisplay(self, tag):
self.template_element.set_display(tag)
def stop_tehint(self, tag):
self.template_element.set_hint(tag)
def stop_tetooltip(self, tag):
self.template_element.set_tooltip(tag)
def stop_tefield(self, tag):
self.template.add_template_element(self.template_element)
self.template_element = None
def start_note(self, attrs): def start_note(self, attrs):
""" """
Add a note to db if it doesn't exist yet and assign Add a note to db if it doesn't exist yet and assign
@ -2083,6 +2163,7 @@ class GrampsParser(UpdateCallback):
self.inaugurate_id(attrs.get('id'), SOURCE_KEY, self.source) self.inaugurate_id(attrs.get('id'), SOURCE_KEY, self.source)
self.source.private = bool(attrs.get("priv")) self.source.private = bool(attrs.get("priv"))
self.source.change = int(attrs.get('change', self.change)) self.source.change = int(attrs.get('change', self.change))
self.source.template = None
self.info.add('new-object', SOURCE_KEY, self.source) self.info.add('new-object', SOURCE_KEY, self.source)
return self.source return self.source
@ -2732,10 +2813,13 @@ class GrampsParser(UpdateCallback):
#store descriptive name of the source #store descriptive name of the source
self.source.name = tag self.source.name = tag
def stop_stemplate(self, tag): def start_stemplate(self, attrs):
#store template of the source """
self.source.template = tag Add a template reference to the source object currently being processed
"""
handle = self.inaugurate(attrs['hlink'], "template", SrcTemplate)
self.source.set_template(handle)
def stop_stitle(self, tag): def stop_stitle(self, tag):
#title was deprecated and converted to name and attribute TITLE in 1.6.0 #title was deprecated and converted to name and attribute TITLE in 1.6.0
if not self.source.name: if not self.source.name:
@ -2754,6 +2838,18 @@ class GrampsParser(UpdateCallback):
self.in_old_sourceref = False self.in_old_sourceref = False
def stop_source(self, *tag): def stop_source(self, *tag):
# Template are new at 1.6.0. Prior to 1.6.0, sources (and citations) wll
# be GEDCOM style, so the template needs to be set to GEDCOM - if the
# GEDCOM template has not alraedy been defined, it needs to be built.
if self.__xml_version < '1.6.0':
gedcom_handle = self.db.get_GEDCOM_template_handle()
if gedcom_handle is None:
from gramps.plugins.srctemplates.gedcomtemplate import load_template
load_template(self.db)
gedcom_handle = self.db.get_GEDCOM_template_handle()
self.source.set_template(gedcom_handle)
# From xml version 1.6.0, if the template is None, this is intentional,
# and there is no template defined.
self.db.commit_source(self.source, self.trans, self.db.commit_source(self.source, self.trans,
self.source.get_change_time()) self.source.get_change_time())
self.source = None self.source = None

View File

@ -47,7 +47,8 @@ _ = glocale.translation.gettext
from gramps.gen.db import DbTxn from gramps.gen.db import DbTxn
from gramps.gen.utils.id import create_id from gramps.gen.utils.id import create_id
from gramps.gen.lib.srctemplate import SrcTemplate, TemplateElement from gramps.gen.lib.srctemplate import SrcTemplate
from gramps.gen.lib.templateelement import TemplateElement
from gramps.gen.utils.citeref import (REF_TYPE_L, REF_TYPE_S, REF_TYPE_F, from gramps.gen.utils.citeref import (REF_TYPE_L, REF_TYPE_S, REF_TYPE_F,
GED_TITLE, GED_AUTHOR, GED_PUBINF, GED_TITLE, GED_AUTHOR, GED_PUBINF,
GED_DATE, GED_PAGE) GED_DATE, GED_PAGE)

View File

@ -48,7 +48,8 @@ from gramps.gen.db import DbTxn
from gramps.gen.utils.id import create_id from gramps.gen.utils.id import create_id
from gramps.gen.lib.srcattrtype import * from gramps.gen.lib.srcattrtype import *
from gramps.gen.lib.date import Date from gramps.gen.lib.date import Date
from gramps.gen.lib.srctemplate import SrcTemplate, TemplateElement from gramps.gen.lib.srctemplate import SrcTemplate
from gramps.gen.lib.templateelement import TemplateElement
from gramps.gen.utils.citeref import (REF_TYPE_L, REF_TYPE_S, REF_TYPE_F, from gramps.gen.utils.citeref import (REF_TYPE_L, REF_TYPE_S, REF_TYPE_F,
GED_TITLE, GED_AUTHOR, GED_PUBINF, GED_TITLE, GED_AUTHOR, GED_PUBINF,
GED_DATE, GED_PAGE) GED_DATE, GED_PAGE)
@ -335,7 +336,7 @@ def load_srctemplate_csv(csvfile, db):
optional = True optional = True
shorteralg = SHORTERALG.get(row[SHORTERCOL].strip()) or EMPTY shorteralg = SHORTERALG.get(row[SHORTERCOL].strip()) or EMPTY
gedcom_type_text = row[GEDCOMCOL].strip() gedcom_type_text = row[GEDCOMCOL].strip()
gedcommap = GEDCOMFIELDS.get(row[GEDCOMCOL].strip()) or EMPTY gedcommap = GEDCOMFIELDS.get(row[GEDCOMCOL].strip())
style = STYLES.get(row[STYLECOL].strip()) or EMPTY style = STYLES.get(row[STYLECOL].strip()) or EMPTY
if source_type in TYPE2TEMPLATEMAP: if source_type in TYPE2TEMPLATEMAP:
@ -376,7 +377,6 @@ def load_srctemplate_csv(csvfile, db):
# Setup the mapping. A typical mapping would look like: # Setup the mapping. A typical mapping would look like:
# ('EE_Full' : '%(COMPILER)s, "%(TITLE)s", %(TYPE)s, %(WEBSITE CREATOR/OWNER)s, <i>%(WEBSITE)s</i>, (%(URL (DIGITAL LOCATION))s: accessed %(DATE ACCESSED)s), %(ITEM OF INTEREST)s; %(CREDIT LINE)s.') # ('EE_Full' : '%(COMPILER)s, "%(TITLE)s", %(TYPE)s, %(WEBSITE CREATOR/OWNER)s, <i>%(WEBSITE)s</i>, (%(URL (DIGITAL LOCATION))s: accessed %(DATE ACCESSED)s), %(ITEM OF INTEREST)s; %(CREDIT LINE)s.')
target = "EE_" + cite_type_text
if te.get_short(): if te.get_short():
if field_type.lower().endswith(' (short)'): if field_type.lower().endswith(' (short)'):
txt = field_type txt = field_type
@ -392,8 +392,8 @@ def load_srctemplate_csv(csvfile, db):
if style == STYLE_QUOTE: if style == STYLE_QUOTE:
txt = '"' + txt + '"' txt = '"' + txt + '"'
elif style == STYLE_QUOTECONT: elif style == STYLE_QUOTECONT:
if template.get_map_element(target)[-1] == '"': if template.get_map_element(cite_type)[-1] == '"':
template.set_map_element(target, template.get_map_element(target)[:-1]) template.set_map_element(cite_type, template.get_map_element(cite_type)[:-1])
txt = txt + '"' txt = txt + '"'
else: else:
txt = '"' + txt + '"' txt = '"' + txt + '"'
@ -401,15 +401,14 @@ def load_srctemplate_csv(csvfile, db):
txt = "<i>" + txt + "</i>" txt = "<i>" + txt + "</i>"
elif style == STYLE_BOLD: elif style == STYLE_BOLD:
txt = "<b>" + txt + "</b>" txt = "<b>" + txt + "</b>"
template.set_map_element(target, template.get_map_element(target) + txt) template.set_map_element(cite_type, template.get_map_element(cite_type) + txt)
# Setup the GEDCOM fields. These are only stored in the L template # Setup the GEDCOM fields. These are only stored in the L template
if cite_type == REF_TYPE_L and gedcom_type_text: if cite_type == REF_TYPE_L and gedcom_type_text:
target = "GEDCOM_" + gedcom_type_text
if style == STYLE_QUOTECONT: if style == STYLE_QUOTECONT:
if template.get_map_element(target) and template.get_map_element(target)[-1] == '"': if template.get_map_element(gedcommap) and template.get_map_element(gedcommap)[-1] == '"':
template.set_map_element(target, template.get_map_element(target)[:-1]) template.set_map_element(gedcommap, template.get_map_element(gedcommap)[:-1])
template.set_map_element(target, template.get_map_element(target) + txt) template.set_map_element(gedcommap, template.get_map_element(gedcommap) + txt)
msg = _("Add template (%s)") % template.get_name() msg = _("Add template (%s)") % template.get_name()
with DbTxn(msg, db) as trans: with DbTxn(msg, db) as trans:
@ -455,9 +454,8 @@ def load_srctemplate_csv(csvfile, db):
template = TYPE2TEMPLATEMAP[source_type] template = TYPE2TEMPLATEMAP[source_type]
for te in [x for x in template.get_template_element_list() for te in [x for x in template.get_template_element_list()
if x.get_citation() and not x.get_short()]: if x.get_citation() and not x.get_short()]:
target = "GEDCOM_PAGE" template.set_map_element(GED_PAGE,
template.set_map_element(target, ", ".join((template.get_map_element(GED_PAGE), txt)))
", ".join((template.get_map_element(target), txt)))
msg = _("Add template (%s)") % template.get_name() msg = _("Add template (%s)") % template.get_name()
with DbTxn(msg, db) as trans: with DbTxn(msg, db) as trans:
db.commit_template(template, trans) db.commit_template(template, trans)