2006-05-01  Alex Roitman  <shura@gramps-project.org>
	* various: merge changes from gramps20.

In po:
2006-05-01  Alex Roitman  <shura@gramps-project.org>
	* POTFILES.in: Add new file.



svn: r6504
This commit is contained in:
Alex Roitman 2006-05-01 21:11:26 +00:00
parent bb9f7dc74d
commit 3fe3482efb
44 changed files with 2077 additions and 647 deletions

View File

@ -1,3 +1,6 @@
2006-05-01 Alex Roitman <shura@gramps-project.org>
* various: merge changes from gramps20.
2006-04-30 Alex Roitman <shura@gramps-project.org> 2006-04-30 Alex Roitman <shura@gramps-project.org>
* src/plugins/Verify.py (Verify.run_tool): Typo. * src/plugins/Verify.py (Verify.run_tool): Typo.

View File

@ -1,3 +1,6 @@
2006-05-01 Alex Roitman <shura@gramps-project.org>
* POTFILES.in: Add new file.
2006-04-27 Alex Roitman <shura@gramps-project.org> 2006-04-27 Alex Roitman <shura@gramps-project.org>
* pt_BR.po: Convert to utf8 encoding. * pt_BR.po: Convert to utf8 encoding.
* zh_CN.po: Convert to utf8 encoding. * zh_CN.po: Convert to utf8 encoding.

View File

@ -81,6 +81,7 @@ src/DateHandler/_Date_lt.py
src/DateHandler/_Date_nl.py src/DateHandler/_Date_nl.py
src/DateHandler/_DateParser.py src/DateHandler/_DateParser.py
src/DateHandler/_Date_ru.py src/DateHandler/_Date_ru.py
src/DateHandler/_Date_sk.py
src/DateHandler/_Date_sv.py src/DateHandler/_Date_sv.py
src/DateHandler/__init__.py src/DateHandler/__init__.py
src/docgen/AbiWord2Doc.py src/docgen/AbiWord2Doc.py
@ -218,6 +219,7 @@ src/plugins/rel_hu.py
src/plugins/rel_it.py src/plugins/rel_it.py
src/plugins/rel_no.py src/plugins/rel_no.py
src/plugins/rel_ru.py src/plugins/rel_ru.py
src/plugins/rel_sk.py
src/plugins/rel_sv.py src/plugins/rel_sv.py
src/plugins/ReorderIds.py src/plugins/ReorderIds.py
src/plugins/SimpleBookTitle.py src/plugins/SimpleBookTitle.py

216
po/check_po Executable file
View File

@ -0,0 +1,216 @@
#! /usr/bin/env python
#
# 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: check_po,v 1.1.2.6 2006/04/22 18:30:33 rshura Exp $
import sys
import re
f = open('template.po')
template_total = 0
for line in f.xreadlines():
try:
if (line.split()[0] == 'msgid'):
template_total += 1
except:
pass
f.close()
NONE = 0
MSGID = 1
MSGSTR = 2
all_total = {}
all_fuzzy = {}
all_untranslated = {}
all_percent_s = {}
all_named_s = {}
all_bnamed_s = {}
all_context = {}
all_coverage = {}
all_template_coverage = {}
def strip_quotes(st):
if len(st.strip()) > 2:
return st.strip()[1:-1]
else:
return ""
args = sys.argv
while len(args) > 1:
args = args[1:]
f = open(args[0],"r")
mode = NONE
fuzzy = False
fuzzy_count = 0
string_map = {}
current_msgid = ""
current_msgstr = ""
for line in f.xreadlines():
data = line.split(None,1)
if mode == NONE:
if len(data) > 0 and data[0] == "msgid":
mode = MSGID
if len(data) > 1:
current_msgid = strip_quotes(data[1])
elif (len(data) > 0) and (data[0] == "#,") \
and (data[1] == 'fuzzy\n'):
fuzzy = True
elif mode == MSGID:
if data[0][0] == '"':
current_msgid += strip_quotes(line)
elif data[0] == "msgstr":
mode = MSGSTR
if len(data) > 1:
current_msgstr = strip_quotes(data[1])
elif mode == MSGSTR:
if line == "" or line[0] == "#":
mode = NONE
if fuzzy:
fuzzy = False
fuzzy_count += 1
else:
string_map[current_msgid] = current_msgstr
elif len(data) > 0 and data[0][0] == '"':
current_msgstr += strip_quotes(line)
f.close()
named = re.compile('%\((\w+)\)\d*s')
bnamed = re.compile('%\((\w+)\)\d*[^sd]')
total = len(string_map) + fuzzy_count
untranslated = 0
percent_s = 0
percent_s_list = []
named_s = 0
named_s_list = []
bnamed_s = 0
bnamed_s_list = []
context = 0
context_list = []
for (msgid,msgstr) in string_map.items():
if msgstr == "":
untranslated += 1
continue
cnt1 = msgid.count('%s')
cnt2 = msgstr.count('%s')
if cnt1 != cnt2:
percent_s += 1
percent_s_list.append(msgid)
list1 = named.findall(msgid)
list2 = named.findall(msgstr)
if len(list1) != len(list2):
percent_s += 1
percent_s_list.append(msgid)
list1.sort()
list2.sort()
if list1 != list2:
named_s += 1
named_s_list.append(msgid)
match = bnamed.match(msgstr)
if match:
bnamed_s +=1
bnamed_s_list.append(msgstr)
has_context1 = (msgid.count('|') > 0)
has_context2 = (msgstr.count('|') > 0)
if has_context1 and has_context2 and (msgid != msgstr):
context += 1
context_list.append(msgid)
coverage = (1.0 - (float(untranslated)/float(total))) * 100
template_coverage = coverage * float(total) / float(template_total)
print "File: %s" % args[0]
print "Template total: %d" % template_total
print "PO total: %d" % total
all_total[args[0]] = total
print "Fuzzy: %d" % fuzzy_count
all_fuzzy[args[0]] = fuzzy_count
print "Untranslated: %d" % untranslated
all_untranslated[args[0]] = untranslated
print "%%s mismatches: %d" % percent_s
all_percent_s[args[0]] = percent_s
print "%%()s mismatches: %d" % named_s
all_named_s[args[0]] = named_s
print "%%() missing s/d: %d" % bnamed_s
all_bnamed_s[args[0]] = bnamed_s
print "Runaway context: %d" % context
all_context[args[0]] = context
print "PO Coverage: %5.2f%%" % coverage
all_coverage[args[0]] = coverage
print "Template Coverage: %5.2f%%" % template_coverage
all_template_coverage[args[0]] = coverage
if percent_s:
print "\n-------- %s mismatches --------------"
for i in percent_s_list:
print "'%s' : '%s'" % (i, string_map[i])
if named_s:
print "\n-------- %()s mismatches ------------"
for i in named_s_list:
print "'%s' : '%s'" % (i, string_map[i])
if bnamed_s:
print "\n-------- %() missing s or d ---------"
for i in bnamed_s_list:
print "'%s' : '%s'" % (i, string_map[i])
if context:
print "\n-------- Runaway context in translation ---------"
for i in context_list:
print "'%s' : '%s'" % (i, string_map[i])
print ""
if len(sys.argv) > 2:
print "\n\nFile \tTotal \tFuzzy \tUntranslated \t%s mismatch \t%()s mismatch \tmissing s/d \tcontext \tCoverage"
for pofile in sys.argv[1:]:
print "%s \t%5d \t%7d \t%7d \t%7d \t%7d \t%7d \t%7d \t%3.2f%% \t%3.2f%%" %\
(pofile,
all_total[pofile],
all_fuzzy[pofile],
all_untranslated[pofile],
all_percent_s[pofile],
all_named_s[pofile],
all_bnamed_s[pofile],
all_context[pofile],
all_coverage[pofile],
all_template_coverage[pofile]
)
f = open("used_strings.txt","w")
keys = string_map.keys()
keys.sort()
for i in keys:
f.write(i + "\n")
f.close()

View File

@ -135,8 +135,11 @@ class ArgHandler:
o,v = options[opt_ix] o,v = options[opt_ix]
if o in ( '-O', '--open'): if o in ( '-O', '--open'):
fname = v fname = v
ftype = Mime.get_type( fullpath = os.path.abspath(os.path.expanduser(fname))
os.path.abspath(os.path.expanduser(fname))) if not os.path.exists(fullpath):
print "Input file does not exist: %s" % fullpath
continue
ftype = Mime.get_type(fullpath)
if opt_ix<len(options)-1 \ if opt_ix<len(options)-1 \
and options[opt_ix+1][0] in ( '-f', '--format'): and options[opt_ix+1][0] in ( '-f', '--format'):
format = options[opt_ix+1][1] format = options[opt_ix+1][1]
@ -151,14 +154,19 @@ class ArgHandler:
elif ftype == const.app_gramps: elif ftype == const.app_gramps:
format = 'grdb' format = 'grdb'
else: else:
print "Unrecognized format for input file %s" % fname print 'Unrecognized type: "%s" for input file: %s' \
% (ftype,fname)
print "Ignoring input file: %s" % fname print "Ignoring input file: %s" % fname
continue continue
self.open = (fname,format) self.open = (fname,format)
elif o in ( '-i', '--import'): elif o in ( '-i', '--import'):
fname = v fname = v
ftype = Mime.get_type( fullpath = os.path.abspath(os.path.expanduser(fname))
os.path.abspath(os.path.expanduser(fname))) if not os.path.exists(fullpath):
print "Input file does not exist: %s" % fullpath
continue
ftype = Mime.get_type(fullpath)
if opt_ix<len(options)-1 \ if opt_ix<len(options)-1 \
and options[opt_ix+1][0] in ( '-f', '--format'): and options[opt_ix+1][0] in ( '-f', '--format'):
format = options[opt_ix+1][1] format = options[opt_ix+1][1]
@ -181,12 +189,25 @@ class ArgHandler:
elif ftype == const.app_geneweb: elif ftype == const.app_geneweb:
format = 'geneweb' format = 'geneweb'
else: else:
print "Unrecognized format for input file %s" % fname print 'Unrecognized type: "%s" for input file: %s' \
% (ftype,fname)
print "Ignoring input file: %s" % fname print "Ignoring input file: %s" % fname
continue continue
self.imports.append((fname,format)) self.imports.append((fname,format))
elif o in ( '-o', '--output' ): elif o in ( '-o', '--output' ):
outfname = v outfname = v
fullpath = os.path.abspath(os.path.expanduser(outfname))
if os.path.exists(fullpath):
print "WARNING: Output file already exist!"
print "WARNING: It will be overwritten:\n %s" % fullpath
answer = None
while not answer:
answer = raw_input('OK to overwrite? ')
if answer.upper() in ('Y','YES'):
print "Will overwrite the existing file: %s" % fullpath
else:
print "Will skip the output file: %s" % fullpath
continue
if opt_ix<len(options)-1 \ if opt_ix<len(options)-1 \
and options[opt_ix+1][0] in ( '-f', '--format'): and options[opt_ix+1][0] in ( '-f', '--format'):
outformat = options[opt_ix+1][1] outformat = options[opt_ix+1][1]
@ -422,9 +443,11 @@ class ArgHandler:
from GrampsDb import GedcomParser from GrampsDb import GedcomParser
filename = os.path.normpath(os.path.abspath(filename)) filename = os.path.normpath(os.path.abspath(filename))
try: try:
np = ReadGedcom.NoteParser(filename, False, None)
g = ReadGedcom.GedcomParser(self.parent.db,filename,None,None,
np.get_map(),np.get_lines())
g = GedcomParser(self.state.db,filename,None) g = GedcomParser(self.state.db,filename,None)
g.parse_gedcom_file() g.parse_gedcom_file()
g.resolve_refns()
del g del g
except: except:
print "Error importing %s" % filename print "Error importing %s" % filename
@ -487,10 +510,13 @@ class ArgHandler:
print "Error importing %s" % filename print "Error importing %s" % filename
os._exit(1) os._exit(1)
# Clean up tempdir after ourselves # Clean up tempdir after ourselves
files = os.listdir(tmpdir_path) # THIS HAS BEEN CHANGED, because now we want to keep images
for fn in files: # stay after the import is over. Just delete the XML file.
os.remove(os.path.join(tmpdir_path,fn)) os.remove(dbname)
os.rmdir(tmpdir_path) ## files = os.listdir(tmpdir_path)
## for fn in files:
## os.remove(os.path.join(tmpdir_path,fn))
## os.rmdir(tmpdir_path)
else: else:
print "Invalid format: %s" % format print "Invalid format: %s" % format
os._exit(1) os._exit(1)

View File

@ -14,6 +14,7 @@ pkgdata_PYTHON = \
_Date_fi.py\ _Date_fi.py\
_Date_sv.py\ _Date_sv.py\
_Date_nl.py\ _Date_nl.py\
_Date_sk.py\
_DateDisplay.py\ _DateDisplay.py\
_DateParser.py\ _DateParser.py\
_DateHandler.py\ _DateHandler.py\

View File

@ -1,4 +1,4 @@
# -*- coding: iso-8859-1 -*- # -*- coding: utf-8 -*-
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
@ -70,20 +70,20 @@ class DateDisplay:
) )
_french = ( _french = (
'', u'',
unicode("Vendémiaire",'latin-1'), u"Vendémiaire",
'Brumaire', u'Brumaire',
'Frimaire', u'Frimaire',
unicode("Nivôse",'latin-1'), u"Nivôse",
unicode("Pluviôse",'latin-1'), u"Pluviôse",
unicode("Ventôse",'latin-1'), u"Ventôse",
'Germinal', u'Germinal',
unicode("Floréal",'latin-1'), u"Floréal",
'Prairial', u'Prairial',
'Messidor', u'Messidor',
'Thermidor', u'Thermidor',
'Fructidor', u'Fructidor',
'Extra' u'Extra',
) )
_persian = ( _persian = (
@ -162,10 +162,6 @@ class DateDisplay:
d1 = self.display_iso(start) d1 = self.display_iso(start)
d2 = self.display_iso(date.get_stop_date()) d2 = self.display_iso(date.get_stop_date())
return "%s %s - %s%s" % (qual_str,d1,d2,self.calendar[cal]) return "%s %s - %s%s" % (qual_str,d1,d2,self.calendar[cal])
elif mod == Date.MOD_RANGE:
d1 = self.display_iso(start)
d2 = self.display_iso(date.get_stop_date())
return "%s %s - %s%s" % (qual_str,d1,d2,self.calendar[cal])
else: else:
text = self.display_iso(start) text = self.display_iso(start)
return "%s%s%s%s" % (qual_str,self._mod_str[mod],text,self.calendar[cal]) return "%s%s%s%s" % (qual_str,self._mod_str[mod],text,self.calendar[cal])
@ -175,7 +171,12 @@ class DateDisplay:
val = - val val = - val
if slash: if slash:
year = "%d/%d" % (val,(val%10)+1) if val % 100 == 99:
year = "%d/%d" % (val,(val%1000)+1)
elif val % 10 == 9:
year = "%d/%d" % (val,(val%100)+1)
else:
year = "%d/%d" % (val,(val%10)+1)
else: else:
year = "%d" % (val) year = "%d" % (val)
@ -184,7 +185,8 @@ class DateDisplay:
def display_iso(self,date_val): def display_iso(self,date_val):
# YYYY-MM-DD (ISO) # YYYY-MM-DD (ISO)
year = self._slash_year(date_val[2],date_val[3]) year = self._slash_year(date_val[2],date_val[3])
if date_val[0] == 0: # FIXME: This prodices 1789-11-00 and 1789-00-00 for incomplete dates.
if False:#date_val[0] == 0:
if date_val[1] == 0: if date_val[1] == 0:
value = year value = year
else: else:
@ -209,13 +211,16 @@ class DateDisplay:
if self.format == 0: if self.format == 0:
return self.display_iso(date_val) return self.display_iso(date_val)
elif self.format == 1: elif self.format == 1:
if date_val[0] == 0 and date_val[1] == 0: if date_val[3]:
value = str(date_val[2]) return self.display_iso(date_val)
else: else:
value = self._tformat.replace('%m',str(date_val[1])) if date_val[0] == 0 and date_val[1] == 0:
value = value.replace('%d',str(date_val[0])) value = str(date_val[2])
value = value.replace('%Y',str(abs(date_val[2]))) else:
value = value.replace('-','/') value = self._tformat.replace('%m',str(date_val[1]))
value = value.replace('%d',str(date_val[0]))
value = value.replace('%Y',str(abs(date_val[2])))
value = value.replace('-','/')
elif self.format == 2: elif self.format == 2:
# Month Day, Year # Month Day, Year
if date_val[0] == 0: if date_val[0] == 0:

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
@ -122,13 +123,13 @@ class DateParser:
} }
french_to_int = { french_to_int = {
u'vend\xc3\xa9miaire' : 1, 'brumaire' : 2, u'vendémiaire' : 1, u'brumaire' : 2,
'frimaire' : 3, u'niv\xc3\xb4se ': 4, u'frimaire' : 3, u'nivôse': 4,
u'pluvi\xc3\xb4se' : 5, u'vent\xc3\xb4se' : 6, u'pluviôse' : 5, u'ventôse' : 6,
'germinal' : 7, u'flor\xc3\xa9al' : 8, u'germinal' : 7, u'floréal' : 8,
'prairial' : 9, 'messidor' : 10, u'prairial' : 9, u'messidor' : 10,
'thermidor' : 11, 'fructidor' : 12, u'thermidor' : 11, u'fructidor' : 12,
'extra' : 13 u'extra' : 13
} }
islamic_to_int = { islamic_to_int = {
@ -150,15 +151,15 @@ class DateParser:
} }
persian_to_int = { persian_to_int = {
"Farvardin" : 1, "Ordibehesht" : 2, "farvardin" : 1, "ordibehesht" : 2,
"Khordad" : 3, "Tir" : 4, "khordad" : 3, "tir" : 4,
"Mordad" : 5, "Shahrivar" : 6, "mordad" : 5, "shahrivar" : 6,
"Mehr" : 7, "Aban" : 8, "mehr" : 7, "aban" : 8,
"Azar" : 9, "Dey" : 10, "azar" : 9, "dey" : 10,
"Bahman" : 11, "Esfand" : 12, "bahman" : 11, "esfand" : 12,
} }
bce = ["BC", "B\.C", "B\.C\.", "BCE", "B\.C\.E", "B\.C\.E"] bce = ["B.C.E.", "B.C.E", "BCE", "B.C.", "B.C", "BC" ]
calendar_to_int = { calendar_to_int = {
'gregorian' : Date.CAL_GREGORIAN, 'gregorian' : Date.CAL_GREGORIAN,
@ -200,9 +201,20 @@ class DateParser:
match = self._fmt_parse.match(fmt.lower()) match = self._fmt_parse.match(fmt.lower())
if match: if match:
self.dmy = (match.groups() == ('d','m','y')) self.dmy = (match.groups() == ('d','m','y'))
self.ymd = (match.groups() == ('y','m','d'))
else: else:
self.dmy = True self.dmy = True
self.ymd = False
def re_longest_first(self, keys):
"""
returns a string for a RE group which contains the given keys
sorted so that longest keys match first. Any '.' characters
are quoted.
"""
keys.sort(lambda x, y: cmp(len(y), len(x)))
return '(' + '|'.join([key.replace('.','\.') for key in keys]) + ')'
def init_strings(self): def init_strings(self):
""" """
This method compiles regular expression strings for matching dates. This method compiles regular expression strings for matching dates.
@ -217,38 +229,29 @@ class DateParser:
self._rfc_mon_str = '(' + '|'.join(self._rfc_mons_to_int.keys()) + ')' self._rfc_mon_str = '(' + '|'.join(self._rfc_mons_to_int.keys()) + ')'
self._rfc_day_str = '(' + '|'.join(self._rfc_days) + ')' self._rfc_day_str = '(' + '|'.join(self._rfc_days) + ')'
self._bce_str = '(' + '|'.join(self.bce) + ')' self._bce_str = self.re_longest_first(self.bce)
self._qual_str = self.re_longest_first(self.quality_to_int.keys())
self._qual_str = '(' + '|'.join( self._mod_str = self.re_longest_first(self.modifier_to_int.keys())
[ key.replace('.','\.') for key in self.quality_to_int.keys() ] self._mod_after_str = self.re_longest_first(
) + ')' self.modifier_after_to_int.keys())
keys = self.modifier_to_int.keys()
keys.sort(lambda x, y: cmp(len(y), len(x)))
self._mod_str = '(' + '|'.join(
[ key.replace('.','\.') for key in keys ]
) + ')'
self._mod_after_str = '(' + '|'.join(
[ key.replace('.','\.') for key in self.modifier_after_to_int.keys() ]
) + ')'
# Need to reverse-sort the keys, so that April matches before Apr does. self._mon_str = self.re_longest_first(self.month_to_int.keys())
# Otherwise, 'april 2000' would be matched as 'apr' + garbage ('il 2000') self._jmon_str = self.re_longest_first(self.hebrew_to_int.keys())
_month_keys = self.month_to_int.keys() self._fmon_str = self.re_longest_first(self.french_to_int.keys())
_month_keys.sort() self._pmon_str = self.re_longest_first(self.persian_to_int.keys())
_month_keys.reverse() self._imon_str = self.re_longest_first(self.islamic_to_int.keys())
self._mon_str = '(' + '|'.join(_month_keys) + ')' self._cal_str = self.re_longest_first(self.calendar_to_int.keys())
self._jmon_str = '(' + '|'.join(self.hebrew_to_int.keys()) + ')'
self._fmon_str = '(' + '|'.join(self.french_to_int.keys()) + ')'
self._pmon_str = '(' + '|'.join(self.persian_to_int.keys()) + ')'
self._cal_str = '(' + '|'.join(self.calendar_to_int.keys()) + ')'
self._imon_str = '(' + '|'.join(self.islamic_to_int.keys()) + ')'
self._bce_re = re.compile("(.+)\s+%s" % self._bce_str) # bce, calendar type and quality may be either at the end or at
# the beginning of the given date string, therefore they will
self._cal = re.compile("(.+)\s\(%s\)" % self._cal_str, # be parsed from the middle and will be in match.group(2).
self._bce_re = re.compile("(.*)\s+%s( ?.*)" % self._bce_str)
self._cal = re.compile("(.*)\s+\(%s\)( ?.*)" % self._cal_str,
re.IGNORECASE) re.IGNORECASE)
self._qual = re.compile("%s\s+(.+)" % self._qual_str, self._qual = re.compile("(.* ?)%s\s+(.+)" % self._qual_str,
re.IGNORECASE) re.IGNORECASE)
self._span = re.compile("(from)\s+(?P<start>.+)\s+to\s+(?P<stop>.+)", self._span = re.compile("(from)\s+(?P<start>.+)\s+to\s+(?P<stop>.+)",
re.IGNORECASE) re.IGNORECASE)
self._range = re.compile("(bet|bet.|between)\s+(?P<start>.+)\s+and\s+(?P<stop>.+)", self._range = re.compile("(bet|bet.|between)\s+(?P<start>.+)\s+and\s+(?P<stop>.+)",
@ -279,7 +282,7 @@ class DateParser:
self._itext2 = re.compile('(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$' % self._imon_str, self._itext2 = re.compile('(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$' % self._imon_str,
re.IGNORECASE) re.IGNORECASE)
self._numeric = re.compile("((\d+)[/\.])?((\d+)[/\.])?(\d+)\s*$") self._numeric = re.compile("((\d+)[/\.])?((\d+)[/\.])?(\d+)\s*$")
self._iso = re.compile("(\d+)-(\d+)-(\d+)\s*$") self._iso = re.compile("(\d+)(/(\d+))?-(\d+)-(\d+)\s*$")
self._rfc = re.compile("(%s,)?\s+(\d|\d\d)\s+%s\s+(\d+)\s+\d\d:\d\d(:\d\d)?\s+(\+|-)\d\d\d\d" self._rfc = re.compile("(%s,)?\s+(\d|\d\d)\s+%s\s+(\d+)\s+\d\d:\d\d(:\d\d)?\s+(\+|-)\d\d\d\d"
% (self._rfc_day_str,self._rfc_mon_str)) % (self._rfc_day_str,self._rfc_mon_str))
@ -325,7 +328,7 @@ class DateParser:
if groups[2] == None: if groups[2] == None:
y = self._get_int(groups[1]) y = self._get_int(groups[1])
d = 0 d = 0
s = None s = False
else: else:
d = self._get_int(groups[1]) d = self._get_int(groups[1])
y = int(groups[3]) y = int(groups[3])
@ -346,8 +349,8 @@ class DateParser:
d = self._get_int(groups[0]) d = self._get_int(groups[0])
if groups[2] == None: if groups[2] == None:
y = 0 y = None
s = None s = False
else: else:
y = int(groups[3]) y = int(groups[3])
s = groups[4] != None s = groups[4] != None
@ -378,12 +381,14 @@ class DateParser:
if match: if match:
groups = match.groups() groups = match.groups()
y = self._get_int(groups[0]) y = self._get_int(groups[0])
m = self._get_int(groups[1]) m = self._get_int(groups[3])
d = self._get_int(groups[2]) d = self._get_int(groups[4])
if gregorian_valid((d,m,y)): if check and not check((d,m,y)):
return (d,m,y,False)
else:
return Date.EMPTY return Date.EMPTY
if groups[2]:
return (d,m,y,True)
else:
return (d,m,y,False)
match = self._rfc.match(text) match = self._rfc.match(text)
if match: if match:
@ -391,21 +396,32 @@ class DateParser:
d = self._get_int(groups[2]) d = self._get_int(groups[2])
m = self._rfc_mons_to_int[groups[3]] m = self._rfc_mons_to_int[groups[3]]
y = self._get_int(groups[4]) y = self._get_int(groups[4])
if gregorian_valid((d,m,y)): value = (d,m,y,False)
return (d,m,y,False) if check and not check((d,m,y)):
else: value = Date.EMPTY
return Date.EMPTY return value
match = self._numeric.match(text) match = self._numeric.match(text)
if match: if match:
groups = match.groups() groups = match.groups()
if self.dmy: if self.ymd:
m = self._get_int(groups[3]) # '1789' and ymd: incomplete date
d = self._get_int(groups[1]) if groups[1] == None:
y = self._get_int(groups[4])
m = 0
d = 0
else:
y = self._get_int(groups[1])
m = self._get_int(groups[3])
d = self._get_int(groups[4])
else: else:
m = self._get_int(groups[1]) y = self._get_int(groups[4])
d = self._get_int(groups[3]) if self.dmy:
y = self._get_int(groups[4]) m = self._get_int(groups[3])
d = self._get_int(groups[1])
else:
m = self._get_int(groups[1])
d = self._get_int(groups[3])
value = (d,m,y,False) value = (d,m,y,False)
if check and not check((d,m,y)): if check and not check((d,m,y)):
value = Date.EMPTY value = Date.EMPTY
@ -417,26 +433,24 @@ class DateParser:
""" """
Try parsing calendar. Try parsing calendar.
Return calendar index and the remainder of text. Return calendar index and the text with calendar removed.
""" """
match = self._cal.match(text) match = self._cal.match(text)
if match: if match:
grps = match.groups() cal = self.calendar_to_int[match.group(2).lower()]
cal = self.calendar_to_int[grps[1].lower()] text = match.group(1) + match.group(3)
text = grps[0]
return (text,cal) return (text,cal)
def match_quality(self,text,qual): def match_quality(self,text,qual):
""" """
Try matching quality. Try matching quality.
Return quality index and the remainder of text. Return quality index and the text with quality removed.
""" """
match = self._qual.match(text) match = self._qual.match(text)
if match: if match:
grps = match.groups() qual = self.quality_to_int[match.group(2).lower()]
qual = self.quality_to_int[grps[0].lower()] text = match.group(1) + match.group(3)
text = grps[1]
return (text,qual) return (text,qual)
def match_span(self,text,cal,qual,date): def match_span(self,text,cal,qual,date):
@ -448,8 +462,16 @@ class DateParser:
match = self._span.match(text) match = self._span.match(text)
if match: if match:
text_parser = self.parser[cal] text_parser = self.parser[cal]
start = self._parse_subdate(match.group('start'),text_parser) (text1,bc1) = self.match_bce(match.group('start'))
stop = self._parse_subdate(match.group('stop'),text_parser) start = self._parse_subdate(text1,text_parser)
if bc1:
start = self.invert_year(start)
(text2,bc2) = self.match_bce(match.group('stop'))
stop = self._parse_subdate(text2,text_parser)
if bc2:
stop = self.invert_year(stop)
date.set(qual,Date.MOD_SPAN,cal,start + stop) date.set(qual,Date.MOD_SPAN,cal,start + stop)
return 1 return 1
return 0 return 0
@ -463,8 +485,16 @@ class DateParser:
match = self._range.match(text) match = self._range.match(text)
if match: if match:
text_parser = self.parser[cal] text_parser = self.parser[cal]
start = self._parse_subdate(match.group('start'),text_parser) (text1,bc1) = self.match_bce(match.group('start'))
stop = self._parse_subdate(match.group('stop'),text_parser) start = self._parse_subdate(text1,text_parser)
if bc1:
start = self.invert_year(start)
(text2,bc2) = self.match_bce(match.group('stop'))
stop = self._parse_subdate(text2,text_parser)
if bc2:
stop = self.invert_year(stop)
date.set(qual,Date.MOD_RANGE,cal,start + stop) date.set(qual,Date.MOD_RANGE,cal,start + stop)
return 1 return 1
return 0 return 0
@ -473,12 +503,16 @@ class DateParser:
""" """
Try matching BCE qualifier. Try matching BCE qualifier.
Return BCE (True/False) and the remainder of text. Return BCE (True/False) and the text with matched part removed.
""" """
match = self._bce_re.match(text) match = self._bce_re.match(text)
bc = False bc = False
if match: if match:
text = match.groups()[0] # bce is in the match.group(2)
try:
text = match.group(1) + match.group(3)
except:
print "MATCH:", match.groups()
bc = True bc = True
return (text,bc) return (text,bc)
@ -492,8 +526,8 @@ class DateParser:
match = self._modifier.match(text) match = self._modifier.match(text)
if match: if match:
grps = match.groups() grps = match.groups()
start = self._parse_subdate(grps[1]) start = self._parse_subdate(grps[1], self.parser[cal])
mod = self.modifier_to_int.get(grps[0].lower(),Date.MOD_NONE) mod = self.modifier_to_int.get(grps[0].lower(), Date.MOD_NONE)
if bc: if bc:
date.set(qual,mod,cal,self.invert_year(start)) date.set(qual,mod,cal,self.invert_year(start))
else: else:
@ -504,7 +538,7 @@ class DateParser:
match = self._modifier_after.match(text) match = self._modifier_after.match(text)
if match: if match:
grps = match.groups() grps = match.groups()
start = self._parse_subdate(grps[0]) start = self._parse_subdate(grps[0], self.parser[cal])
mod = self.modifier_after_to_int.get(grps[1].lower(), mod = self.modifier_after_to_int.get(grps[1].lower(),
Date.MOD_NONE) Date.MOD_NONE)
if bc: if bc:
@ -529,7 +563,6 @@ class DateParser:
Parses the text and sets the date according to the parsing. Parses the text and sets the date according to the parsing.
""" """
date.set_text_value(text) date.set_text_value(text)
qual = Date.QUAL_NONE qual = Date.QUAL_NONE
cal = Date.CAL_GREGORIAN cal = Date.CAL_GREGORIAN

View File

@ -88,17 +88,17 @@ class DateParserDE(DateParser):
} }
calendar_to_int = { calendar_to_int = {
u'Gregorianisch' : Date.CAL_GREGORIAN, u'gregorianisch' : Date.CAL_GREGORIAN,
u'Greg.' : Date.CAL_GREGORIAN, u'greg.' : Date.CAL_GREGORIAN,
u'Julianisch' : Date.CAL_JULIAN, u'julianisch' : Date.CAL_JULIAN,
u'Jul.' : Date.CAL_JULIAN, u'jul.' : Date.CAL_JULIAN,
u'Hebräisch' : Date.CAL_HEBREW, u'hebräisch' : Date.CAL_HEBREW,
u'Hebr.' : Date.CAL_HEBREW, u'hebr.' : Date.CAL_HEBREW,
u'Islamisch' : Date.CAL_ISLAMIC, u'islamisch' : Date.CAL_ISLAMIC,
u'Isl.' : Date.CAL_ISLAMIC, u'isl.' : Date.CAL_ISLAMIC,
u'Französisch Republikanisch': Date.CAL_FRENCH, u'französisch republikanisch': Date.CAL_FRENCH,
u'Franz.' : Date.CAL_FRENCH, u'franz.' : Date.CAL_FRENCH,
u'Persisch' : Date.CAL_PERSIAN, u'persisch' : Date.CAL_PERSIAN,
} }
quality_to_int = { quality_to_int = {
@ -109,7 +109,10 @@ class DateParserDE(DateParser):
u'ber.' : Date.QUAL_CALCULATED, u'ber.' : Date.QUAL_CALCULATED,
} }
bce = DateParser.bce + ["vor (unserer|der) Zeit(rechnung)?", "v\. (u|d)\. Z\.", "vor Christus", "vor Christi Geburt", "v\. Chr\."] bce = ["vor unserer Zeitrechnung", "vor unserer Zeit",
"vor der Zeitrechnung", "vor der Zeit",
"v. u. Z.", "v. d. Z.", "v.u.Z.", "v.d.Z.",
"vor Christi Geburt", "vor Christus", "v. Chr."] + DateParser.bce
def init_strings(self): def init_strings(self):
DateParser.init_strings(self) DateParser.init_strings(self)
@ -128,8 +131,8 @@ class DateParserDE(DateParser):
class DateDisplayDE(DateDisplay): class DateDisplayDE(DateDisplay):
calendar = ( calendar = (
"", u" (Julianisch)", u" (Hebräisch)", "", u" (julianisch)", u" (hebräisch)",
u" (Französisch Republikanisch)", u" (Persisch)", u" (Islamisch)" u" (französisch republikanisch)", u" (persisch)", u" (islamisch)"
) )
_mod_str = ("",u"vor ",u"nach ",u"etwa ","","","") _mod_str = ("",u"vor ",u"nach ",u"etwa ","","","")
@ -146,14 +149,17 @@ class DateDisplayDE(DateDisplay):
def _display_gregorian(self,date_val): def _display_gregorian(self,date_val):
year = self._slash_year(date_val[2],date_val[3]) year = self._slash_year(date_val[2],date_val[3])
if self.format == 0: if self.format == 0:
value = self.display_iso(date_val) return self.display_iso(date_val)
elif self.format == 1: elif self.format == 1:
if date_val[0] == 0 and date_val[1] == 0: if date_val[3]:
value = str(date_val[2]) return self.display_iso(date_val)
else: else:
value = self._tformat.replace('%m',str(date_val[1])) if date_val[0] == 0 and date_val[1] == 0:
value = value.replace('%d',str(date_val[0])) value = str(date_val[2])
value = value.replace('%Y',str(date_val[2])) else:
value = self._tformat.replace('%m',str(date_val[1]))
value = value.replace('%d',str(date_val[0]))
value = value.replace('%Y',str(date_val[2]))
elif self.format == 2: elif self.format == 2:
# Month Day, Year # Month Day, Year
if date_val[0] == 0: if date_val[0] == 0:
@ -190,7 +196,10 @@ class DateDisplayDE(DateDisplay):
value = "%s %s" % (self._MONS[date_val[1]],year) value = "%s %s" % (self._MONS[date_val[1]],year)
else: else:
value = "%d. %s %s" % (date_val[0],self._MONS[date_val[1]],year) value = "%d. %s %s" % (date_val[0],self._MONS[date_val[1]],year)
return value if date_val[2] < 0:
return self._bce_str % value
else:
return value
def display(self,date): def display(self,date):
""" """

View File

@ -97,7 +97,7 @@ class DateParserES(DateParser):
DateParser.init_strings(self) DateParser.init_strings(self)
_span_1 = [u'de'] _span_1 = [u'de']
_span_2 = [u'a'] _span_2 = [u'a']
_range_1 = [u'ent.',u'ent',u'entre'] _range_1 = [u'entre',u'ent\.',u'ent']
_range_2 = [u'y'] _range_2 = [u'y']
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" % self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_span_1),'|'.join(_span_2)), ('|'.join(_span_1),'|'.join(_span_2)),

View File

@ -72,7 +72,7 @@ class DateParserFI(DateParser):
u'j.' : Date.MOD_AFTER, u'j.' : Date.MOD_AFTER,
} }
bce = ["ekr", "ekr\."] bce = [u"ekr.", u"ekr"]
calendar_to_int = { calendar_to_int = {
u'gregoriaaninen' : Date.CAL_GREGORIAN, u'gregoriaaninen' : Date.CAL_GREGORIAN,
@ -99,9 +99,9 @@ class DateParserFI(DateParser):
def init_strings(self): def init_strings(self):
DateParser.init_strings(self) DateParser.init_strings(self)
# date, whitespace # date, whitespace
self._span = re.compile("(?P<start>.+)\s+(-)\s+(?P<stop>.+)", self._span = re.compile(u"(?P<start>.+)\s+(-)\s+(?P<stop>.+)",
re.IGNORECASE) re.IGNORECASE)
self._range = re.compile("(vuosien\s*)?(?P<start>.+)\s+ja\s+(?P<stop>.+)\s+välillä", self._range = re.compile(u"(vuosien\s*)?(?P<start>.+)\s+ja\s+(?P<stop>.+)\s+välillä",
re.IGNORECASE) re.IGNORECASE)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -112,15 +112,15 @@ class DateParserFI(DateParser):
class DateDisplayFI(DateDisplay): class DateDisplayFI(DateDisplay):
calendar = ("", calendar = ("",
u"(Juliaaninen)", u"(juliaaninen)",
u"(Heprealainen)", u"(heprealainen)",
u"(Ranskan v.)", u"(ranskan v.)",
u"(Persialainen)", u"(persialainen)",
u"(Islamilainen)") u"(islamilainen)")
_qual_str = ("", "arviolta", "laskettuna") _qual_str = (u"", u"arviolta", u"laskettuna")
_bce_str = "%s ekr." _bce_str = u"%s ekr."
formats = ( formats = (
"VVVV-KK-PP (ISO)", "VVVV-KK-PP (ISO)",
@ -139,7 +139,7 @@ class DateDisplayFI(DateDisplay):
if mod == Date.MOD_TEXTONLY: if mod == Date.MOD_TEXTONLY:
return date.get_text() return date.get_text()
if start == Date.EMPTY: if start == Date.EMPTY:
return "" return u""
# select numerical date format # select numerical date format
self.format = 1 self.format = 1
@ -147,32 +147,32 @@ class DateDisplayFI(DateDisplay):
if mod == Date.MOD_SPAN: if mod == Date.MOD_SPAN:
d1 = self.display_cal[cal](start) d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](date.get_stop_date()) d2 = self.display_cal[cal](date.get_stop_date())
text = "%s - %s" % (d1, d2) text = u"%s - %s" % (d1, d2)
elif mod == Date.MOD_RANGE: elif mod == Date.MOD_RANGE:
stop = date.get_stop_date() stop = date.get_stop_date()
if start[0] == 0 and start[1] == 0 and stop[0] == 0 and stop[1] == 0: if start[0] == 0 and start[1] == 0 and stop[0] == 0 and stop[1] == 0:
d1 = self.display_cal[cal](start) d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](stop) d2 = self.display_cal[cal](stop)
text = "vuosien %s ja %s välillä" % (d1, d2) text = u"vuosien %s ja %s välillä" % (d1, d2)
else: else:
d1 = self.display_cal[cal](start) d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](stop) d2 = self.display_cal[cal](stop)
text = "%s ja %s välillä" % (d1, d2) text = u"%s ja %s välillä" % (d1, d2)
else: else:
text = self.display_cal[date.get_calendar()](start) text = self.display_cal[date.get_calendar()](start)
if mod == Date.MOD_AFTER: if mod == Date.MOD_AFTER:
text = text + " jälkeen" text = text + u" jälkeen"
elif mod == Date.MOD_ABOUT: elif mod == Date.MOD_ABOUT:
text = "noin " + text text = u"noin " + text
elif mod == Date.MOD_BEFORE: elif mod == Date.MOD_BEFORE:
text = "ennen " + text text = u"ennen " + text
if qual: if qual:
# prepend quality # prepend quality
text = "%s %s" % (self._qual_str[qual], text) text = u"%s %s" % (self._qual_str[qual], text)
if cal: if cal:
# append calendar type # append calendar type
text = "%s %s" % (text, self.calendar[cal]) text = u"%s %s" % (text, self.calendar[cal])
return text return text

View File

@ -90,7 +90,6 @@ class DateParserFR(DateParser):
modifier_to_int = { modifier_to_int = {
u'avant' : Date.MOD_BEFORE, u'avant' : Date.MOD_BEFORE,
u'av.' : Date.MOD_BEFORE, u'av.' : Date.MOD_BEFORE,
u'av' : Date.MOD_BEFORE,
u'après' : Date.MOD_AFTER, u'après' : Date.MOD_AFTER,
u'ap.' : Date.MOD_AFTER, u'ap.' : Date.MOD_AFTER,
u'ap' : Date.MOD_AFTER, u'ap' : Date.MOD_AFTER,
@ -134,8 +133,11 @@ class DateParserFR(DateParser):
def init_strings(self): def init_strings(self):
DateParser.init_strings(self) DateParser.init_strings(self)
self._span = re.compile("(de)\s+(?P<start>.+)\s+(à)\s+(?P<stop>.+)",re.IGNORECASE) # This self._numeric is different from the base
self._range = re.compile("(entre|ent|ent.)\s+(?P<start>.+)\s+(et)\s+(?P<stop>.+)",re.IGNORECASE) # by allowing space after the slash/dot
self._numeric = re.compile("((\d+)[/\. ])?\s*((\d+)[/\.])?\s*(\d+)\s*$")
self._span = re.compile(u"(de)\s+(?P<start>.+)\s+(à)\s+(?P<stop>.+)",re.IGNORECASE)
self._range = re.compile(u"(entre|ent\.|ent)\s+(?P<start>.+)\s+(et)\s+(?P<stop>.+)",re.IGNORECASE)
self._text2 =re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._mon_str, self._text2 =re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._mon_str,
re.IGNORECASE) re.IGNORECASE)
self._jtext2 =re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._mon_str, self._jtext2 =re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._mon_str,
@ -155,24 +157,27 @@ class DateDisplayFR(DateDisplay):
_mod_str = ("",u"avant ",u"après ",u"vers ","","","") _mod_str = ("",u"avant ",u"après ",u"vers ","","","")
_qual_str = ("","estimée ","calculée ","") _qual_str = ("",u"estimée ",u"calculée ","")
formats = ( formats = (
"AAAA-MM-DD (ISO)", "Numérique", "Mois Jour, Année", "AAAA-MM-JJ (ISO)", "Numérique", "Mois Jour, Année",
"MOI Jour, Année", "Jour Mois, Année", "Jour MOIS Année" "MOI Jour, Année", "Jour Mois, Année", "Jour MOI Année"
) )
def _display_gregorian(self,date_val): def _display_gregorian(self,date_val):
year = self._slash_year(date_val[2],date_val[3]) year = self._slash_year(date_val[2],date_val[3])
if self.format == 0: if self.format == 0:
value = self.display_iso(date_val) return self.display_iso(date_val)
elif self.format == 1: elif self.format == 1:
if date_val[0] == 0 and date_val[1] == 0: if date_val[3]:
value = str(date_val[2]) return self.display_iso(date_val)
else: else:
value = self._tformat.replace('%m',str(date_val[1])) if date_val[0] == 0 and date_val[1] == 0:
value = value.replace('%d',str(date_val[0])) value = str(date_val[2])
value = value.replace('%Y',str(date_val[2])) else:
value = self._tformat.replace('%m',str(date_val[1]))
value = value.replace('%d',str(date_val[0]))
value = value.replace('%Y',str(date_val[2]))
elif self.format == 2: elif self.format == 2:
# Month Day, Year # Month Day, Year
if date_val[0] == 0: if date_val[0] == 0:
@ -209,7 +214,11 @@ class DateDisplayFR(DateDisplay):
value = "%s %s" % (self._MONS[date_val[1]],year) value = "%s %s" % (self._MONS[date_val[1]],year)
else: else:
value = "%d. %s %s" % (date_val[0],self._MONS[date_val[1]],year) value = "%d. %s %s" % (date_val[0],self._MONS[date_val[1]],year)
return value if date_val[2] < 0:
return self._bce_str % value
else:
return value
def display(self,date): def display(self,date):
""" """
@ -243,5 +252,6 @@ class DateDisplayFR(DateDisplay):
# Register classes # Register classes
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
register_datehandler(('fr_FR','fr','french','fr_CA','fr_BE','fr_CH'), register_datehandler(
DateParserFR,DateDisplayFR) ('fr_FR','fr','french','fr_CA','fr_BE','fr_CH','fr_LU'),
DateParserFR,DateDisplayFR)

View File

@ -56,17 +56,17 @@ class DateParserLT(DateParser):
} }
calendar_to_int = { calendar_to_int = {
u'Grigaliaus' : Date.CAL_GREGORIAN, u'grigaliaus' : Date.CAL_GREGORIAN,
u'g' : Date.CAL_GREGORIAN, u'g' : Date.CAL_GREGORIAN,
u'Julijaus' : Date.CAL_JULIAN, u'julijaus' : Date.CAL_JULIAN,
u'j' : Date.CAL_JULIAN, u'j' : Date.CAL_JULIAN,
u'Hebrajų' : Date.CAL_HEBREW, u'hebrajų' : Date.CAL_HEBREW,
u'h' : Date.CAL_HEBREW, u'h' : Date.CAL_HEBREW,
u'Islamo' : Date.CAL_ISLAMIC, u'islamo' : Date.CAL_ISLAMIC,
u'i' : Date.CAL_ISLAMIC, u'i' : Date.CAL_ISLAMIC,
u'Prancuzų Respublikos': Date.CAL_FRENCH, u'prancuzų respublikos': Date.CAL_FRENCH,
u'r' : Date.CAL_FRENCH, u'r' : Date.CAL_FRENCH,
u'Persų' : Date.CAL_PERSIAN, u'persų' : Date.CAL_PERSIAN,
u'p' : Date.CAL_PERSIAN, u'p' : Date.CAL_PERSIAN,
} }
@ -96,18 +96,20 @@ class DateParserLT(DateParser):
class DateDisplayLT(DateDisplay): class DateDisplayLT(DateDisplay):
calendar = ( calendar = (
"", u" (Julijaus)", u"", u" (julijaus)",
u" (Hebrajų)", u" (hebrajų)",
u" (Prancuzų Respublikos)", u" (prancuzų respublikos)",
u" (Persų)", u" (persų)",
u" (Islamo)" u" (islamo)"
) )
_mod_str = ("",u"iki ", _mod_str = (u"",
u"prieš ",
u"po ", u"po ",
u"apie ","","","") u"apie ",
u"",u"",u"")
_qual_str = ("","apytikriai ","apskaičiuota ") _qual_str = (u"",u"apytikriai ",u"apskaičiuota ")
formats = ( formats = (
"YYYY-MM-DD (ISO)", "Skaitmeninis", "Mėnuo Diena, Metai", "YYYY-MM-DD (ISO)", "Skaitmeninis", "Mėnuo Diena, Metai",
@ -132,7 +134,7 @@ class DateDisplayLT(DateDisplay):
elif mod == Date.MOD_SPAN: elif mod == Date.MOD_SPAN:
d1 = self.display_cal[cal](start) d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](date.get_stop_date()) d2 = self.display_cal[cal](date.get_stop_date())
return "%sс %s %s %s%s" % (qual_str,d1,u'iki',d2,self.calendar[cal]) return "%s%s %s %s %s%s" % (qual_str,u'nuo',d1,u'iki',d2,self.calendar[cal])
elif mod == Date.MOD_RANGE: elif mod == Date.MOD_RANGE:
d1 = self.display_cal[cal](start) d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](date.get_stop_date()) d2 = self.display_cal[cal](date.get_stop_date())

View File

@ -92,17 +92,17 @@ class DateParserNL(DateParser):
} }
calendar_to_int = { calendar_to_int = {
u'Gregoriaans' : Date.CAL_GREGORIAN, u'gregoriaans' : Date.CAL_GREGORIAN,
u'Greg.' : Date.CAL_GREGORIAN, u'greg.' : Date.CAL_GREGORIAN,
u'Juliaans' : Date.CAL_JULIAN, u'juliaans' : Date.CAL_JULIAN,
u'Jul.' : Date.CAL_JULIAN, u'jul.' : Date.CAL_JULIAN,
u'Hebreeuws' : Date.CAL_HEBREW, u'hebreeuws' : Date.CAL_HEBREW,
u'Hebr.' : Date.CAL_HEBREW, u'hebr.' : Date.CAL_HEBREW,
u'Islamitisch' : Date.CAL_ISLAMIC, u'islamitisch' : Date.CAL_ISLAMIC,
u'Isl.' : Date.CAL_ISLAMIC, u'isl.' : Date.CAL_ISLAMIC,
u'Franse republiek': Date.CAL_FRENCH, u'franse republiek': Date.CAL_FRENCH,
u'Fran.' : Date.CAL_FRENCH, u'fran.' : Date.CAL_FRENCH,
u'Persisch' : Date.CAL_PERSIAN, u'persisch' : Date.CAL_PERSIAN,
} }
quality_to_int = { quality_to_int = {
@ -112,9 +112,7 @@ class DateParserNL(DateParser):
u'ber.' : Date.QUAL_CALCULATED, u'ber.' : Date.QUAL_CALCULATED,
} }
bce = DateParser.bce + ["voor onze tijdrekening", bce = ["voor onze tijdrekening","voor Christus","v. Chr."] + DateParser.bce
"voor Christus",
"v\. Chr\."]
def init_strings(self): def init_strings(self):
DateParser.init_strings(self) DateParser.init_strings(self)
@ -137,8 +135,8 @@ class DateParserNL(DateParser):
class DateDisplayNL(DateDisplay): class DateDisplayNL(DateDisplay):
calendar = ( calendar = (
"", u" (Juliaans)", u" (Hebreeuws)", "", u" (juliaans)", u" (hebreeuws)",
u" (Franse Republiek)", u" (Persisch)", u" (Islamitisch)" u" (franse republiek)", u" (persisch)", u" (islamitisch)"
) )
_mod_str = ("",u"voor ",u"na ",u"rond ","","","") _mod_str = ("",u"voor ",u"na ",u"rond ","","","")
@ -157,14 +155,17 @@ class DateDisplayNL(DateDisplay):
if self.format == 0: if self.format == 0:
return self.display_iso(date_val) return self.display_iso(date_val)
elif self.format == 1: elif self.format == 1:
# Numeric if date_val[3]:
if date_val[0] == 0 and date_val[1] == 0: return self.display_iso(date_val)
value = str(date_val[2])
else: else:
value = self._tformat.replace('%m',str(date_val[1])) # Numeric
value = value.replace('%d',str(date_val[0])) if date_val[0] == 0 and date_val[1] == 0:
value = value.replace('%Y',str(abs(date_val[2]))) value = str(date_val[2])
value = value.replace('-','/') else:
value = self._tformat.replace('%m',str(date_val[1]))
value = value.replace('%d',str(date_val[0]))
value = value.replace('%Y',str(abs(date_val[2])))
value = value.replace('-','/')
elif self.format == 2: elif self.format == 2:
# Month Day, Year # Month Day, Year
if date_val[0] == 0: if date_val[0] == 0:

View File

@ -50,7 +50,7 @@ from _DateHandler import register_datehandler
class DateParserRU(DateParser): class DateParserRU(DateParser):
modifier_to_int = { modifier_to_int = {
u'до' : Date.MOD_BEFORE, u'перед' : Date.MOD_BEFORE,
u'по' : Date.MOD_BEFORE, u'по' : Date.MOD_BEFORE,
u'после' : Date.MOD_AFTER, u'после' : Date.MOD_AFTER,
u'п.' : Date.MOD_AFTER, u'п.' : Date.MOD_AFTER,
@ -97,11 +97,77 @@ class DateParserRU(DateParser):
u'выч' : Date.QUAL_CALCULATED, u'выч' : Date.QUAL_CALCULATED,
} }
hebrew_to_int = {
u"тишрей":1,
u"хешван":2,
u"кислев":3,
u"тевет":4,
u"шеват":5,
u"адар":6,
u"адар бет":7,
u"нисан":8,
u"ияр":9,
u"сиван":10,
u"таммуз":11,
u"ав":12,
u"элул":13,
}
islamic_to_int = {
u"мухаррам":1,
u"сафар":2,
u"раби-аль-авваль":3,
u"раби-ассани":4,
u"джумада-аль-уля":5,
u"джумада-аль-ахира":6,
u"раджаб":7,
u"шаабан":8,
u"рамадан":9,
u"шавваль":10,
u"зуль-каада":11,
u"зуль-хиджжа":12,
}
persian_to_int = {
u"фарвардин":1,
u"урдбихишт":2,
u"хурдад":3,
u"тир":4,
u"мурдад":5,
u"шахривар":6,
u"михр":7,
u"абан":8,
u"азар":9,
u"дай":10,
u"бахман":11,
u"исфаидармуз":12,
}
french_to_int = {
u"вандемьер":1,
u"брюмер":2,
u"фример":3,
u"нивоз":4,
u"плювиоз":5,
u"вантоз":6,
u"жерминаль":7,
u"флореаль":8,
u"прериаль":9,
u"мессидор":10,
u"термидор":11,
u"фрюктидор":12,
u"дополнит.":13,
}
bce = [
u'до нашей эры', u'до н. э.', u'до н.э.',
u'до н э', u'до нэ'] + DateParser.bce
def init_strings(self): def init_strings(self):
DateParser.init_strings(self) DateParser.init_strings(self)
_span_1 = [u'с',u'от'] _span_1 = [u'с',u'от']
_span_2 = [u'по',u'до'] _span_2 = [u'по']
_range_1 = [u'между',u'меж',u'меж.'] _range_1 = [u'между',u'меж\.',u'меж']
_range_2 = [u'и'] _range_2 = [u'и']
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" % self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_span_1),'|'.join(_span_2)), ('|'.join(_span_1),'|'.join(_span_2)),
@ -118,24 +184,92 @@ class DateParserRU(DateParser):
class DateDisplayRU(DateDisplay): class DateDisplayRU(DateDisplay):
calendar = ( calendar = (
"", u" (юлианский)", u"",
u" (юлианский)",
u" (еврейский)", u" (еврейский)",
u" (республиканский)", u" (республиканский)",
u" (персидский)", u" (персидский)",
u" (исламский)" u" (исламский)"
) )
_mod_str = ("",u"до ", _mod_str = (
u"",
u"перед ",
u"после ", u"после ",
u"около ","","","") u"около ",
u"",u"",u"")
_qual_str = ("","оцен ","вычисл ") _qual_str = (u"",u"оцен ",u"вычисл ")
_bce_str = u"%s до н.э."
formats = ( formats = (
"ГГГГ-ММ-ДД (ISO)", "Численный", "Месяц День, Год", "ГГГГ-ММ-ДД (ISO)", "Численный", "Месяц День, Год",
"МЕС ДД, ГГГГГ", "День Месяц, Год", "ДД МЕС, ГГГГГ" "МЕС ДД, ГГГГГ", "День Месяц, Год", "ДД МЕС, ГГГГГ"
) )
_hebrew = ( u"",
u"Тишрей",
u"Хешван",
u"Кислев",
u"Тевет",
u"Шеват",
u"Адар",
u"Адар бет",
u"Нисан",
u"Ияр",
u"Сиван",
u"Таммуз",
u"Ав",
u"Элул",
)
_islamic = ( u"",
u"Мухаррам",
u"Сафар",
u"Раби-аль-авваль",
u"Раби-ассани",
u"Джумада-аль-уля",
u"Джумада-аль-ахира",
u"Раджаб",
u"Шаабан",
u"Рамадан",
u"Шавваль",
u"Зуль-каада",
u"Зуль-хиджжа",
)
_persian = ( u"",
u"Фарвардин",
u"Урдбихишт",
u"Хурдад",
u"Тир",
u"Мурдад",
u"Шахривар",
u"Михр",
u"Абан",
u"Азар",
u"Дай",
u"Бахман",
u"Исфаидармуз",
)
_french = ( u"",
u"Вандемьер",
u"Брюмер",
u"Фример",
u"Нивоз",
u"Плювиоз",
u"Вантоз",
u"Жерминаль",
u"Флореаль",
u"Прериаль",
u"Мессидор",
u"Термидор",
u"Фрюктидор",
u"Дополнит."
)
def display(self,date): def display(self,date):
""" """
Returns a text string representing the date. Returns a text string representing the date.

149
src/DateHandler/_Date_sk.py Normal file
View File

@ -0,0 +1,149 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2004-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: Date_sk.py,v 1.1.2.4 2006/04/16 03:20:06 rshura Exp $
"""
Slovak-specific classes for parsing and displaying dates.
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import re
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import Date
from DateParser import DateParser
from DateDisplay import DateDisplay
#-------------------------------------------------------------------------
#
# Slovak parser
#
#-------------------------------------------------------------------------
class DateParserSK(DateParser):
modifier_to_int = {
u'pred' : Date.MOD_BEFORE,
u'do' : Date.MOD_BEFORE,
u'po' : Date.MOD_AFTER,
u'asi' : Date.MOD_ABOUT,
u'okolo' : Date.MOD_ABOUT,
u'pribl.' : Date.MOD_ABOUT,
}
calendar_to_int = {
u'gregoriánsky' : Date.CAL_GREGORIAN,
u'g' : Date.CAL_GREGORIAN,
u'juliánský' : Date.CAL_JULIAN,
u'j' : Date.CAL_JULIAN,
u'hebrejský' : Date.CAL_HEBREW,
u'h' : Date.CAL_HEBREW,
u'islamský' : Date.CAL_ISLAMIC,
u'i' : Date.CAL_ISLAMIC,
u'republikánsky': Date.CAL_FRENCH,
u'r' : Date.CAL_FRENCH,
u'perzský' : Date.CAL_PERSIAN,
u'p' : Date.CAL_PERSIAN,
}
quality_to_int = {
u'odhadovaný' : Date.QUAL_ESTIMATED,
u'odh.' : Date.QUAL_ESTIMATED,
u'vypočítaný' : Date.QUAL_CALCULATED,
u'vyp.' : Date.QUAL_CALCULATED,
}
def init_strings(self):
DateParser.init_strings(self)
_span_1 = [u'od']
_span_2 = [u'do']
_range_1 = [u'medzi']
_range_2 = [u'a']
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_span_1),'|'.join(_span_2)),
re.IGNORECASE)
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_range_1),'|'.join(_range_2)),
re.IGNORECASE)
#-------------------------------------------------------------------------
#
# Slovak display
#
#-------------------------------------------------------------------------
class DateDisplaySK(DateDisplay):
calendar = (
"", u" (juliánský)", u" (hebrejský)",
u" (republikánsky)", u" (perzský)", u" (islamský)"
)
_mod_str = ("",u"pred ",u"po ",u"okolo ","","","")
_qual_str = ("","odh. ","vyp. ")
formats = (
"RRRR-MM-DD (ISO)", "numerický", "Mesiac Deň, Rok",
"MES Deň, Rok", "Deň, Mesiac, Rok", "Deň MES Rok"
)
def display(self,date):
"""
Returns a text string representing the date.
"""
mod = date.get_modifier()
cal = date.get_calendar()
qual = date.get_quality()
start = date.get_start_date()
qual_str = self._qual_str[qual]
if mod == Date.MOD_TEXTONLY:
return date.get_text()
elif start == Date.EMPTY:
return ""
elif mod == Date.MOD_SPAN:
d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](date.get_stop_date())
return "%s%s %s %s %s%s" % (qual_str,u'od',d1,u'do',d2,self.calendar[cal])
elif mod == Date.MOD_RANGE:
d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](date.get_stop_date())
return "%s%s %s %s %s%s" % (qual_str,u'medzi',d1,u'a',d2,self.calendar[cal])
else:
text = self.display_cal[date.get_calendar()](start)
return "%s%s%s%s" % (qual_str,self._mod_str[mod],text,self.calendar[cal])
#-------------------------------------------------------------------------
#
# Register classes
#
#-------------------------------------------------------------------------
from DateHandler import register_datehandler
register_datehandler(('sk_SK','sk','SK'),DateParserSK, DateDisplaySK)

View File

@ -145,7 +145,7 @@ class DateDisplaySv(DateDisplay):
if mod == Date.MOD_TEXTONLY: if mod == Date.MOD_TEXTONLY:
return date.get_text() return date.get_text()
elif start == Date.EMPTY: elif start == Date.EMPTY:
return "" return u""
elif mod == Date.MOD_SPAN: elif mod == Date.MOD_SPAN:
d1 = self.display_cal[cal](start) d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](date.get_stop_date()) d2 = self.display_cal[cal](date.get_stop_date())
@ -157,7 +157,7 @@ class DateDisplaySv(DateDisplay):
self.calendar[cal]) self.calendar[cal])
else: else:
text = self.display_cal[date.get_calendar()](start) text = self.display_cal[date.get_calendar()](start)
return "%s%s%s%s" % (qual_str,self._mod_str[mod], return u"%s%s%s%s" % (qual_str,self._mod_str[mod],
text,self.calendar[cal]) text,self.calendar[cal])
#------------------------------------------------------------------------- #-------------------------------------------------------------------------

View File

@ -2126,14 +2126,13 @@ class IsLessThanNthGenerationAncestorOfDefaultPerson(Rule):
def prepare(self,db): def prepare(self,db):
self.db = db self.db = db
p = db.get_default_person() p = db.get_default_person()
if p == 0: if p:
self.apply = lambda db,p: False
else:
self.def_handle = p.get_handle() self.def_handle = p.get_handle()
self.apply = self.apply_real self.apply = self.apply_real
self.map = {} self.map = {}
self.init_ancestor_list(self.def_handle, 1) self.init_ancestor_list(self.def_handle, 1)
else:
self.apply = lambda db,p: False
def init_ancestor_list(self,handle,gen): def init_ancestor_list(self,handle,gen):
# if self.map.has_key(p.get_handle()) == 1: # if self.map.has_key(p.get_handle()) == 1:

View File

@ -164,6 +164,10 @@ lds_status = {
_event_family_str = _("%(event_name)s of %(family)s") _event_family_str = _("%(event_name)s of %(family)s")
_event_person_str = _("%(event_name)s of %(person)s") _event_person_str = _("%(event_name)s of %(person)s")
_transtable = string.maketrans('','')
_delc = _transtable[0:31]
_transtable2 = _transtable[0:128] + ('?' * 128)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# GEDCOM events to GRAMPS events conversion # GEDCOM events to GRAMPS events conversion
@ -233,7 +237,7 @@ def importData(database, filename, callback=None, use_trans=False):
def import2(database, filename, callback, codeset, use_trans): def import2(database, filename, callback, codeset, use_trans):
# add some checking here # add some checking here
try: try:
np = NoteParser(filename, False) np = NoteParser(filename, False, codeset)
g = GedcomParser(database,filename, callback, codeset, np.get_map(), g = GedcomParser(database,filename, callback, codeset, np.get_map(),
np.get_lines(),np.get_persons()) np.get_lines(),np.get_persons())
except IOError,msg: except IOError,msg:
@ -334,43 +338,73 @@ class CurrentState:
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class NoteParser: class NoteParser:
def __init__(self, filename,broken): def __init__(self, filename,broken,override):
self.name_map = {} if override:
if override == 1:
self.cnv = ansel_to_utf8
elif override == 2:
self.cnv = latin_to_utf8
else:
self.cnv = nocnv
else:
f = open(filename,"rU")
for index in range(50):
line = f.readline().split()
if len(line) > 2 and line[1] == 'CHAR':
if line[2] == "ANSEL":
self.cnv = ansel_to_utf8
elif line[2] in ["UNICODE","UTF-8","UTF8"]:
self.cnv = nocnv
else:
self.cnv = latin_to_utf8
f.close()
self.count = 0 self.name_map = {}
self.person_count = 0
f = open(filename,"rU") self.count = 0
innote = False self.person_count = 0
f = open(filename,"rU")
innote = False
for line in f: for line in f:
try:
text = string.translate(line,_transtable,_delc)
except:
text = line
self.count += 1 try:
if innote: text = self.cnv(text)
match = contRE.match(line) except:
if match: text = string.translate(text,_transtable2)
noteobj.append("\n" + match.groups()[0])
continue
match = concRE.match(line) self.count += 1
if match: if innote:
if broken: match = contRE.match(text)
noteobj.append(" " + match.groups()[0]) if match:
else: noteobj.append("\n" + match.groups()[0])
noteobj.append(match.groups()[0]) continue
continue
innote = False match = concRE.match(text)
else: if match:
match = noteRE.match(line) if broken:
if match: noteobj.append(" " + match.groups()[0])
data = match.groups()[0] else:
noteobj = RelLib.Note() noteobj.append(match.groups()[0])
self.name_map["@%s@" % data] = noteobj continue
noteobj.append(match.groups()[1]) # Here we have finished parsing CONT/CONC tags for the NOTE
innote = True # and ignored the rest of the tags (SOUR,CHAN,REFN,RIN).
elif personRE.match(line): innote = False
self.person_count += 1 match = noteRE.match(text)
if match:
f.close() data = match.groups()[0]
noteobj = RelLib.Note()
self.name_map["@%s@" % data] = noteobj
noteobj.append(match.groups()[1])
innote = True
elif personRE.match(line):
self.person_count += 1
f.close()
def get_map(self): def get_map(self):
return self.name_map return self.name_map
@ -392,9 +426,6 @@ class Reader:
self.f = open(name,'rU') self.f = open(name,'rU')
self.current_list = [] self.current_list = []
self.eof = False self.eof = False
self.transtable = string.maketrans('','')
self.delc = self.transtable[0:31]
self.transtable2 = self.transtable[0:128] + ('?' * 128)
self.cnv = lambda s: unicode(s) self.cnv = lambda s: unicode(s)
self.broken_conc = False self.broken_conc = False
self.cnt = 0 self.cnt = 0
@ -426,11 +457,11 @@ class Reader:
break break
line = line.split(None,2) + [''] line = line.split(None,2) + ['']
val = line[2].translate(self.transtable,self.delc) val = line[2].translate(_transtable,_delc)
try: try:
val = self.cnv(val) val = self.cnv(val)
except: except:
val = self.cnv(val.translate(self.transtable2)) val = self.cnv(val.translate(_transtable2))
try: try:
level = int(line[0]) level = int(line[0])
@ -1168,23 +1199,21 @@ class GedcomParser:
del event del event
def parse_note_base(self,matches,obj,level,old_note,task): def parse_note_base(self,matches,obj,level,old_note,task):
note = old_note # reference to a named note defined elsewhere
if matches[2] and matches[2][0] == "@": # reference to a named note defined elsewhere if matches[2] and matches[2][0] == "@":
note_obj = self.note_map.get(matches[2]) note_obj = self.note_map.get(matches[2])
if note_obj: if note_obj:
return note_obj.get() new_note = note_obj.get()
else: else:
return u"" new_note = u""
else: else:
if old_note: new_note = matches[2] + self.parse_continue_data(level)
note = u"%s\n%s" % (old_note,matches[2])
else:
note = matches[2]
if type(note) != unicode:
print type(note),type(matches[2])
task(note)
self.ignore_sub_junk(level+1) self.ignore_sub_junk(level+1)
if old_note:
note = u"%s\n%s" % (old_note,matches[2])
else:
note = new_note
task(note)
return note return note
def parse_note(self,matches,obj,level,old_note): def parse_note(self,matches,obj,level,old_note):
@ -1489,7 +1518,7 @@ class GedcomParser:
event.set_cause(info) event.set_cause(info)
self.parse_cause(event,level+1) self.parse_cause(event,level+1)
elif matches[1] in (TOKEN_NOTE,TOKEN_OFFI): elif matches[1] in (TOKEN_NOTE,TOKEN_OFFI):
info = matches[2] info = self.parse_note(matches,event,level+1,note)
if note == "": if note == "":
note = info note = info
else: else:
@ -1548,7 +1577,7 @@ class GedcomParser:
event.set_cause(info) event.set_cause(info)
self.parse_cause(event,level+1) self.parse_cause(event,level+1)
elif matches[1] == TOKEN_NOTE: elif matches[1] == TOKEN_NOTE:
info = matches[2] info = self.parse_note(matches,event,level+1,note)
if note == "": if note == "":
note = info note = info
else: else:
@ -1604,7 +1633,7 @@ class GedcomParser:
elif matches[1] == TOKEN_DATE: elif matches[1] == TOKEN_DATE:
note = "%s\n\n" % ("Date : %s" % matches[2]) note = "%s\n\n" % ("Date : %s" % matches[2])
elif matches[1] == TOKEN_NOTE: elif matches[1] == TOKEN_NOTE:
info = matches[2] info = self.parse_note(matches,attr,level+1,note)
if note == "": if note == "":
note = info note = info
else: else:
@ -1741,6 +1770,7 @@ class GedcomParser:
def parse_header_source(self): def parse_header_source(self):
genby = "" genby = ""
note = ""
while True: while True:
matches = self.get_next() matches = self.get_next()
if int(matches[0]) < 1: if int(matches[0]) < 1:
@ -1788,7 +1818,7 @@ class GedcomParser:
date.date = matches[2] date.date = matches[2]
self.def_src.set_data_item('Creation date',matches[2]) self.def_src.set_data_item('Creation date',matches[2])
elif matches[1] == TOKEN_NOTE: elif matches[1] == TOKEN_NOTE:
note = matches[2] note = self.parse_note(matches,self.def_src,2,note)
elif matches[1] == TOKEN_UNKNOWN: elif matches[1] == TOKEN_UNKNOWN:
self.ignore_sub_junk(2) self.ignore_sub_junk(2)
else: else:
@ -2126,7 +2156,7 @@ class GedcomParser:
state.add_to_note(self.parse_optional_note(2)) state.add_to_note(self.parse_optional_note(2))
def func_person_famc(self,matches,state): def func_person_famc(self,matches,state):
ftype,note = self.parse_famc_type(2,state.person) ftype,famc_note = self.parse_famc_type(2,state.person)
handle = self.find_family_handle(matches[2][1:-1]) handle = self.find_family_handle(matches[2][1:-1])
for f in self.person.get_parent_family_handle_list(): for f in self.person.get_parent_family_handle_list():

View File

@ -325,16 +325,6 @@ def make_date(subdate,calendar,mode):
# #
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def fmtline(text,limit,level,endl):
new_text = []
while len(text) > limit:
new_text.append(text[0:limit-1])
text = text[limit:]
if len(text) > 0:
new_text.append(text)
app = "%s%d CONC " % (endl,level+1)
return app.join(new_text)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# #
@ -782,6 +772,36 @@ class GedcomWriter:
self.dump_event_stats(event) self.dump_event_stats(event)
for attr in family.get_attribute_list():
if self.private and attr.get_privacy():
continue
name = attr.get_type()
if name in ["AFN", "RFN", "_UID"]:
self.writeln("1 %s %s" % ( name, attr.get_value()))
continue
if Utils.personal_attributes.has_key(name):
val = Utils.personal_attributes[name]
else:
val = ""
value = self.cnvtxt(attr.get_value()).replace('\r',' ')
if val:
if value:
self.writeln("1 %s %s" % (val, value))
else:
self.writeln("1 %s" % val)
else:
self.writeln("1 EVEN")
if value:
self.writeln("2 TYPE %s %s" % (self.cnvtxt(name), value))
else:
self.writeln("2 TYPE %s" % self.cnvtxt(name))
if attr.get_note():
self.write_long_text("NOTE",2,self.cnvtxt(attr.get_note()))
for srcref in attr.get_source_references():
self.write_source_ref(2,srcref)
for person_handle in family.get_child_handle_list(): for person_handle in family.get_child_handle_list():
if not self.plist.has_key(person_handle): if not self.plist.has_key(person_handle):
continue continue
@ -815,6 +835,9 @@ class GedcomWriter:
continue continue
self.write_photo(photo,1) self.write_photo(photo,1)
if family.get_note():
self.write_long_text("NOTE",1,self.cnvtxt(family.get_note()))
self.write_change(1,family.get_change_time()) self.write_change(1,family.get_change_time())
self.update() self.update()
@ -831,11 +854,17 @@ class GedcomWriter:
for (source_id, source) in sorted: for (source_id, source) in sorted:
self.writeln("0 @%s@ SOUR" % source_id) self.writeln("0 @%s@ SOUR" % source_id)
if source.get_title(): if source.get_title():
self.writeln("1 TITL %s" % fmtline(self.cnvtxt(source.get_title()),248,1,self.nl)) self.write_long_text('TITL',1,
"%s" % self.cnvtxt(source.get_title()))
if source.get_author(): if source.get_author():
self.writeln("1 AUTH %s" % self.cnvtxt(source.get_author())) self.write_long_text("AUTH", 1,
"%s" % self.cnvtxt(source.get_author()))
if source.get_publication_info(): if source.get_publication_info():
self.writeln("1 PUBL %s" % self.cnvtxt(source.get_publication_info())) self.write_long_text("PUBL", 1,"%s" % self.cnvtxt(
source.get_publication_info()))
if source.get_abbreviation(): if source.get_abbreviation():
self.writeln("1 ABBR %s" % self.cnvtxt(source.get_abbreviation())) self.writeln("1 ABBR %s" % self.cnvtxt(source.get_abbreviation()))
if self.images: if self.images:
@ -1113,6 +1142,10 @@ class GedcomWriter:
else: else:
for line in textlines: for line in textlines:
ll = len(line) ll = len(line)
if ll == 0:
self.writeln("%s " % prefix)
prefix = "%d CONT" % (level+1)
continue
while ll > 0: while ll > 0:
brkpt = 70 brkpt = 70
if ll > brkpt: if ll > brkpt:
@ -1142,6 +1175,10 @@ class GedcomWriter:
else: else:
for line in textlines: for line in textlines:
ll = len(line) ll = len(line)
if ll == 0:
self.writeln("%s " % prefix)
prefix = "%d CONT" % (level+1)
continue
while ll > 0: while ll > 0:
brkpt = 70 brkpt = 70
if ll > brkpt: if ll > brkpt:

View File

@ -47,7 +47,7 @@ import Config
try: try:
ICON = pixbuf_new_from_file(const.icon) ICON = pixbuf_new_from_file(const.icon)
except: except:
pass ICON = None
class SaveDialog: class SaveDialog:
def __init__(self,msg1,msg2,task1,task2,parent=None): def __init__(self,msg1,msg2,task1,task2,parent=None):

View File

@ -231,7 +231,8 @@ class Person(PrimaryObject,SourceBase,NoteBase,MediaBase,
elif classname == 'Family': elif classname == 'Family':
return handle in (self.family_list + self.parent_family_list) return handle in (self.family_list + self.parent_family_list)
elif classname == 'Place': elif classname == 'Place':
return handle in self.lds_ord_list return handle in [ordinance.place for ordinance
in self.lds_ord_list]
return False return False
def _remove_handle_references(self, classname, handle_list): def _remove_handle_references(self, classname, handle_list):
@ -255,9 +256,9 @@ class Person(PrimaryObject,SourceBase,NoteBase,MediaBase,
if handle not in handle_list ] if handle not in handle_list ]
self.parent_family_list = new_list self.parent_family_list = new_list
elif classname == 'Place': elif classname == 'Place':
for ordinance in self.lds_ord_list: new_list = [ordinance for ordinance in self.lds_ord_list
if ordinance.place in handle_list: if ordinance.place not in handle_list]
ordinance.place = None self.lds_ord_list = new_list
def _replace_handle_reference(self, classname, old_handle, new_handle): def _replace_handle_reference(self, classname, old_handle, new_handle):
if classname == 'Event': if classname == 'Event':
@ -285,9 +286,11 @@ class Person(PrimaryObject,SourceBase,NoteBase,MediaBase,
ix = self.parent_family_list.index(old_handle) ix = self.parent_family_list.index(old_handle)
self.parent_family_list[ix] = new_handle self.parent_family_list[ix] = new_handle
elif classname == 'Place': elif classname == 'Place':
for ordinance in self.lds_ord_list: handle_list = [ordinance.place for ordinance in self.lds_ord_list]
if ordinance.place == old_handle: while old_handle in handle_list:
ordinance.place = new_handle ix = handle_list.index(old_handle)
self.lds_ord_list[ix].place = new_handle
handle_list[ix] = ''
def get_text_data_list(self): def get_text_data_list(self):
""" """

View File

@ -1,7 +1,7 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2005 Donald N. Allingham # Copyright (C) 2005-2006 Donald N. Allingham
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@ -46,11 +46,16 @@ try:
import locale import locale
lang = locale.getlocale()[0] lang = locale.getlocale()[0]
gtkspell.Spell(gtk.TextView()).set_language(lang) if lang == None:
success = True print _("Spelling checker cannot be used without language set.")
print _("Set your locale appropriately to use spelling checker.")
else:
gtkspell.Spell(gtk.TextView()).set_language(lang)
success = True
except ImportError, msg: except ImportError, msg:
print _("Spelling checker is not installed") print _("Spelling checker is not installed")
except TypeError,msg:
print "Spell.py: ", msg
except RuntimeError,msg: except RuntimeError,msg:
print "Spell.py: ", msg print "Spell.py: ", msg
except SystemError,msg: except SystemError,msg:

View File

@ -630,7 +630,7 @@ def probably_alive(person,db,current_year=None,limit=0):
death = db.get_event_from_handle(person.death_ref.ref) death = db.get_event_from_handle(person.death_ref.ref)
if death.get_date_object().get_start_date() != RelLib.Date.EMPTY: if death.get_date_object().get_start_date() != RelLib.Date.EMPTY:
death_year = death.get_date_object().get_year() death_year = death.get_date_object().get_year()
if death_year - limit < current_year: if death_year + limit < current_year:
return False return False
# Look for Cause Of Death, Burial or Cremation events. # Look for Cause Of Death, Burial or Cremation events.
@ -643,7 +643,7 @@ def probably_alive(person,db,current_year=None,limit=0):
if not death_year: if not death_year:
death_year = ev.get_date_object().get_year() death_year = ev.get_date_object().get_year()
if ev.get_date_object().get_start_date() != RelLib.Date.EMPTY: if ev.get_date_object().get_start_date() != RelLib.Date.EMPTY:
if ev.get_date_object().get_year() - limit < current_year: if ev.get_date_object().get_year() + limit < current_year:
return False return False
# For any other event of this person, check whether it happened # For any other event of this person, check whether it happened
# too long ago. If so then the person is likely dead now. # too long ago. If so then the person is likely dead now.

265
src/date_test.py Normal file
View File

@ -0,0 +1,265 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Martin Hawlisch, 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: date_test.py,v 1.1.2.5 2006/04/20 04:04:31 rshura Exp $
"""Testscript for date displayer/parser"""
import os
import sys
import traceback
import locale
import gettext
import gtk
if os.environ.has_key("GRAMPSI18N"):
loc = os.environ["GRAMPSI18N"]
else:
loc = "/usr/share/locale"
try:
locale.setlocale(locale.LC_ALL,'C')
locale.setlocale(locale.LC_ALL,'')
except locale.Error:
pass
except ValueError:
pass
gettext.textdomain("gramps")
gettext.install("gramps",loc,unicode=1)
import DateHandler
from DateHandler import parser as _dp
from DateHandler import displayer as _dd
import Date
print locale.getlocale(locale.LC_TIME)
print _dd
print _dp
print
date_tests = {}
# first the "basics".
testset = "basic test"
dates = []
calendar = Date.CAL_GREGORIAN
for quality in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, Date.QUAL_CALCULATED):
for modifier in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, Date.MOD_ABOUT):
for month in range(1,13):
d = Date.Date()
d.set(quality,modifier,calendar,(4,month,1789,False),"Text comment")
dates.append( d)
for modifier in (Date.MOD_RANGE, Date.MOD_SPAN):
for month1 in range(1,13):
for month2 in range(1,13):
d = Date.Date()
d.set(quality,modifier,calendar,(4,month1,1789,False,5,month2,1876,False),"Text comment")
dates.append( d)
modifier = Date.MOD_TEXTONLY
d = Date.Date()
d.set(quality,modifier,calendar,Date.EMPTY,"This is a textual date")
dates.append( d)
date_tests[testset] = dates
# incomplete dates (day or month missing)
testset = "partial date"
dates = []
calendar = Date.CAL_GREGORIAN
for quality in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, Date.QUAL_CALCULATED):
for modifier in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, Date.MOD_ABOUT):
d = Date.Date()
d.set(quality,modifier,calendar,(0,11,1789,False),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(0,0,1789,False),"Text comment")
dates.append( d)
for modifier in (Date.MOD_RANGE, Date.MOD_SPAN):
d = Date.Date()
d.set(quality,modifier,calendar,(4,10,1789,False,0,11,1876,False),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(4,10,1789,False,0,0,1876,False),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(0,10,1789,False,5,11,1876,False),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(0,10,1789,False,0,11,1876,False),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(0,10,1789,False,0,0,1876,False),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(0,0,1789,False,5,11,1876,False),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(0,0,1789,False,0,11,1876,False),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(0,0,1789,False,0,0,1876,False),"Text comment")
dates.append( d)
date_tests[testset] = dates
# slash-dates
testset = "slash-dates"
dates = []
calendar = Date.CAL_GREGORIAN
for quality in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, Date.QUAL_CALCULATED):
for modifier in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, Date.MOD_ABOUT):
# normal date
d = Date.Date()
d.set(quality,modifier,calendar,(4,11,1789,True),"Text comment")
dates.append( d)
for modifier in (Date.MOD_RANGE, Date.MOD_SPAN):
d = Date.Date()
d.set(quality,modifier,calendar,(4,11,1789,True,5,10,1876,False),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(4,11,1789,False,5,10,1876,True),"Text comment")
dates.append( d)
d = Date.Date()
d.set(quality,modifier,calendar,(4,11,1789,True,5,10,1876,True),"Text comment")
dates.append( d)
date_tests[testset] = dates
# BCE
testset = "B. C. E."
dates = []
calendar = Date.CAL_GREGORIAN
for quality in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, Date.QUAL_CALCULATED):
for modifier in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, Date.MOD_ABOUT):
# normal date
d = Date.Date()
d.set(quality,modifier,calendar,(4,11,-90,False),"Text comment")
dates.append( d)
for modifier in (Date.MOD_RANGE, Date.MOD_SPAN):
d = Date.Date()
d.set(quality,modifier,calendar,(5,10,-90,False,4,11,-90,False),"Text comment")
dates.append( d)
d = Date.Date()
date_tests[testset] = dates
# test for all other different calendars
testset = "Non-gregorian"
dates = []
for calendar in (Date.CAL_JULIAN, Date.CAL_HEBREW, Date.CAL_ISLAMIC, Date.CAL_FRENCH, Date.CAL_PERSIAN):
for quality in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, Date.QUAL_CALCULATED):
for modifier in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, Date.MOD_ABOUT):
d = Date.Date()
d.set(quality,modifier,calendar,(4,11,1789,False),"Text comment")
dates.append( d)
for modifier in (Date.MOD_RANGE, Date.MOD_SPAN):
d = Date.Date()
d.set(quality,modifier,calendar,(4,10,1789,False,5,11,1876,False),"Text comment")
dates.append( d)
quality = Date.QUAL_NONE
modifier = Date.MOD_NONE
for calendar in (Date.CAL_JULIAN, Date.CAL_ISLAMIC, Date.CAL_PERSIAN):
for month in range(1,13):
d = Date.Date()
d.set(quality,modifier,calendar,(4,month,1789,False),"Text comment")
dates.append( d)
for calendar in (Date.CAL_HEBREW, Date.CAL_FRENCH):
for month in range(1,14):
d = Date.Date()
d.set(quality,modifier,calendar,(4,month,1789,False),"Text comment")
dates.append( d)
date_tests[testset] = dates
# now run the tests using all available date formats
cal_str = [ "CAL_GREGORIAN", "CAL_JULIAN", "CAL_HEBREW", "CAL_FRENCH", "CAL_PERSIAN", "CAL_ISLAMIC"]
mod_str = ["MOD_NONE", "MOD_BEFORE", "MOD_AFTER", "MOD_ABOUT", "MOD_RANGE", "MOD_SPAN", "MOD_TEXTONLY"]
qua_str = ["QUAL_NONE", "QUAL_ESTIMATED", "QUAL_CALCULATED"]
stats = {}
formats = DateHandler.get_date_formats()
for testset in date_tests.keys():
print "\n##### %s:\n" % testset
stats[testset] = [0,0,testset]
for format in range( len( DateHandler.get_date_formats())):
DateHandler.set_format(format)
print "\n## %s:\n" % DateHandler.get_date_formats()[format]
for dateval in date_tests[testset]:
failed = True
ex = None
errmsg = ""
datestr = None
ndate = None
ntxt = None
if dateval.modifier != Date.MOD_TEXTONLY:
dateval.text = "Comment. Format: %s" % DateHandler.get_date_formats()[format]
try:
datestr = _dd.display( dateval)
try:
ndate = _dp.parse( datestr)
ntxt = _dd.display( ndate)
if ndate:
if dateval.is_equal( ndate):
failed = False
else:
if dateval.modifier != Date.MOD_TEXTONLY and ndate.modifier == Date.MOD_TEXTONLY:
errmsg = "FAILED! (was parsed as text)"
else:
errmsg = "FAILED!"
else:
errmsg = "FAILED: DateParser returned no Date"
except:
ex = "Parser"
errmsg = "FAILED: DateParser Exception %s" % ("".join(traceback.format_exception(*sys.exc_info())),)
except:
ex = "Display"
errmsg = "FAILED: DateDisplay Exception: %s" % ("".join(traceback.format_exception(*sys.exc_info())),)
if not failed:
stats[testset][1] = stats[testset][1] + 1
print datestr
print ntxt
print "ok"
else:
stats[testset][0] = stats[testset][0] + 1
print "input was:"
print " calendar: %s" % cal_str[dateval.calendar]
print " modifier: %s" % mod_str[dateval.modifier]
print " quality: %s" % qua_str[dateval.quality]
print " dateval: %s" % str(dateval.dateval)
print " text: '%s'" % dateval.text
if ex == "Display":
print "This date is not displayable because of an Exception:"
print errmsg
else:
print "DateDisplay gives: '%s'" % datestr
if ex == "Parser":
print "This date is not parsable because of an Exception:"
print errmsg
else:
print "parsed date was:"
print " calendar: %s" % cal_str[ndate.calendar]
print " modifier: %s" % mod_str[ndate.modifier]
print " quality: %s" % qua_str[ndate.quality]
print " dateval: %s" % str(ndate.dateval)
print " text: '%s'" % ndate.text
print "this gives:'%s'" % ntxt
print
print "RESULT:"
for result in stats:
print "% 13s: % 5d dates ok, % 4d failed." % (stats[result][2],stats[result][1],stats[result][0])

View File

@ -101,7 +101,7 @@ class ODFDoc(BaseDoc.BaseDoc):
def init(self): def init(self):
assert(self.init_called==False) assert (not self.init_called)
self.init_called = True self.init_called = True
current_locale = locale.getlocale() current_locale = locale.getlocale()
@ -164,8 +164,6 @@ class ODFDoc(BaseDoc.BaseDoc):
self.cntnt.write(' >\n') self.cntnt.write(' >\n')
self.cntnt.write('<style:graphic-properties ') self.cntnt.write('<style:graphic-properties ')
print(" get_line_width donne %.5f " % style.get_line_width() )
print(" pour le style %s" % style_name )
if style.get_line_width(): if style.get_line_width():
self.cntnt.write('svg:stroke-width="%.2f" ' % (style.get_line_width()*10)) self.cntnt.write('svg:stroke-width="%.2f" ' % (style.get_line_width()*10))
self.cntnt.write('draw:marker-start="" ') self.cntnt.write('draw:marker-start="" ')
@ -175,7 +173,6 @@ class ODFDoc(BaseDoc.BaseDoc):
self.cntnt.write('draw:textarea-horizontal-align="center" ') self.cntnt.write('draw:textarea-horizontal-align="center" ')
self.cntnt.write('draw:textarea-vertical-align="middle" ') self.cntnt.write('draw:textarea-vertical-align="middle" ')
else: else:
print(" get_line_width non defini : style %s" % style_name )
self.cntnt.write('draw:stroke="none" ') self.cntnt.write('draw:stroke="none" ')
self.cntnt.write('draw:stroke-color="#000000" ') self.cntnt.write('draw:stroke-color="#000000" ')
@ -346,7 +343,7 @@ class ODFDoc(BaseDoc.BaseDoc):
self.cntnt.write('<style:style style:name="Left" style:family="graphic"') self.cntnt.write('<style:style style:name="Left" style:family="graphic"')
self.cntnt.write(' style:parent-style-name="photo">') self.cntnt.write(' style:parent-style-name="photo">')
self.cntnt.write('<style:graphic-properties style:run-through="foreground"') self.cntnt.write('<style:graphic-properties style:run-through="foreground"')
self.cntnt.write(' style:wrap="parallel"') self.cntnt.write(' style:wrap="dynamic"')
self.cntnt.write(' style:number-wrapped-paragraphs="no-limit"') self.cntnt.write(' style:number-wrapped-paragraphs="no-limit"')
self.cntnt.write(' style:wrap-contour="false" style:vertical-pos="from-top"') self.cntnt.write(' style:wrap-contour="false" style:vertical-pos="from-top"')
self.cntnt.write(' style:vertical-rel="paragraph-content"') self.cntnt.write(' style:vertical-rel="paragraph-content"')
@ -461,7 +458,7 @@ class ODFDoc(BaseDoc.BaseDoc):
self.cntnt.write('text:anchor-type="paragraph" ') self.cntnt.write('text:anchor-type="paragraph" ')
self.cntnt.write('svg:width="%.2fcm" ' % act_width) self.cntnt.write('svg:width="%.2fcm" ' % act_width)
self.cntnt.write('svg:height="%.2fcm" ' % act_height) self.cntnt.write('svg:height="%.2fcm" ' % act_height)
self.cntnt.write('draw:z-index="0" >') self.cntnt.write('draw:z-index="1" >')
self.cntnt.write('<draw:image xlink:href="Pictures/') self.cntnt.write('<draw:image xlink:href="Pictures/')
self.cntnt.write(base) self.cntnt.write(base)
self.cntnt.write('" xlink:type="simple" xlink:show="embed" ') self.cntnt.write('" xlink:type="simple" xlink:show="embed" ')

View File

@ -99,7 +99,7 @@ class OpenOfficeDoc(BaseDoc.BaseDoc):
def init(self): def init(self):
assert(self.init_called==False) assert (not self.init_called)
self.init_called = True self.init_called = True
self.lang = Utils.xml_lang() self.lang = Utils.xml_lang()
@ -314,7 +314,7 @@ class OpenOfficeDoc(BaseDoc.BaseDoc):
self.cntnt.write('<style:style style:name="Left" style:family="graphics"') self.cntnt.write('<style:style style:name="Left" style:family="graphics"')
self.cntnt.write(' style:parent-style-name="photo">') self.cntnt.write(' style:parent-style-name="photo">')
self.cntnt.write('<style:properties style:run-through="foreground"') self.cntnt.write('<style:properties style:run-through="foreground"')
self.cntnt.write(' style:wrap="parallel"') self.cntnt.write(' style:wrap="dynamic"')
self.cntnt.write(' style:number-wrapped-paragraphs="no-limit"') self.cntnt.write(' style:number-wrapped-paragraphs="no-limit"')
self.cntnt.write(' style:wrap-contour="false" style:vertical-pos="from-top"') self.cntnt.write(' style:wrap-contour="false" style:vertical-pos="from-top"')
self.cntnt.write(' style:vertical-rel="paragraph-content"') self.cntnt.write(' style:vertical-rel="paragraph-content"')

View File

@ -1,7 +1,7 @@
# #
# Gramps - a GTK+/GNOME based genealogy program # Gramps - a GTK+/GNOME based genealogy program
# #
# Copyright (C) 2000-2004 Donald N. Allingham # Copyright (C) 2000-2006 Donald N. Allingham
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@ -204,12 +204,12 @@ class OpenSpreadSheet(SpreadSheetDoc):
def _write_zip(self): def _write_zip(self):
file = zipfile.ZipFile(self.filename,"w",zipfile.ZIP_DEFLATED) the_file = zipfile.ZipFile(self.filename,"w",zipfile.ZIP_DEFLATED)
file.write(self.manifest_xml,str("META-INF/manifest.xml")) the_file.write(self.manifest_xml,str("META-INF/manifest.xml"))
file.write(self.content_xml,str("content.xml")) the_file.write(self.content_xml,str("content.xml"))
file.write(self.meta_xml,str("meta.xml")) the_file.write(self.meta_xml,str("meta.xml"))
file.write(self.styles_xml,str("styles.xml")) the_file.write(self.styles_xml,str("styles.xml"))
file.close() the_file.close()
os.unlink(self.manifest_xml) os.unlink(self.manifest_xml)
os.unlink(self.content_xml) os.unlink(self.content_xml)

View File

@ -310,6 +310,8 @@ class PdfDoc(BaseDoc.BaseDoc):
self.tblstyle.append(('LINEABOVE', loc, loc, 1, black)) self.tblstyle.append(('LINEABOVE', loc, loc, 1, black))
if self.my_table_style.get_bottom_border(): if self.my_table_style.get_bottom_border():
self.tblstyle.append(('LINEBELOW', loc, loc, 1, black)) self.tblstyle.append(('LINEBELOW', loc, loc, 1, black))
# Set the alignment
if p.get_alignment() == BaseDoc.PARA_ALIGN_LEFT: if p.get_alignment() == BaseDoc.PARA_ALIGN_LEFT:
self.tblstyle.append(('ALIGN', loc, loc, 'LEFT')) self.tblstyle.append(('ALIGN', loc, loc, 'LEFT'))
elif p.get_alignment() == BaseDoc.PARA_ALIGN_RIGHT: elif p.get_alignment() == BaseDoc.PARA_ALIGN_RIGHT:
@ -326,6 +328,13 @@ class PdfDoc(BaseDoc.BaseDoc):
#if self.span != 1: #if self.span != 1:
# self.tblstyle.append(('SPAN', (self.col, self.row), (self.col + self.span - 1, self.row ) )) # self.tblstyle.append(('SPAN', (self.col, self.row), (self.col + self.span - 1, self.row ) ))
# The following lines will enable the span feature.
# This is nice, except when spanning, lines that would have overfilled
# their cells still increase the height of the cell to make room for the
# wrapped text (even though the text does not actually wrap because it is spanned)
#if self.span != 1:
# self.tblstyle.append(('SPAN', (self.col, self.row), (self.col + self.span - 1, self.row ) ))
self.col = self.col + self.span self.col = self.col + self.span
self.text = "" self.text = ""
@ -336,6 +345,9 @@ class PdfDoc(BaseDoc.BaseDoc):
return return
x,y = img.size() x,y = img.size()
if (x,y) == (0,0):
return
if (x,y) == (0,0): if (x,y) == (0,0):
return return

View File

@ -349,6 +349,9 @@ class RTFDoc(BaseDoc.BaseDoc):
nx,ny = im.size() nx,ny = im.size()
if (nx,ny) == (0,0):
return
if (nx,ny) == (0,0): if (nx,ny) == (0,0):
return return

View File

@ -69,7 +69,7 @@ import ListModel
from PluginUtils import Plugins, Report, ReportOptions, \ from PluginUtils import Plugins, Report, ReportOptions, \
bkitems_list, register_report bkitems_list, register_report
import BaseDoc import BaseDoc
from QuestionDialog import WarningDialog from QuestionDialog import WarningDialog, ErrorDialog
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -710,7 +710,7 @@ class BookReportSelector:
self.book.append_item(item) self.book.append_item(item)
data = [ item.get_translated_name(), item.get_category(), item.get_name() ] data = [ item.get_translated_name(), item.get_category(), item.get_name() ]
if data[2] == 'simple_book_title': if data[2] in ('simple_book_title','custom_text'):
data.append(_("Not Applicable")) data.append(_("Not Applicable"))
else: else:
pname = self.db.get_person_from_gramps_id(person_id) pname = self.db.get_person_from_gramps_id(person_id)
@ -727,7 +727,7 @@ class BookReportSelector:
if not the_iter: if not the_iter:
return return
data = self.av_model.get_data(the_iter,range(self.av_ncols)) data = self.av_model.get_data(the_iter,range(self.av_ncols))
if data[2] == 'simple_book_title': if data[2] in ('simple_book_title','custom_text'):
data.append(_("Not Applicable")) data.append(_("Not Applicable"))
else: else:
data.append(self.person.get_primary_name().get_regular_name()) data.append(self.person.get_primary_name().get_regular_name())

View File

@ -661,7 +661,7 @@ class CalendarOptions(NewReportOptions):
help = "Include holidays", help = "Include holidays",
valid_text = "Select to include holidays", valid_text = "Select to include holidays",
), ),
NumberWidget(self, label = "Offset", NumberWidget(self, label = _("Offset"),
name = "offset", name = "offset",
value = -0.5, value = -0.5,
help = "Distance to move text on page", help = "Distance to move text on page",

View File

@ -45,6 +45,8 @@ from PluginUtils import Report, ReportOptions, ReportUtils, register_report
pt2cm = ReportUtils.pt2cm pt2cm = ReportUtils.pt2cm
import BaseDoc import BaseDoc
from SubstKeywords import SubstKeywords from SubstKeywords import SubstKeywords
import Errors
import NameDisplay
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #

View File

@ -469,9 +469,9 @@ register_report(
report_class = DescendChart, report_class = DescendChart,
options_class = DescendChartOptions, options_class = DescendChartOptions,
modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI, modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI,
translated_name = _("Descendant Graph"), translated_name = _("Descendant Chart"),
status = _("Stable"), status = _("Stable"),
author_name = "Donald N. Allingham", author_name = "Donald N. Allingham",
author_email = "don@gramps-project.org", author_email = "don@gramps-project.org",
description = _("Produces a graphical descendant tree graph"), description = _("Produces a graphical descendant tree chart"),
) )

View File

@ -254,7 +254,7 @@ class DisplayChart(ManagedWindow.ManagedWindow):
def on_help_clicked(self,obj): def on_help_clicked(self,obj):
"""Display the relevant portion of GRAMPS manual""" """Display the relevant portion of GRAMPS manual"""
help('gramps-manual','tools-ae') help('tools-ae')
def build_menu_names(self,obj): def build_menu_names(self,obj):
return (_("Event Comparison Results"),None) return (_("Event Comparison Results"),None)

View File

@ -22,13 +22,6 @@
"Generate files/Family Group Report" "Generate files/Family Group Report"
#------------------------------------------------------------------------
#
# python modules
#
#------------------------------------------------------------------------
from gettext import gettext as _
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
# Gnome/GTK modules # Gnome/GTK modules
@ -46,6 +39,7 @@ from PluginUtils import Report, ReportOptions, register_report
import BaseDoc import BaseDoc
import DateHandler import DateHandler
import Utils import Utils
from TransUtils import sgettext as _
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -361,6 +355,42 @@ class FamilyGroup(Report.Report):
self.doc.end_table() self.doc.end_table()
def dump_marriage(self,family):
if not family:
return
m = None
family_list = family.get_event_list()
for event_handle in family_list:
if event_handle:
event = self.database.get_event_from_handle(event_handle)
if event.get_name() == "Marriage":
m = event
break
if len(family_list) > 0 or self.missingInfo:
self.doc.start_table(("MarriageInfo"),'FGR-ParentTable')
self.doc.start_row()
self.doc.start_cell('FGR-ParentHead',3)
self.doc.start_paragraph('FGR-ParentName')
self.doc.write_text(_("Marriage:"))
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.end_row()
self.dump_parent_event(_("Marriage"),m)
for event_handle in family_list:
if event_handle:
event = self.database.get_event_from_handle(event_handle)
if event.get_name() != "Marriage":
self.dump_parent_event(event.get_name(),event)
self.doc.end_table()
def dump_child_event(self,text,name,event): def dump_child_event(self,text,name,event):
date = "" date = ""
place = "" place = ""
@ -425,10 +455,11 @@ class FamilyGroup(Report.Report):
else: else:
self.doc.start_cell('FGR-TextChild2') self.doc.start_cell('FGR-TextChild2')
self.doc.start_paragraph('FGR-ChildText') self.doc.start_paragraph('FGR-ChildText')
index_str = ("%d" % index)
if person.get_gender() == RelLib.Person.MALE: if person.get_gender() == RelLib.Person.MALE:
self.doc.write_text(_("%dM") % index) self.doc.write_text(index_str + _("acronym for male|M"))
elif person.get_gender() == RelLib.Person.FEMALE: elif person.get_gender() == RelLib.Person.FEMALE:
self.doc.write_text(_("%dF") % index) self.doc.write_text(index_str + _("acronym for female|F"))
else: else:
self.doc.write_text(_("%dU") % index) self.doc.write_text(_("%dU") % index)
self.doc.end_paragraph() self.doc.end_paragraph()

View File

@ -505,7 +505,7 @@ class EditFilter:
def on_help_clicked(self,obj): def on_help_clicked(self,obj):
"""Display the relevant portion of GRAMPS manual""" """Display the relevant portion of GRAMPS manual"""
help_display('gramps-manual','tools-util-cfe') GrampsDisplay.help('tools-util-cfe')
def on_delete_event(self,obj,b): def on_delete_event(self,obj,b):
pass pass
@ -748,7 +748,7 @@ class EditRule:
def on_help_clicked(self,obj): def on_help_clicked(self,obj):
"""Display the relevant portion of GRAMPS manual""" """Display the relevant portion of GRAMPS manual"""
help_display('gramps-manual','append-filtref') GrampsDisplay.help('append-filtref')
def on_delete_event(self,obj,b): def on_delete_event(self,obj,b):
self.remove_itself_from_menu() self.remove_itself_from_menu()

View File

@ -78,18 +78,38 @@ class _options:
) )
fonts = ( fonts = (
# Last items tells whether strings need to be converted to Latin1 # Last items tells whether strings need to be converted to Latin1
("", "Default", _("Default"), 1), ("", "Default", _("Default")),
("Helvetica", "Postscript / Helvetica", _("Postscript / Helvetica"), 1), ("Helvetica", "Postscript / Helvetica", _("Postscript / Helvetica")),
("FreeSans", "Truetype / FreeSans", _("Truetype / FreeSans"), 0), ("FreeSans", "Truetype / FreeSans", _("Truetype / FreeSans")),
) )
colors = ( colors = (
("outline", "B&W Outline", _("B&W outline")), ("outline", "B&W Outline", _("B&W outline")),
("colored", "Colored outline", _("Colored outline")), ("colored", "Colored outline", _("Colored outline")),
("filled", "Color fill", _("Color fill")), ("filled", "Color fill", _("Color fill")),
) )
ratio = (
("compress", "Minimal size", _("Minimal size")),
("fill", "Fill the given area", _("Fill the given area")),
("expand", "Automatically use optimal number of pages",
_("Automatically use optimal number of pages"))
)
rankdir = ( rankdir = (
("TB", "Vertical", _("Vertical")),
("LR", "Horizontal", _("Horizontal")), ("LR", "Horizontal", _("Horizontal")),
("RL", "Vertical", _("Vertical")), )
pagedir = (
("BL", "Bottom, left", _("Bottom, left")),
("BR", "Bottom, right", _("Bottom, right")),
("TL", "Top, left", _("Top, left")),
("TR", "Top, right", _("Top, Right")),
("RB", "Right, bottom", _("Right, bottom")),
("RT", "Right, top", _("Right, top")),
("LB", "Left, bottom", _("Left, bottom")),
("LT", "Left, top", _("Left, top")),
)
noteloc = (
("t", "Top", _("Top")),
("b", "Bottom", _("Bottom")),
) )
arrowstyles = ( arrowstyles = (
('d', "Descendants <- Ancestors", _("Descendants <- Ancestors")), ('d', "Descendants <- Ancestors", _("Descendants <- Ancestors")),
@ -98,7 +118,11 @@ class _options:
('', "Descendants - Ancestors", _("Descendants - Ancestors")), ('', "Descendants - Ancestors", _("Descendants - Ancestors")),
) )
dot_found = os.system("dot -V 2>/dev/null") == 0 _dot_found = os.system("dot -V 2>/dev/null") == 0
if os.system("which epstopdf >/dev/null 2>&1") == 0:
_options.formats += (("pdf", "PDF", _("PDF"), "application/pdf"),)
_pdf_pipe = 'epstopdf -f -o=%s'
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -124,7 +148,7 @@ class GraphViz:
The option class carries its number, and the function The option class carries its number, and the function
returning the list of filters. returning the list of filters.
font - Font to use. font - Font to use.
latin - Set if font supports only Latin1 latin - Set if text needs to be converted to latin-1
arrow - Arrow styles for heads and tails. arrow - Arrow styles for heads and tails.
showfamily - Whether to show family nodes. showfamily - Whether to show family nodes.
incid - Whether to include IDs. incid - Whether to include IDs.
@ -132,12 +156,17 @@ class GraphViz:
justyears - Use years only. justyears - Use years only.
placecause - Whether to replace missing dates with place or cause placecause - Whether to replace missing dates with place or cause
url - Whether to include URLs. url - Whether to include URLs.
rankdir - Graph direction rankdir - Graph direction, LR or RL
ratio - Output aspect ration, fill/compress/auto
color - Whether to use outline, colored outline or filled color in graph color - Whether to use outline, colored outline or filled color in graph
dashedl - Whether to use dashed lines for non-birth relationships. dashedl - Whether to use dashed lines for non-birth relationships.
margin - Margins, in cm. margin - Margins, in cm.
pagesh - Number of pages in horizontal direction. pagesh - Number of pages in horizontal direction.
pagesv - Number of pages in vertical direction. pagesv - Number of pages in vertical direction.
pagedir - Paging direction
note - Note to add to the graph
notesize - Note font size (in points)
noteloc - Note location t/b
""" """
colored = { colored = {
'male': 'dodgerblue4', 'male': 'dodgerblue4',
@ -160,11 +189,14 @@ class GraphViz:
self.height = self.paper.get_height_inches() self.height = self.paper.get_height_inches()
options = options_class.handler.options_dict options = options_class.handler.options_dict
self.pagedir = options['pagedir']
self.hpages = options['pagesh'] self.hpages = options['pagesh']
self.vpages = options['pagesv'] self.vpages = options['pagesv']
margin_cm = options['margin'] margin_cm = options['margin']
self.margin = round(margin_cm/2.54,2) self.margin = round(margin_cm/2.54,2)
if margin_cm > 0.1: if margin_cm > 0.1:
# GraphViz has rounding errors so have to make the real
# margins slightly smaller than (page - content size)
self.margin_small = round((margin_cm-0.1)/2.54,2) self.margin_small = round((margin_cm-0.1)/2.54,2)
else: else:
self.margin_small = 0 self.margin_small = 0
@ -176,8 +208,8 @@ class GraphViz:
self.just_years = options['justyears'] self.just_years = options['justyears']
self.placecause = options['placecause'] self.placecause = options['placecause']
self.rankdir = options['rankdir'] self.rankdir = options['rankdir']
self.ratio = options['ratio']
self.fontname = options['font'] self.fontname = options['font']
self.latin = options['latin']
self.colorize = options['color'] self.colorize = options['color']
if self.colorize == 'colored': if self.colorize == 'colored':
self.colors = colored self.colors = colored
@ -193,189 +225,295 @@ class GraphViz:
else: else:
self.arrowtailstyle = 'none' self.arrowtailstyle = 'none'
self.latin = options['latin']
self.noteloc = options['noteloc']
self.notesize = options['notesize']
self.note = options['note']
filter_num = options_class.get_filter_number() filter_num = options_class.get_filter_number()
filters = options_class.get_report_filters(person) filters = options_class.get_report_filters(person)
filters.extend(GenericFilter.CustomFilters.get_filters()) filters.extend(GenericFilter.CustomFilters.get_filters())
self.filter = filters[filter_num] self.filter = filters[filter_num]
self.f = open(options_class.get_output(),'w') the_buffer = self.get_report()
self.write_report() if self.latin:
self.f.write(the_buffer.encode('iso-8859-1'))
else:
self.f.write(the_buffer)
self.f.close() self.f.close()
def write_report(self): def get_report(self):
"return string of the .dot file contents"
self.ind_list = self.filter.apply(self.database, self.person_handles = self.filter.apply(self.database,
self.database.get_person_handles(sort_handles=False)) self.database.get_person_handles(sort_handles=False))
self.write_header() # graph size
self.f.write("digraph GRAMPS_relationship_graph {\n")
self.f.write("bgcolor=white;\n")
self.f.write("rankdir=%s;\n" % self.rankdir)
self.f.write("center=1;\n")
self.f.write("margin=%3.2f;\n" % self.margin_small)
self.f.write("ratio=fill;\n")
if self.orient == PAPER_LANDSCAPE: if self.orient == PAPER_LANDSCAPE:
self.f.write("size=\"%3.2f,%3.2f\";\n" % ( rotate = 90
(self.height-self.margin*2)*self.hpages, sizew = (self.height - self.margin*2) * self.hpages
(self.width-self.margin*2)*self.vpages sizeh = (self.width - self.margin*2) * self.vpages
))
else: else:
self.f.write("size=\"%3.2f,%3.2f\";\n" % ( rotate = 0
(self.width-self.margin*2)*self.hpages, sizew = (self.width - self.margin*2) * self.hpages
(self.height-self.margin*2)*self.vpages sizeh = (self.height - self.margin*2) * self.vpages
))
self.f.write("page=\"%3.2f,%3.2f\";\n" % (self.width,self.height))
buffer = self.get_comment_header()
buffer += """
digraph GRAMPS_relationship_graph {
/* whole graph attributes */
bgcolor=white;
center=1;
ratio=%s;
rankdir=%s;
mclimit=2.0;
margin="%3.2f";
pagedir="%s";
page="%3.2f,%3.2f";
size="%3.2f,%3.2f";
rotate=%d;
/* default node and edge attributes */
nodesep=0.25;
edge [syle=solid, arrowhead=%s arrowtail=%s];
""" % (
self.ratio,
self.rankdir,
self.margin_small,
self.pagedir,
self.width, self.height,
sizew, sizeh,
rotate,
self.arrowheadstyle,
self.arrowtailstyle
)
if self.orient == PAPER_LANDSCAPE: if self.fontname:
self.f.write("rotate=90;\n") font = 'fontname="%s"' % self.fontname
else:
font = ''
if self.colorize == 'filled':
buffer += 'node [style=filled %s];\n' % font
else:
buffer += 'node [%s];\n' % font
if self.latin:
# GraphViz default is UTF-8
buffer += 'charset="iso-8859-1";\n'
if len(self.person_handles) > 1:
buffer += "/* persons and their families */\n"
buffer += self.get_persons_and_families()
buffer += "/* link children to families */\n"
buffer += self.get_child_links_to_families()
if len(self.ind_list) > 1: if self.note:
self.dump_index() buffer += 'labelloc="%s";\n' % self.noteloc
self.dump_person() buffer += 'label="%s";\n' % self.note.replace('\n', '\\n').replace('"', '\\\"')
buffer += 'fontsize="%d";\n' % self.notesize # in points
self.f.write("}\n") return buffer + "}\n"
def dump_person(self):
# Hash people in a dictionary for faster inclusion checking. def get_comment_header(self):
"return comment of Gramps options which are not Graphviz options"
return """/*
GRAMPS - Relationship graph
Generated on %s.
Report content options:
include URLs : %s
IDs : %s
dates : %s
just year : %s
place or cause : %s
colorize : %s
dotted adoptions : %s
show family nodes : %s
pages horizontal : %s
vertical : %s
For other options, see graph settings below.
If you need to switch between iso-8859-1 and utf-8 text encodings,
e.g. because you're using different font or -T output format,
just use iconv:
iconv -f iso-8859-1 -t utf-8 old.dot > new.dot
iconv -t utf-8 -f iso-8859-1 old.dot > new.dot
*/
""" % (
asctime(),
bool(self.includeurl),
bool(self.includeid),
bool(self.includedates),
bool(self.just_years),
bool(self.placecause),
bool(self.colorize),
bool(self.adoptionsdashed),
bool(self.show_families),
self.hpages, self.vpages
)
def get_child_links_to_families(self):
"returns string of GraphViz edges linking parents to families or children"
person_dict = {} person_dict = {}
for p_id in self.ind_list: # Hash people in a dictionary for faster inclusion checking
person_dict[p_id] = 1 for person_handle in self.person_handles:
person_dict[person_handle] = 1
for person_handle in self.ind_list: the_buffer = ""
for person_handle in self.person_handles:
person = self.database.get_person_from_handle(person_handle) person = self.database.get_person_from_handle(person_handle)
pid = person.get_gramps_id().replace('-','_') p_id = person.get_gramps_id()
for family_handle in person.get_parent_family_handle_list(): for fam_handle in person.get_parent_family_handle_list():
family = self.database.get_family_from_handle(family_handle) family = self.database.get_family_from_handle(fam_handle)
madopted = False
fadopted = False
for child_ref in family.get_child_ref_list():
if child_ref.ref == person_handle:
fadopted = child_ref.frel != RelLib.ChildRefType.BIRTH
madopted = child_ref.mrel != RelLib.ChildRefType.BIRTH
father_handle = family.get_father_handle() father_handle = family.get_father_handle()
mother_handle = family.get_mother_handle() mother_handle = family.get_mother_handle()
famid = family.get_gramps_id().replace('-','_') for child_ref in family.get_child_ref_list():
if child_ref.ref == person_handle:
frel = child_ref.frel
mrel = child_ref.mrel
break
if (self.show_families and if (self.show_families and
(father_handle and person_dict.has_key(father_handle) or ((father_handle and father_handle in person_dict) or
mother_handle and person_dict.has_key(mother_handle))): (mother_handle and mother_handle in person_dict))):
# Link to the family node. # Link to the family node if either parent is in graph
self.f.write('p%s -> f%s [' % (pid, famid)) the_buffer += self.get_family_link(p_id,family,frel,mrel)
self.f.write('arrowhead=%s, arrowtail=%s, ' %
(self.arrowheadstyle, self.arrowtailstyle))
if self.adoptionsdashed and (fadopted or madopted):
self.f.write('style=dotted')
else:
self.f.write('style=solid')
self.f.write('];\n')
else: else:
# Link to the parents' nodes directly. # Link to the parents' nodes directly, if they are in graph
if father_handle and person_dict.has_key(father_handle): if father_handle and father_handle in person_dict:
father = self.database.get_person_from_handle(father_handle) the_buffer += self.get_parent_link(p_id,father_handle,frel)
fid = father.get_gramps_id().replace('-','_') if mother_handle and mother_handle in person_dict:
self.f.write('p%s -> p%s [' % (pid, fid)) the_buffer += self.get_parent_link(p_id,mother_handle,mrel)
self.f.write('arrowhead=%s, arrowtail=%s, ' % return the_buffer
(self.arrowheadstyle, self.arrowtailstyle))
if self.adoptionsdashed and fadopted:
self.f.write('style=dotted')
else:
self.f.write('style=solid')
self.f.write('];\n')
if mother_handle and person_dict.has_key(mother_handle):
mother = self.database.get_person_from_handle(mother_handle)
mid = mother.get_gramps_id().replace('-','_')
self.f.write('p%s -> p%s [' % (pid, mid))
self.f.write('arrowhead=%s, arrowtail=%s, ' %
(self.arrowheadstyle, self.arrowtailstyle))
if self.adoptionsdashed and madopted:
self.f.write('style=dotted')
else:
self.f.write('style=solid')
self.f.write('];\n')
def dump_index(self):
# The list of families for which we have output the node, so we
# don't do it twice.
families_done = []
for person_handle in self.ind_list:
person = self.database.get_person_from_handle(person_handle)
# Output the person's node.
label = person.get_primary_name().get_name()
the_id = person.get_gramps_id().replace('-','_')
if self.includeid:
label = label + " (%s)" % the_id
if self.includedates:
birth_ref = person.get_birth_ref()
if birth_ref:
birth_event = self.database.get_event_from_handle(birth_ref.ref)
birth = self.dump_event(birth_event)
else:
birth = ''
death_ref = person.get_death_ref()
if death_ref:
death_event = self.database.get_event_from_handle(death_ref.ref)
death = self.dump_event(death_event)
else:
death = ''
label = label + '\\n(%s - %s)' % (birth, death)
self.f.write('p%s [shape=box, ' % the_id)
if self.includeurl:
h = person.get_handle()
self.f.write('URL="ppl/%s/%s/%s.html", ' % (h[0],h[1],h))
if self.colorize != 'outline':
if self.colorize == 'filled':
style = 'style=filled, fillcolor'
else:
style = 'color'
gender = person.get_gender()
if gender == person.MALE:
self.f.write('%s=%s, ' % (style, self.colors['male']))
elif gender == person.FEMALE:
self.f.write('%s=%s, ' % (style, self.colors['female']))
else:
self.f.write('%s=%s, ' % (style, self.colors['unknown']))
if self.latin:
label = label.encode('iso-8859-1')
self.f.write('fontname="%s", label="%s"];\n' % (self.fontname,label))
# Output families's nodes. def get_family_link(self, p_id, family, frel, mrel):
"returns string of GraphViz edge linking child to family"
style = ''
adopted = ((int(frel) != RelLib.ChildRefType.BIRTH) or
(int(mrel) != RelLib.ChildRefType.BIRTH))
if adopted and self.adoptionsdashed:
style = 'style=dotted'
return '"p%s" -> "f%s" [%s];\n' % (p_id,
family.get_gramps_id(), style)
def get_parent_link(self, p_id, parent_handle, rel):
"returns string of GraphViz edge linking child to parent"
style = ''
if (int(rel) != RelLib.ChildRefType.BIRTH) and self.adoptionsdashed:
style = 'style=dotted'
parent = self.database.get_person_from_handle(parent_handle)
return '"p%s" -> "p%s" [%s];\n' % (p_id, parent.get_gramps_id(), style)
def get_persons_and_families(self):
"returns string of GraphViz nodes for persons and their families"
# The list of families for which we have output the node,
# so we don't do it twice
buffer = ""
families_done = {}
for person_handle in self.person_handles:
person = self.database.get_person_from_handle(person_handle)
p_id = person.get_gramps_id()
# Output the person's node
label = self.get_person_label(person)
style = self.get_gender_style(person)
url = ""
if self.includeurl:
h = person_handle
url = ', URL="ppl/%s/%s/%s.html", ' % (h[0],h[1],h)
buffer += '"p%s" [label="%s", %s%s];\n' % (p_id, label, style, url)
# Output families where person is a parent
if self.show_families: if self.show_families:
family_list = person.get_family_handle_list() family_list = person.get_family_handle_list()
for fam_handle in family_list: for fam_handle in family_list:
fam = self.database.get_family_from_handle(fam_handle) fam = self.database.get_family_from_handle(fam_handle)
fid = fam.get_gramps_id().replace('-','_') fam_id = fam.get_gramps_id()
if fam_handle not in families_done: if fam_handle not in families_done:
families_done.append(fam_handle) families_done[fam_handle] = 1
self.f.write('f%s [shape=ellipse, ' % fid) label = ""
if self.colorize == 'colored':
self.f.write('color=%s, ' % self.colors['family'])
elif self.colorize == 'filled':
self.f.write('style=filled fillcolor=%s, ' % self.colors['family'])
marriage = ""
for event_ref in fam.get_event_ref_list(): for event_ref in fam.get_event_ref_list():
if event_ref: event = self.database.get_event_from_handle(
event = self.database.get_event_from_handle(event_ref.ref) event_ref.ref)
if int(event.get_type()) == RelLib.EventType.MARRIAGE: if int(event.get_type()) == RelLib.EventType.MARRIAGE:
m = event label = self.get_event_string(event)
break break
else:
m = None
if m:
marriage = self.dump_event(m)
if self.includeid: if self.includeid:
marriage = marriage + " (%s)" % fid label = "%s (%s)" % (label, fam_id)
self.f.write('fontname="%s", label="%s"];\n' color = ""
% (self.fontname,marriage)) if self.colorize == 'colored':
color = ', color="%s"' % self.colors['family']
elif self.colorize == 'filled':
color = ', fillcolor="%s"' % self.colors['family']
buffer += '"f%s" [shape=ellipse, label="%s"%s];\n' % (fam_id, label, color)
# Link this person to all his/her families. # Link this person to all his/her families.
self.f.write('f%s -> p%s [' % (fid, the_id)) buffer += '"f%s" -> "p%s";\n' % (fam_id, p_id)
self.f.write('arrowhead=%s, arrowtail=%s, ' % return buffer
(self.arrowheadstyle, self.arrowtailstyle))
self.f.write('style=solid];\n') def get_gender_style(self, person):
"return gender specific person style"
gender = person.get_gender()
if gender == person.MALE:
shape = 'shape="box"'
elif gender == person.FEMALE:
shape = 'shape="box", style="rounded"'
else:
shape = 'shape="hexagon"'
if self.colorize == 'outline':
return shape
else:
if gender == person.MALE:
color = self.colors['male']
elif gender == person.FEMALE:
color = self.colors['female']
else:
color = self.colors['unknown']
if self.colorize == 'filled':
# In current GraphViz boxes cannot be both rounded and filled
return 'shape="box", fillcolor="%s"' % color
else:
return '%s, color="%s"' % (shape, color)
def get_person_label(self, person):
"return person label string"
label = person.get_primary_name().get_name()
p_id = person.get_gramps_id()
if self.includeid:
label = label + " (%s)" % p_id
if self.includedates:
birth, death = self.get_date_strings(person)
label = label + '\\n(%s - %s)' % (birth, death)
return label.replace('"', '\\\"')
def dump_event(self,event): def get_date_strings(self, person):
"returns tuple of birth/christening and death/burying date strings"
birth_ref = person.get_birth_ref()
if birth_ref:
birth_event = self.database.get_event_from_handle(birth_ref.ref)
birth = self.get_event_string(birth_event)
else:
birth = ''
death_ref = person.get_death_ref()
if death_ref:
death_event = self.database.get_event_from_handle(death_ref)
death = self.get_event_string(death_event)
else:
death = ''
if birth and death:
return (birth, death)
# missing info, use (first) christening/burial instead
for event_ref in person.get_event_ref_list():
event = self.database.get_event_from_handle(event_ref.ref)
if int(event.get_type()) == RelLib.EventType.CHRISTEN:
if not birth:
birth = self.get_event_string(event)
elif int(event.get_type()) == RelLib.EventType.BURIAL:
if not death:
death = self.get_event_string(event)
return (birth, death)
def get_event_string(self, event):
""" """
Compile an event label. return string for for an event label.
Based on the data availability and preferences, we select one Based on the data availability and preferences, we select one
of the following for a given event: of the following for a given event:
@ -399,33 +537,6 @@ class GraphViz:
return event.get_cause() return event.get_cause()
return '' return ''
def write_header(self):
"""
Write header listing the options used.
"""
self.f.write("/* GRAMPS - Relationship graph\n")
self.f.write(" *\n")
self.f.write(" * Report options:\n")
self.f.write(" * font style : %s\n" % self.fontname)
self.f.write(" * style arrow head : %s\n" % self.arrowheadstyle)
self.f.write(" * tail : %s\n" % self.arrowtailstyle)
self.f.write(" * graph direction : %s\n" % self.rankdir)
self.f.write(" * include URLs : %s\n" % bool(self.includeurl))
self.f.write(" * IDs : %s\n" % bool(self.includeid))
self.f.write(" * dates : %s\n" % bool(self.includedates))
self.f.write(" * just year : %s\n" % bool(self.just_years))
self.f.write(" * place or cause : %s\n" % bool(self.placecause))
self.f.write(" * colorize : %s\n" % bool(self.colorize))
self.f.write(" * dotted adoptions : %s\n" % bool(self.adoptionsdashed))
self.f.write(" * show family nodes : %s\n" % bool(self.show_families))
self.f.write(" * margin : %3.2fin\n" % self.margin_small)
self.f.write(" * pages horizontal : %s\n" % self.hpages)
self.f.write(" * vertical : %s\n" % self.vpages)
self.f.write(" * page width : %3.2fin\n" % self.width)
self.f.write(" * height : %3.2fin\n" % self.height)
self.f.write(" *\n")
self.f.write(" * Generated on %s by GRAMPS\n" % asctime())
self.f.write(" */\n\n")
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -453,12 +564,17 @@ class GraphVizOptions(ReportOptions.ReportOptions):
'justyears' : 0, 'justyears' : 0,
'placecause' : 1, 'placecause' : 1,
'url' : 1, 'url' : 1,
'ratio' : "compress",
'rankdir' : "LR", 'rankdir' : "LR",
'color' : "filled", 'color' : "filled",
'dashedl' : 1, 'dashedl' : 1,
'margin' : 1.0, 'margin' : 1.0,
'pagedir' : 'BL',
'pagesh' : 1, 'pagesh' : 1,
'pagesv' : 1, 'pagesv' : 1,
'note' : '',
'noteloc' : 'b',
'notesize' : 32,
'gvof' : 'ps', 'gvof' : 'ps',
} }
@ -490,7 +606,10 @@ class GraphVizOptions(ReportOptions.ReportOptions):
'url' : ("=0/1","Whether to include URLs.", 'url' : ("=0/1","Whether to include URLs.",
["Do not include URLs","Include URLs"], ["Do not include URLs","Include URLs"],
True), True),
'rankdir' : ("=str","Graph direction.", 'ratio' : ("=str","Graph aspect ratio.",
[ "%s\t%s" % (item[0],item[1]) for item in _options.ratio ],
False),
'rankdir' : ("=str","Graph direction.",
[ "%s\t%s" % (item[0],item[1]) for item in _options.rankdir ], [ "%s\t%s" % (item[0],item[1]) for item in _options.rankdir ],
False), False),
'color' : ("=str","Whether and how to colorize graph.", 'color' : ("=str","Whether and how to colorize graph.",
@ -501,10 +620,20 @@ class GraphVizOptions(ReportOptions.ReportOptions):
True), True),
'margin' : ("=num","Margin size.", 'margin' : ("=num","Margin size.",
"Floating point value, in cm"), "Floating point value, in cm"),
'pagedir' : ("=str","Paging direction.",
[ "%s\t%s" % (item[0],item[1]) for item in _options.pagedir ],
False),
'pagesh' : ("=num","Number of pages in horizontal direction.", 'pagesh' : ("=num","Number of pages in horizontal direction.",
"Integer values"), "Integer values"),
'pagesv' : ("=num","Number of pages in vertical direction.", 'pagesv' : ("=num","Number of pages in vertical direction.",
"Integer values"), "Integer values"),
'note' : ("=str","Note to add to the graph.",
"Text"),
'notesize' : ("=num","Note size (in points).",
"Integer values"),
'noteloc' : ("=str","Note location.",
[ "%s\t%s" % (item[0],item[1]) for item in _options.noteloc ],
False),
'gvof' : ("=str","Output format to convert dot file into.", 'gvof' : ("=str","Output format to convert dot file into.",
[ "%s\t%s" % (item[0],item[1]) for item in _options.formats ], [ "%s\t%s" % (item[0],item[1]) for item in _options.formats ],
False), False),
@ -546,6 +675,22 @@ class GraphVizOptions(ReportOptions.ReportOptions):
def make_doc_menu(self,dialog,active=None): def make_doc_menu(self,dialog,active=None):
pass pass
def add_list(self, options, default):
"returns compobox of given options and default value"
box = gtk.ComboBox()
store = gtk.ListStore(str)
box.set_model(store)
cell = gtk.CellRendererText()
box.pack_start(cell,True)
box.add_attribute(cell,'text',0)
index = 0
for item in options:
store.append(row=[item[2]])
if item[0] == default:
box.set_active(index)
index = index + 1
return box
def add_user_options(self,dialog): def add_user_options(self,dialog):
if self.handler.module_name == "rel_graph2": if self.handler.module_name == "rel_graph2":
dialog.make_doc_menu = self.make_doc_menu dialog.make_doc_menu = self.make_doc_menu
@ -599,36 +744,8 @@ class GraphVizOptions(ReportOptions.ReportOptions):
_("Include individual and family IDs.")) _("Include individual and family IDs."))
# GraphViz output options tab # GraphViz output options tab
self.rank_box = gtk.ComboBox() self.color_box = self.add_list(_options.colors,
store = gtk.ListStore(str) self.options_dict['color'])
self.rank_box.set_model(store)
cell = gtk.CellRendererText()
self.rank_box.pack_start(cell,True)
self.rank_box.add_attribute(cell,'text',0)
index = 0
for item in _options.rankdir:
store.append(row=[item[2]])
if item[0] == self.options_dict['rankdir']:
self.rank_box.set_active(index)
index = index + 1
dialog.add_frame_option(_("GraphViz Options"),
_("Graph direction"),
self.rank_box,
_("Whether generations go from top to bottom "
"or left to right."))
self.color_box = gtk.ComboBox()
store = gtk.ListStore(str)
self.color_box.set_model(store)
cell = gtk.CellRendererText()
self.color_box.pack_start(cell,True)
self.color_box.add_attribute(cell,'text',0)
index = 0
for item in _options.colors:
store.append(row=[item[2]])
if item[0] == self.options_dict['color']:
self.color_box.set_active(index)
index = index + 1
dialog.add_frame_option(_("GraphViz Options"), dialog.add_frame_option(_("GraphViz Options"),
_("Graph coloring"), _("Graph coloring"),
self.color_box, self.color_box,
@ -636,39 +753,15 @@ class GraphVizOptions(ReportOptions.ReportOptions):
"with red. If the sex of an individual " "with red. If the sex of an individual "
"is unknown it will be shown with gray.")) "is unknown it will be shown with gray."))
self.arrowstyle_box = gtk.ComboBox() self.arrowstyle_box = self.add_list(_options.arrowstyles,
store = gtk.ListStore(str) self.options_dict['arrow'])
self.arrowstyle_box.set_model(store)
cell = gtk.CellRendererText()
self.arrowstyle_box.pack_start(cell,True)
self.arrowstyle_box.add_attribute(cell,'text',0)
index = 0
for item in _options.arrowstyles:
store.append(row=[item[2]])
if item[0] == self.options_dict['arrow']:
self.arrowstyle_box.set_active(index)
index = index + 1
dialog.add_frame_option(_("GraphViz Options"), dialog.add_frame_option(_("GraphViz Options"),
_("Arrowhead direction"), _("Arrowhead direction"),
self.arrowstyle_box, self.arrowstyle_box,
_("Choose the direction that the arrows point.")) _("Choose the direction that the arrows point."))
self.font_box = gtk.ComboBox() self.font_box = self.add_list(_options.fonts,
store = gtk.ListStore(str) self.options_dict['font'])
self.font_box.set_model(store)
cell = gtk.CellRendererText()
self.font_box.pack_start(cell,True)
self.font_box.add_attribute(cell,'text',0)
index = 0
for item in _options.fonts:
if item[3]:
name = "%s (iso-latin1 font)" % item[2]
else:
name = item[2]
store.append(row=[name])
if item[0] == self.options_dict['font']:
self.font_box.set_active(index)
index = index + 1
dialog.add_frame_option(_("GraphViz Options"), dialog.add_frame_option(_("GraphViz Options"),
_("Font family"), _("Font family"),
self.font_box, self.font_box,
@ -677,6 +770,13 @@ class GraphVizOptions(ReportOptions.ReportOptions):
"FreeSans is available from: " "FreeSans is available from: "
"http://www.nongnu.org/freefont/")) "http://www.nongnu.org/freefont/"))
self.latin_cb = gtk.CheckButton(_("Output format/font requires text as latin-1"))
self.latin_cb.set_active(self.options_dict['latin'])
dialog.add_frame_option(_("GraphViz Options"), '',
self.latin_cb,
_("If text doesn't show correctly in report, use this. "
"Required e.g. for default font with PS output."))
self.adoptionsdashed_cb = gtk.CheckButton(_("Indicate non-birth relationships with dotted lines")) self.adoptionsdashed_cb = gtk.CheckButton(_("Indicate non-birth relationships with dotted lines"))
self.adoptionsdashed_cb.set_active(self.options_dict['dashedl']) self.adoptionsdashed_cb.set_active(self.options_dict['dashedl'])
dialog.add_frame_option(_("GraphViz Options"), '', dialog.add_frame_option(_("GraphViz Options"), '',
@ -691,13 +791,30 @@ class GraphVizOptions(ReportOptions.ReportOptions):
_("Families will show up as ellipses, linked " _("Families will show up as ellipses, linked "
"to parents and children.")) "to parents and children."))
# Page options tab # Page/layout options tab
self.rank_box = self.add_list(_options.rankdir,
self.options_dict['rankdir'])
dialog.add_frame_option(_("Layout Options"),
_("Graph direction"),
self.rank_box,
_("Whether generations go from top to bottom "
"or left to right."))
self.ratio_box = self.add_list(_options.ratio,
self.options_dict['ratio'])
dialog.add_frame_option(_("Layout Options"),
_("Aspect ratio"),
self.ratio_box,
_("Affects greatly how the graph is layed out "
"on the page. Multiple pages overrides the "
"pages settings below."))
margin_adj = gtk.Adjustment(value=self.options_dict['margin'], margin_adj = gtk.Adjustment(value=self.options_dict['margin'],
lower=0.0, upper=10.0, step_incr=1.0) lower=0.0, upper=10.0, step_incr=1.0)
self.margin_sb = gtk.SpinButton(adjustment=margin_adj, digits=1) self.margin_sb = gtk.SpinButton(adjustment=margin_adj, digits=1)
dialog.add_frame_option(_("Page Options"), dialog.add_frame_option(_("Layout Options"),
_("Margin size"), _("Margin size"),
self.margin_sb) self.margin_sb)
@ -709,14 +826,14 @@ class GraphVizOptions(ReportOptions.ReportOptions):
self.hpages_sb = gtk.SpinButton(adjustment=hpages_adj, digits=0) self.hpages_sb = gtk.SpinButton(adjustment=hpages_adj, digits=0)
self.vpages_sb = gtk.SpinButton(adjustment=vpages_adj, digits=0) self.vpages_sb = gtk.SpinButton(adjustment=vpages_adj, digits=0)
dialog.add_frame_option(_("Page Options"), dialog.add_frame_option(_("Layout Options"),
_("Number of Horizontal Pages"), _("Number of Horizontal Pages"),
self.hpages_sb, self.hpages_sb,
_("GraphViz can create very large graphs by " _("GraphViz can create very large graphs by "
"spreading the graph across a rectangular " "spreading the graph across a rectangular "
"array of pages. This controls the number " "array of pages. This controls the number "
"pages in the array horizontally.")) "pages in the array horizontally."))
dialog.add_frame_option(_("Page Options"), dialog.add_frame_option(_("Layout Options"),
_("Number of Vertical Pages"), _("Number of Vertical Pages"),
self.vpages_sb, self.vpages_sb,
_("GraphViz can create very large graphs " _("GraphViz can create very large graphs "
@ -724,6 +841,41 @@ class GraphVizOptions(ReportOptions.ReportOptions):
"rectangular array of pages. This " "rectangular array of pages. This "
"controls the number pages in the array " "controls the number pages in the array "
"vertically.")) "vertically."))
self.pagedir_box = self.add_list(_options.pagedir,
self.options_dict['pagedir'])
dialog.add_frame_option(_("Layout Options"),
_("Paging direction"),
self.pagedir_box,
_("The order in which the graph pages are output."))
# Notes tab
self.textbox = gtk.TextView()
self.textbox.get_buffer().set_text(self.options_dict['note'])
self.textbox.set_editable(1)
swin = gtk.ScrolledWindow()
swin.set_shadow_type(gtk.SHADOW_IN)
swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
swin.add(self.textbox)
dialog.add_frame_option(_("Notes"),
_("Note to add to the graph"),
swin,
_("This text will be added to the graph."))
self.noteloc_box = self.add_list(_options.noteloc,
self.options_dict['noteloc'])
dialog.add_frame_option(_("Notes"),
_("Note location"),
self.noteloc_box,
_("Whether note will appear on top "
"or bottom of the page."))
notesize_adj = gtk.Adjustment(value=self.options_dict['notesize'],
lower=8, upper=128, step_incr=1)
self.notesize_sb = gtk.SpinButton(adjustment=notesize_adj, digits=0)
dialog.add_frame_option(_("Notes"),
_("Note size (in points)"),
self.notesize_sb,
_("The size of note text, in points."))
def toggle_date(self, obj): def toggle_date(self, obj):
self.just_years_cb.set_sensitive(self.includedates_cb.get_active()) self.just_years_cb.set_sensitive(self.includedates_cb.get_active())
@ -740,6 +892,8 @@ class GraphVizOptions(ReportOptions.ReportOptions):
self.options_dict['incid'] = int(self.includeid_cb.get_active()) self.options_dict['incid'] = int(self.includeid_cb.get_active())
self.options_dict['justyears'] = int(self.just_years_cb.get_active()) self.options_dict['justyears'] = int(self.just_years_cb.get_active())
self.options_dict['placecause'] = int(self.place_cause_cb.get_active()) self.options_dict['placecause'] = int(self.place_cause_cb.get_active())
self.options_dict['ratio'] = \
_options.ratio[self.ratio_box.get_active()][0]
self.options_dict['rankdir'] = \ self.options_dict['rankdir'] = \
_options.rankdir[self.rank_box.get_active()][0] _options.rankdir[self.rank_box.get_active()][0]
self.options_dict['color'] = \ self.options_dict['color'] = \
@ -748,8 +902,15 @@ class GraphVizOptions(ReportOptions.ReportOptions):
_options.arrowstyles[self.arrowstyle_box.get_active()][0] _options.arrowstyles[self.arrowstyle_box.get_active()][0]
self.options_dict['font'] = \ self.options_dict['font'] = \
_options.fonts[self.font_box.get_active()][0] _options.fonts[self.font_box.get_active()][0]
self.options_dict['latin'] = \ self.options_dict['pagedir'] = \
_options.fonts[self.font_box.get_active()][3] _options.pagedir[self.pagedir_box.get_active()][0]
self.options_dict['noteloc'] = \
_options.noteloc[self.noteloc_box.get_active()][0]
self.options_dict['notesize'] = self.notesize_sb.get_value_as_int()
b = self.textbox.get_buffer()
self.options_dict['note'] = \
b.get_text(b.get_start_iter(), b.get_end_iter(), False)
if self.handler.module_name == "rel_graph2": if self.handler.module_name == "rel_graph2":
self.options_dict['gvof'] = dialog.format_menu.get_format_str() self.options_dict['gvof'] = dialog.format_menu.get_format_str()
@ -837,7 +998,24 @@ class FormatComboBox(gtk.ComboBox):
return '.dot' return '.dot'
def get_printable(self): def get_printable(self):
return None _apptype = _options.formats[self.get_active()][3]
print_label = None
try:
import Utils
import GrampsMime
mprog = GrampsMime.get_application(_apptype)
if Utils.search_for(mprog[0]):
print_label = _("Open in %(program_name)s") % { 'program_name':
mprog[1]}
else:
print_label = None
except:
print_label = None
return print_label
def get_clname(self): def get_clname(self):
return 'dot' return 'dot'
@ -907,7 +1085,6 @@ class GraphicsFormatComboBox(gtk.ComboBox):
class EmptyDoc: class EmptyDoc:
def __init__(self,styles,type,template,orientation,source=None): def __init__(self,styles,type,template,orientation,source=None):
self.print_req = 0 self.print_req = 0
pass
def init(self): def init(self):
pass pass
@ -955,9 +1132,31 @@ class GraphVizGraphics(Report.Report):
GraphViz(self.database,self.start_person,self.options_class) GraphViz(self.database,self.start_person,self.options_class)
def end_report(self): def end_report(self):
os.system('dot -T%s -o%s %s ; rm %s' % if self.the_format == "pdf":
(self.the_format,self.user_output, command = ('dot -Tps %s | ' + _pdf_pipe + ' ; rm %s') % \
self.junk_output,self.junk_output)) (self.junk_output,self.user_output,self.junk_output)
os.system(command)
else:
os.system('dot -T%s -o%s %s ; rm %s' %
(self.the_format,self.user_output,
self.junk_output,self.junk_output))
if self.doc.print_req:
_apptype = None
for format in _options.formats:
if format[0] == self.the_format:
_apptype = format[3]
break
if _apptype:
try:
import Utils
import GrampsMime
app = GrampsMime.get_application(_apptype)
os.environ["FILE"] = self.user_output
os.system ('%s "$FILE" &' % app[0])
except:
pass
if self.doc.print_req: if self.doc.print_req:
_apptype = None _apptype = None
@ -1011,7 +1210,7 @@ register_report(
author_email="don@gramps-project.org" author_email="don@gramps-project.org"
) )
if dot_found: if _dot_found:
register_report( register_report(
name = 'rel_graph2', name = 'rel_graph2',
category = Report.CATEGORY_DRAW, category = Report.CATEGORY_DRAW,

View File

@ -153,6 +153,7 @@ class BasePage:
self.exclude_private = not options.handler.options_dict['NWEBincpriv'] self.exclude_private = not options.handler.options_dict['NWEBincpriv']
self.usegraph = options.handler.options_dict['NWEBgraph'] self.usegraph = options.handler.options_dict['NWEBgraph']
self.use_home = self.options.handler.options_dict['NWEBhomenote'] != "" self.use_home = self.options.handler.options_dict['NWEBhomenote'] != ""
self.page_title = ""
def store_file(self,archive,html_dir,from_path,to_path): def store_file(self,archive,html_dir,from_path,to_path):
if archive: if archive:
@ -901,7 +902,6 @@ class MediaPage(BasePage):
return None return None
def copy_thumbnail(self,handle,photo): def copy_thumbnail(self,handle,photo):
ext = os.path.splitext(photo.get_path())[1]
to_dir = self.build_path(handle,'thumb') to_dir = self.build_path(handle,'thumb')
to_path = os.path.join(to_dir,handle+".png") to_path = os.path.join(to_dir,handle+".png")
if photo.get_mime_type(): if photo.get_mime_type():
@ -923,16 +923,6 @@ class MediaPage(BasePage):
except IOError: except IOError:
print "Could not copy file" print "Could not copy file"
def copy_preview_image(handle,photo):
base = '/desktop/gnome/thumbnailers/%s' % mtype.replace('/','@')
thumbnailer = Config.client.get_string(base + '/command')
enable = Config.client.get_bool(base + '/enable')
if thumbnailer and enable:
run_thumbnailer(thumbnailer,path,_build_thumb_path(path),320)
return path
else:
return None
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
# #
@ -1284,8 +1274,6 @@ class ContactPage(BasePage):
self.store_file(archive,self.html_dir,obj.get_path(), self.store_file(archive,self.html_dir,obj.get_path(),
newpath) newpath)
dirpath = self.build_path(note_id,'img')
of.write('<div class="rightwrap">\n') of.write('<div class="rightwrap">\n')
of.write('<table><tr>') of.write('<table><tr>')
of.write('<td height="205">') of.write('<td height="205">')
@ -2050,6 +2038,7 @@ class WebReport(Report.Report):
NWEBhomenote NWEBhomenote
NWEBnoid NWEBnoid
""" """
self.database = database self.database = database
self.start_person = person self.start_person = person
self.options = options self.options = options
@ -2196,7 +2185,6 @@ class WebReport(Report.Report):
# people rule # people rule
if self.restrict: if self.restrict:
self.progress.set_pass(_('Filtering living people'),len(ind_list)) self.progress.set_pass(_('Filtering living people'),len(ind_list))
new_list = []
for key in ind_list: for key in ind_list:
self.progress.step() self.progress.step()
p = self.database.get_person_from_handle(key) p = self.database.get_person_from_handle(key)
@ -2331,19 +2319,6 @@ class WebReport(Report.Report):
def base_pages(self, photo_list, archive): def base_pages(self, photo_list, archive):
if self.use_home:
index_page = "index"
surname_page = "surnames"
intro_page = "introduction"
elif self.use_intro:
index_page = ""
surname_page = "surnames"
intro_page = "index"
else:
index_page = ""
surname_page = "index"
intro_page = ""
if self.use_home: if self.use_home:
HomePage(self.database, self.title, self.options, archive, photo_list) HomePage(self.database, self.title, self.options, archive, photo_list)
@ -2380,7 +2355,7 @@ class WebReportOptions(ReportOptions.ReportOptions):
Defines options and provides handling interface. Defines options and provides handling interface.
""" """
def __init__(self,name,database,person_id=None): def __init__(self,name,database=None,person_id=None):
ReportOptions.ReportOptions.__init__(self,name,person_id) ReportOptions.ReportOptions.__init__(self,name,person_id)
self.db = database self.db = database
@ -2556,18 +2531,21 @@ class WebReportOptions(ReportOptions.ReportOptions):
title = _("Page Generation") title = _("Page Generation")
cursor = self.db.get_media_cursor()
media_list = [['','']] media_list = [['','']]
html_list = [['','']] html_list = [['','']]
data = cursor.first()
while data: if self.db:
(handle, value) = data cursor = self.db.get_media_cursor()
if value[3]: data = cursor.first()
media_list.append([value[4],handle]) while data:
else: (handle, value) = data
html_list.append([value[4],handle]) if value[3]:
data = cursor.next() media_list.append([value[4],handle])
cursor.close() else:
html_list.append([value[4],handle])
data = cursor.next()
cursor.close()
media_list.sort() media_list.sort()
html_list.sort() html_list.sort()
@ -2901,7 +2879,7 @@ register_report(
category = Report.CATEGORY_WEB, category = Report.CATEGORY_WEB,
report_class = WebReportDialog, report_class = WebReportDialog,
options_class = cl_report, options_class = cl_report,
modes = Report.MODE_GUI, modes = Report.MODE_GUI | Report.MODE_CLI,
translated_name = _("Narrative Web Site"), translated_name = _("Narrative Web Site"),
status = _("Stable"), status = _("Stable"),
author_name="Donald N. Allingham", author_name="Donald N. Allingham",

View File

@ -80,10 +80,6 @@ class PackageWriter:
def __init__(self,database,filename,callback): def __init__(self,database,filename,callback):
self.db = database self.db = database
self.callback = callback self.callback = callback
if os.path.splitext(filename)[1] != ".gpkg":
filename = filename + ".gpkg"
self.filename = filename self.filename = filename
def export(self): def export(self):

View File

@ -154,7 +154,7 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
other_birth_event = other_person.get_birth() other_birth_event = other_person.get_birth()
other_birth_date = other_birth_event.get_date_object() other_birth_date = other_birth_event.get_date_object()
if (orig_birth_date == "")or(other_birth_date == "") :return 0 if (orig_birth_date == "")or(other_birth_date == "") :return 0
else :return RelLib.Date.compare_dates(orig_birth_date,other_birth_date) else :return orig_birth_date>other_birth_date
def get_age_brother (self,level): def get_age_brother (self,level):
@ -203,7 +203,7 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
family = self.db.get_family_from_handle(g) family = self.db.get_family_from_handle(g)
if family: if family:
if sp_id in family.get_child_handle_list(): if sp_id in family.get_child_handle_list():
return [sp] return [sp_id]
return [] return []
#------------------------------------------------------------------------ #------------------------------------------------------------------------
@ -246,7 +246,7 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if family: if family:
c = family.get_child_handle_list() c = family.get_child_handle_list()
if (other.get_handle() in c) and (sp_id in c): if (other.get_handle() in c) and (sp_id in c):
return [sp] return [sp_id]
return [] return []
#------------------------------------------------------------------------- #-------------------------------------------------------------------------

231
src/plugins/rel_sk.py Normal file
View File

@ -0,0 +1,231 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2005 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: rel_sk.py,v 1.1.2.1 2006/03/16 16:22:27 rshura Exp $
# Slovak terms added by Lubo Vasko
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import RelLib
import Relationship
import types
from gettext import gettext as _
#-------------------------------------------------------------------------
#
#Slovak-specific definitions of relationships
#
#-------------------------------------------------------------------------
_level_name = [ "", "prvého", "druhého", "tretieho", "štvrtého", "piateho", "šiesteho",
"siedmeho", "ôsmeho", "deviateho", "desiateho", "jedenásteho", "dvanásteho",
"trinásteho", "štrnásteho", "pätnásteho", "šestnásteho",
"sedemnásteho", "osemnásteho", "devätnásteho", "dvadsiateho", "dvadsiatehoprvého", "dvadsiatehodruhého",
"dvadsiatehotretieho", "dvadsiatehoštvrtého","dvadsiatehopiateho","dvadsiatehošiesteho","dvadsiatehosiedmeho",
"dvadsiatehoôsmeho","dvadsiatehodeviateho","tridsiateho" ]
_parents_level = [ "", "rodičia", "starí rodičia", "prarodičia",
"vzdialení príbuzní", ]
_father_level = [ "", "otec", "starý otec", "prastarý otec", "prapredok", ]
_mother_level = [ "", "matka", "stará matka", "prastará matka", "prapredok", ]
_son_level = [ "", "syn", "vnuk", "pravnuk", ]
_daughter_level = [ "", "dcéra", "vnučka", "pravnučka", ]
_sister_level = [ "", "sestra", "teta", "prateta", "praprateta", ]
_brother_level = [ "", "brat", "strýko", "prastrýko", "praprastrýko", ]
_nephew_level = [ "", "synovec", "prasynovec", "praprasynovec", ]
_niece_level = [ "", "neter", "praneter", "prapraneter", ]
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
class RelationshipCalculator(Relationship.RelationshipCalculator):
def __init__(self,db):
Relationship.RelationshipCalculator.__init__(self,db)
def get_male_cousin(self,level):
if level>len(_level_name)-1:
return "vzdialený príbuzný"
else:
return "bratranec %s stupňa" % (_level_name[level])
def get_female_cousin(self,level):
if level>len(_level_name)-1:
return "vzdialená príbuzná"
else:
return "sesternica %s stupňa" % (_level_name[level])
def get_parents(self,level):
if level>len(_parents_level)-1:
return "vzdialení príbuzní"
else:
return _parents_level[level]
def get_father(self,level):
if level>len(_father_level)-1:
return "vzdialený príbuzný"
else:
return _father_level[level]
def get_son(self,level):
if level>len(_son_level)-1:
return "vzdialený potomok"
else:
return _son_level[level]
def get_mother(self,level):
if level>len(_mother_level)-1:
return "vzdialený predok"
else:
return _mother_level[level]
def get_daughter(self,level):
if level>len(_daughter_level)-1:
return "vzdialený potomok"
else:
return _daughter_level[level]
def get_aunt(self,level):
if level>len(_sister_level)-1:
return "vzdialený predok"
else:
return _sister_level[level]
def get_uncle(self,level):
if level>len(_brother_level)-1:
return "vzdialený predok"
else:
return _brother_level[level]
def get_nephew(self,level):
if level>len(_nephew_level)-1:
return "vzdialený potomok"
else:
return _nephew_level[level]
def get_niece(self,level):
if level>len(_niece_level)-1:
return "vzdialený potomok"
else:
return _niece_level[level]
def get_relationship(self,orig_person,other_person):
"""
Returns a string representing the relationshp between the two people,
along with a list of common ancestors (typically father,mother)
Special cases: relation strings "", "undefined" and "spouse".
"""
if orig_person == None:
return ("undefined",[])
if orig_person.get_handle() == other_person.get_handle():
return ('', [])
is_spouse = self.is_spouse(orig_person,other_person)
if is_spouse:
return (is_spouse,[])
(firstRel,secondRel,common) = self.get_relationship_distance(orig_person,other_person)
if type(common) == types.StringType or type(common) == types.UnicodeType:
return (common,[])
elif common:
person_handle = common[0]
else:
return ("",[])
firstRel = len(firstRel)
secondRel = len(secondRel)
if firstRel == 0:
if secondRel == 0:
return ('',common)
elif other_person.get_gender() == RelLib.Person.MALE:
return (self.get_father(secondRel),common)
else:
return (self.get_mother(secondRel),common)
elif secondRel == 0:
if other_person.get_gender() == RelLib.Person.MALE:
return (self.get_son(firstRel),common)
else:
return (self.get_daughter(firstRel),common)
elif firstRel == 1:
if other_person.get_gender() == RelLib.Person.MALE:
return (self.get_uncle(secondRel),common)
else:
return (self.get_aunt(secondRel),common)
elif secondRel == 1:
if other_person.get_gender() == RelLib.Person.MALE:
return (self.get_nephew(firstRel-1),common)
else:
return (self.get_niece(firstRel-1),common)
elif firstRel == 2 and secondRel == 2:
if other_person.get_gender() == RelLib.Person.MALE:
return ('vlastný bratranec',common)
else:
return ('vlastná sesternica',common)
elif firstRel == 3 and secondRel == 2:
if other_person.get_gender() == RelLib.Person.MALE:
return ('bratranec druhého stupňa',common)
else:
return ('sesternica druhého stupňa',common)
elif firstRel == 2 and secondRel == 3:
if other_person.get_gender() == RelLib.Person.MALE:
return ('bratranec druhého stupňa',common)
else:
return ('sesternica druhého stupňa',common)
else:
if other_person.get_gender() == RelLib.Person.MALE:
if firstRel+secondRel>len(_level_name)-1:
return (self.get_male_cousin(firstRel+secondRel),common)
else:
return ('vzdialený bratranec',common)
else:
if firstRel+secondRel>len(_level_name)-1:
return (self.get_female_cousin(firstRel+secondRel),common)
else:
return ('vzdialená sesternica',common)
#-------------------------------------------------------------------------
#
# Register this class with the Plugins system
#
#-------------------------------------------------------------------------
from PluginMgr import register_relcalc
register_relcalc(RelationshipCalculator,
["sk", "SK", "sk_SK", "slovensky", "slovak", "Slovak", "sk_SK.UTF8", "sk_SK.UTF-8", "sk_SK.utf-8", "sk_SK.utf8"])

33
test/dates.sh Executable file
View File

@ -0,0 +1,33 @@
#! /bin/sh
#
# Date Handler test for GRAMPS:
# o Run date_test.py for every available locale.
# $Id: dates.sh,v 1.1.2.2 2006/04/15 20:21:03 loshawlos Exp $
TOP_DIR=`dirname $PWD`
SRC_DIR=$TOP_DIR/src
PRG="python date_test.py"
export PYTHONPATH=$SRC_DIR
# Get the list of xx_XX language codes
LANG_LIST=`locale -a | grep _ | cut -f 1 -d . | sort | uniq`
for lang in $LANG_LIST; do
# for each xx_XX language code, try all available locales
LOC_LIST=`locale -a | grep $lang`
false
for loc in $LOC_LIST; do
export LANG=$loc
# Run test
res=`cd $SRC_DIR && $PRG`
# Print results
echo "$res"
if [ $?=0 ]; then
# Finish with this LANG if succeeded.
echo "Done testing $LANG"
read -p" ENTER to continue "
break
fi
done
done

View File

@ -1,8 +1,13 @@
#! /bin/sh #! /bin/sh
# #
# Import/export test for GRAMPS: Import example XML data and create GRDB, # Import/export test for GRAMPS:
# check data for integrity, output in all formats, check resulting XML for # o Import example XML data and create GRDB
# well-formedness and validate it against DTD and RelaxNG schema. # o Open produced GRDB, then
# * check data for integrity
# * output in all formats
# o Check resulting XML for well-formedness and validate it
# against DTD and RelaxNG schema.
# o Import ever file produced and run summary on it.
# $Id$ # $Id$
@ -13,6 +18,7 @@ PRG="python gramps.py"
EXAMPLE_XML=$TOP_DIR/example/gramps/example.gramps EXAMPLE_XML=$TOP_DIR/example/gramps/example.gramps
OUT_FMT="gedcom gramps-xml gramps-pkg wft geneweb" OUT_FMT="gedcom gramps-xml gramps-pkg wft geneweb"
IN_FMT="gedcom gramps-xml gramps-pkg"
DATA_DIR=$TEST_DIR/data DATA_DIR=$TEST_DIR/data
mkdir -p $DATA_DIR mkdir -p $DATA_DIR
if [ -f $DATA_DIR/example.grdb ]; then if [ -f $DATA_DIR/example.grdb ]; then
@ -53,3 +59,12 @@ echo "* Post-parsing DTD validation"
xmllint --noout --postvalid $DATA_DIR/example.gramps-xml xmllint --noout --postvalid $DATA_DIR/example.gramps-xml
echo "* Validate against RelaxNG schema" echo "* Validate against RelaxNG schema"
xmllint --noout --relaxng $TOP_DIR/doc/grampsxml.rng $DATA_DIR/example.gramps-xml xmllint --noout --relaxng $TOP_DIR/doc/grampsxml.rng $DATA_DIR/example.gramps-xml
echo ""
echo "+--------------------------------------------------------------"
echo "| Import all produced files and print summary"
echo "+--------------------------------------------------------------"
for fmt in $IN_FMT; do
OPTS="-i $DATA_DIR/example.$fmt -f $fmt -a summary"
(cd $SRC_DIR; $PRG $OPTS)
done