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>
* 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>
* pt_BR.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/_DateParser.py
src/DateHandler/_Date_ru.py
src/DateHandler/_Date_sk.py
src/DateHandler/_Date_sv.py
src/DateHandler/__init__.py
src/docgen/AbiWord2Doc.py
@ -218,6 +219,7 @@ src/plugins/rel_hu.py
src/plugins/rel_it.py
src/plugins/rel_no.py
src/plugins/rel_ru.py
src/plugins/rel_sk.py
src/plugins/rel_sv.py
src/plugins/ReorderIds.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]
if o in ( '-O', '--open'):
fname = v
ftype = Mime.get_type(
os.path.abspath(os.path.expanduser(fname)))
fullpath = 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 \
and options[opt_ix+1][0] in ( '-f', '--format'):
format = options[opt_ix+1][1]
@ -151,14 +154,19 @@ class ArgHandler:
elif ftype == const.app_gramps:
format = 'grdb'
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
continue
self.open = (fname,format)
elif o in ( '-i', '--import'):
fname = v
ftype = Mime.get_type(
os.path.abspath(os.path.expanduser(fname)))
fullpath = 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 \
and options[opt_ix+1][0] in ( '-f', '--format'):
format = options[opt_ix+1][1]
@ -181,12 +189,25 @@ class ArgHandler:
elif ftype == const.app_geneweb:
format = 'geneweb'
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
continue
self.imports.append((fname,format))
elif o in ( '-o', '--output' ):
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 \
and options[opt_ix+1][0] in ( '-f', '--format'):
outformat = options[opt_ix+1][1]
@ -422,9 +443,11 @@ class ArgHandler:
from GrampsDb import GedcomParser
filename = os.path.normpath(os.path.abspath(filename))
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.parse_gedcom_file()
g.resolve_refns()
del g
except:
print "Error importing %s" % filename
@ -487,10 +510,13 @@ class ArgHandler:
print "Error importing %s" % filename
os._exit(1)
# Clean up tempdir after ourselves
files = os.listdir(tmpdir_path)
for fn in files:
os.remove(os.path.join(tmpdir_path,fn))
os.rmdir(tmpdir_path)
# THIS HAS BEEN CHANGED, because now we want to keep images
# stay after the import is over. Just delete the XML file.
os.remove(dbname)
## files = os.listdir(tmpdir_path)
## for fn in files:
## os.remove(os.path.join(tmpdir_path,fn))
## os.rmdir(tmpdir_path)
else:
print "Invalid format: %s" % format
os._exit(1)

View File

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

View File

@ -1,4 +1,4 @@
# -*- coding: iso-8859-1 -*-
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
@ -70,20 +70,20 @@ class DateDisplay:
)
_french = (
'',
unicode("Vendémiaire",'latin-1'),
'Brumaire',
'Frimaire',
unicode("Nivôse",'latin-1'),
unicode("Pluviôse",'latin-1'),
unicode("Ventôse",'latin-1'),
'Germinal',
unicode("Floréal",'latin-1'),
'Prairial',
'Messidor',
'Thermidor',
'Fructidor',
'Extra'
u'',
u"Vendémiaire",
u'Brumaire',
u'Frimaire',
u"Nivôse",
u"Pluviôse",
u"Ventôse",
u'Germinal',
u"Floréal",
u'Prairial',
u'Messidor',
u'Thermidor',
u'Fructidor',
u'Extra',
)
_persian = (
@ -162,10 +162,6 @@ class DateDisplay:
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])
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:
text = self.display_iso(start)
return "%s%s%s%s" % (qual_str,self._mod_str[mod],text,self.calendar[cal])
@ -175,7 +171,12 @@ class DateDisplay:
val = - val
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:
year = "%d" % (val)
@ -184,7 +185,8 @@ class DateDisplay:
def display_iso(self,date_val):
# YYYY-MM-DD (ISO)
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:
value = year
else:
@ -209,13 +211,16 @@ class DateDisplay:
if self.format == 0:
return self.display_iso(date_val)
elif self.format == 1:
if date_val[0] == 0 and date_val[1] == 0:
value = str(date_val[2])
if date_val[3]:
return self.display_iso(date_val)
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('-','/')
if date_val[0] == 0 and date_val[1] == 0:
value = 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(abs(date_val[2])))
value = value.replace('-','/')
elif self.format == 2:
# Month Day, Year
if date_val[0] == 0:

View File

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

View File

@ -88,17 +88,17 @@ class DateParserDE(DateParser):
}
calendar_to_int = {
u'Gregorianisch' : Date.CAL_GREGORIAN,
u'Greg.' : Date.CAL_GREGORIAN,
u'Julianisch' : Date.CAL_JULIAN,
u'Jul.' : Date.CAL_JULIAN,
u'Hebräisch' : Date.CAL_HEBREW,
u'Hebr.' : Date.CAL_HEBREW,
u'Islamisch' : Date.CAL_ISLAMIC,
u'Isl.' : Date.CAL_ISLAMIC,
u'Französisch Republikanisch': Date.CAL_FRENCH,
u'Franz.' : Date.CAL_FRENCH,
u'Persisch' : Date.CAL_PERSIAN,
u'gregorianisch' : Date.CAL_GREGORIAN,
u'greg.' : Date.CAL_GREGORIAN,
u'julianisch' : Date.CAL_JULIAN,
u'jul.' : Date.CAL_JULIAN,
u'hebräisch' : Date.CAL_HEBREW,
u'hebr.' : Date.CAL_HEBREW,
u'islamisch' : Date.CAL_ISLAMIC,
u'isl.' : Date.CAL_ISLAMIC,
u'französisch republikanisch': Date.CAL_FRENCH,
u'franz.' : Date.CAL_FRENCH,
u'persisch' : Date.CAL_PERSIAN,
}
quality_to_int = {
@ -109,7 +109,10 @@ class DateParserDE(DateParser):
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):
DateParser.init_strings(self)
@ -128,8 +131,8 @@ class DateParserDE(DateParser):
class DateDisplayDE(DateDisplay):
calendar = (
"", u" (Julianisch)", u" (Hebräisch)",
u" (Französisch Republikanisch)", u" (Persisch)", u" (Islamisch)"
"", u" (julianisch)", u" (hebräisch)",
u" (französisch republikanisch)", u" (persisch)", u" (islamisch)"
)
_mod_str = ("",u"vor ",u"nach ",u"etwa ","","","")
@ -146,14 +149,17 @@ class DateDisplayDE(DateDisplay):
def _display_gregorian(self,date_val):
year = self._slash_year(date_val[2],date_val[3])
if self.format == 0:
value = self.display_iso(date_val)
return self.display_iso(date_val)
elif self.format == 1:
if date_val[0] == 0 and date_val[1] == 0:
value = str(date_val[2])
if date_val[3]:
return self.display_iso(date_val)
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]))
if date_val[0] == 0 and date_val[1] == 0:
value = 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:
# Month Day, Year
if date_val[0] == 0:
@ -190,7 +196,10 @@ class DateDisplayDE(DateDisplay):
value = "%s %s" % (self._MONS[date_val[1]],year)
else:
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):
"""

View File

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

View File

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

View File

@ -90,7 +90,6 @@ class DateParserFR(DateParser):
modifier_to_int = {
u'avant' : Date.MOD_BEFORE,
u'av.' : Date.MOD_BEFORE,
u'av' : Date.MOD_BEFORE,
u'après' : Date.MOD_AFTER,
u'ap.' : Date.MOD_AFTER,
u'ap' : Date.MOD_AFTER,
@ -134,8 +133,11 @@ class DateParserFR(DateParser):
def init_strings(self):
DateParser.init_strings(self)
self._span = re.compile("(de)\s+(?P<start>.+)\s+(à)\s+(?P<stop>.+)",re.IGNORECASE)
self._range = re.compile("(entre|ent|ent.)\s+(?P<start>.+)\s+(et)\s+(?P<stop>.+)",re.IGNORECASE)
# This self._numeric is different from the base
# 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,
re.IGNORECASE)
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 ","","","")
_qual_str = ("","estimée ","calculée ","")
_qual_str = ("",u"estimée ",u"calculée ","")
formats = (
"AAAA-MM-DD (ISO)", "Numérique", "Mois Jour, Année",
"MOI Jour, Année", "Jour Mois, Année", "Jour MOIS Année"
"AAAA-MM-JJ (ISO)", "Numérique", "Mois Jour, Année",
"MOI Jour, Année", "Jour Mois, Année", "Jour MOI Année"
)
def _display_gregorian(self,date_val):
year = self._slash_year(date_val[2],date_val[3])
if self.format == 0:
value = self.display_iso(date_val)
return self.display_iso(date_val)
elif self.format == 1:
if date_val[0] == 0 and date_val[1] == 0:
value = str(date_val[2])
if date_val[3]:
return self.display_iso(date_val)
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]))
if date_val[0] == 0 and date_val[1] == 0:
value = 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:
# Month Day, Year
if date_val[0] == 0:
@ -209,7 +214,11 @@ class DateDisplayFR(DateDisplay):
value = "%s %s" % (self._MONS[date_val[1]],year)
else:
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):
"""
@ -243,5 +252,6 @@ class DateDisplayFR(DateDisplay):
# Register classes
#
#-------------------------------------------------------------------------
register_datehandler(('fr_FR','fr','french','fr_CA','fr_BE','fr_CH'),
DateParserFR,DateDisplayFR)
register_datehandler(
('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 = {
u'Grigaliaus' : Date.CAL_GREGORIAN,
u'grigaliaus' : Date.CAL_GREGORIAN,
u'g' : Date.CAL_GREGORIAN,
u'Julijaus' : Date.CAL_JULIAN,
u'julijaus' : Date.CAL_JULIAN,
u'j' : Date.CAL_JULIAN,
u'Hebrajų' : Date.CAL_HEBREW,
u'hebrajų' : Date.CAL_HEBREW,
u'h' : Date.CAL_HEBREW,
u'Islamo' : Date.CAL_ISLAMIC,
u'islamo' : 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'Persų' : Date.CAL_PERSIAN,
u'persų' : Date.CAL_PERSIAN,
u'p' : Date.CAL_PERSIAN,
}
@ -96,18 +96,20 @@ class DateParserLT(DateParser):
class DateDisplayLT(DateDisplay):
calendar = (
"", u" (Julijaus)",
u" (Hebrajų)",
u" (Prancuzų Respublikos)",
u" (Persų)",
u" (Islamo)"
u"", u" (julijaus)",
u" (hebrajų)",
u" (prancuzų respublikos)",
u" (persų)",
u" (islamo)"
)
_mod_str = ("",u"iki ",
_mod_str = (u"",
u"prieš ",
u"po ",
u"apie ","","","")
u"apie ",
u"",u"",u"")
_qual_str = ("","apytikriai ","apskaičiuota ")
_qual_str = (u"",u"apytikriai ",u"apskaičiuota ")
formats = (
"YYYY-MM-DD (ISO)", "Skaitmeninis", "Mėnuo Diena, Metai",
@ -132,7 +134,7 @@ class DateDisplayLT(DateDisplay):
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" % (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:
d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](date.get_stop_date())

View File

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

View File

@ -50,7 +50,7 @@ from _DateHandler import register_datehandler
class DateParserRU(DateParser):
modifier_to_int = {
u'до' : Date.MOD_BEFORE,
u'перед' : Date.MOD_BEFORE,
u'по' : Date.MOD_BEFORE,
u'после' : Date.MOD_AFTER,
u'п.' : Date.MOD_AFTER,
@ -97,11 +97,77 @@ class DateParserRU(DateParser):
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):
DateParser.init_strings(self)
_span_1 = [u'с',u'от']
_span_2 = [u'по',u'до']
_range_1 = [u'между',u'меж',u'меж.']
_span_2 = [u'по']
_range_1 = [u'между',u'меж\.',u'меж']
_range_2 = [u'и']
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
('|'.join(_span_1),'|'.join(_span_2)),
@ -118,24 +184,92 @@ class DateParserRU(DateParser):
class DateDisplayRU(DateDisplay):
calendar = (
"", u" (юлианский)",
u"",
u" (юлианский)",
u" (еврейский)",
u" (республиканский)",
u" (персидский)",
u" (исламский)"
)
_mod_str = ("",u"до ",
_mod_str = (
u"",
u"перед ",
u"после ",
u"около ","","","")
u"около ",
u"",u"",u"")
_qual_str = ("","оцен ","вычисл ")
_qual_str = (u"",u"оцен ",u"вычисл ")
_bce_str = u"%s до н.э."
formats = (
"ГГГГ-ММ-ДД (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):
"""
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:
return date.get_text()
elif start == Date.EMPTY:
return ""
return u""
elif mod == Date.MOD_SPAN:
d1 = self.display_cal[cal](start)
d2 = self.display_cal[cal](date.get_stop_date())
@ -157,7 +157,7 @@ class DateDisplaySv(DateDisplay):
self.calendar[cal])
else:
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])
#-------------------------------------------------------------------------

View File

@ -2126,14 +2126,13 @@ class IsLessThanNthGenerationAncestorOfDefaultPerson(Rule):
def prepare(self,db):
self.db = db
p = db.get_default_person()
if p == 0:
self.apply = lambda db,p: False
else:
if p:
self.def_handle = p.get_handle()
self.apply = self.apply_real
self.map = {}
self.init_ancestor_list(self.def_handle, 1)
else:
self.apply = lambda db,p: False
def init_ancestor_list(self,handle,gen):
# 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_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
@ -233,7 +237,7 @@ def importData(database, filename, callback=None, use_trans=False):
def import2(database, filename, callback, codeset, use_trans):
# add some checking here
try:
np = NoteParser(filename, False)
np = NoteParser(filename, False, codeset)
g = GedcomParser(database,filename, callback, codeset, np.get_map(),
np.get_lines(),np.get_persons())
except IOError,msg:
@ -334,43 +338,73 @@ class CurrentState:
#
#-------------------------------------------------------------------------
class NoteParser:
def __init__(self, filename,broken):
self.name_map = {}
def __init__(self, filename,broken,override):
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.person_count = 0
f = open(filename,"rU")
innote = False
self.name_map = {}
self.count = 0
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
if innote:
match = contRE.match(line)
if match:
noteobj.append("\n" + match.groups()[0])
continue
try:
text = self.cnv(text)
except:
text = string.translate(text,_transtable2)
match = concRE.match(line)
if match:
if broken:
noteobj.append(" " + match.groups()[0])
else:
noteobj.append(match.groups()[0])
continue
innote = False
else:
match = noteRE.match(line)
if match:
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()
self.count += 1
if innote:
match = contRE.match(text)
if match:
noteobj.append("\n" + match.groups()[0])
continue
match = concRE.match(text)
if match:
if broken:
noteobj.append(" " + match.groups()[0])
else:
noteobj.append(match.groups()[0])
continue
# Here we have finished parsing CONT/CONC tags for the NOTE
# and ignored the rest of the tags (SOUR,CHAN,REFN,RIN).
innote = False
match = noteRE.match(text)
if match:
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):
return self.name_map
@ -392,9 +426,6 @@ class Reader:
self.f = open(name,'rU')
self.current_list = []
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.broken_conc = False
self.cnt = 0
@ -426,11 +457,11 @@ class Reader:
break
line = line.split(None,2) + ['']
val = line[2].translate(self.transtable,self.delc)
val = line[2].translate(_transtable,_delc)
try:
val = self.cnv(val)
except:
val = self.cnv(val.translate(self.transtable2))
val = self.cnv(val.translate(_transtable2))
try:
level = int(line[0])
@ -1168,23 +1199,21 @@ class GedcomParser:
del event
def parse_note_base(self,matches,obj,level,old_note,task):
note = old_note
if matches[2] and matches[2][0] == "@": # reference to a named note defined elsewhere
# reference to a named note defined elsewhere
if matches[2] and matches[2][0] == "@":
note_obj = self.note_map.get(matches[2])
if note_obj:
return note_obj.get()
new_note = note_obj.get()
else:
return u""
new_note = u""
else:
if old_note:
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)
new_note = matches[2] + self.parse_continue_data(level)
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
def parse_note(self,matches,obj,level,old_note):
@ -1489,7 +1518,7 @@ class GedcomParser:
event.set_cause(info)
self.parse_cause(event,level+1)
elif matches[1] in (TOKEN_NOTE,TOKEN_OFFI):
info = matches[2]
info = self.parse_note(matches,event,level+1,note)
if note == "":
note = info
else:
@ -1548,7 +1577,7 @@ class GedcomParser:
event.set_cause(info)
self.parse_cause(event,level+1)
elif matches[1] == TOKEN_NOTE:
info = matches[2]
info = self.parse_note(matches,event,level+1,note)
if note == "":
note = info
else:
@ -1604,7 +1633,7 @@ class GedcomParser:
elif matches[1] == TOKEN_DATE:
note = "%s\n\n" % ("Date : %s" % matches[2])
elif matches[1] == TOKEN_NOTE:
info = matches[2]
info = self.parse_note(matches,attr,level+1,note)
if note == "":
note = info
else:
@ -1741,6 +1770,7 @@ class GedcomParser:
def parse_header_source(self):
genby = ""
note = ""
while True:
matches = self.get_next()
if int(matches[0]) < 1:
@ -1788,7 +1818,7 @@ class GedcomParser:
date.date = matches[2]
self.def_src.set_data_item('Creation date',matches[2])
elif matches[1] == TOKEN_NOTE:
note = matches[2]
note = self.parse_note(matches,self.def_src,2,note)
elif matches[1] == TOKEN_UNKNOWN:
self.ignore_sub_junk(2)
else:
@ -2126,7 +2156,7 @@ class GedcomParser:
state.add_to_note(self.parse_optional_note(2))
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])
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)
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():
if not self.plist.has_key(person_handle):
continue
@ -815,6 +835,9 @@ class GedcomWriter:
continue
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.update()
@ -831,11 +854,17 @@ class GedcomWriter:
for (source_id, source) in sorted:
self.writeln("0 @%s@ SOUR" % source_id)
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():
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():
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():
self.writeln("1 ABBR %s" % self.cnvtxt(source.get_abbreviation()))
if self.images:
@ -1113,6 +1142,10 @@ class GedcomWriter:
else:
for line in textlines:
ll = len(line)
if ll == 0:
self.writeln("%s " % prefix)
prefix = "%d CONT" % (level+1)
continue
while ll > 0:
brkpt = 70
if ll > brkpt:
@ -1142,6 +1175,10 @@ class GedcomWriter:
else:
for line in textlines:
ll = len(line)
if ll == 0:
self.writeln("%s " % prefix)
prefix = "%d CONT" % (level+1)
continue
while ll > 0:
brkpt = 70
if ll > brkpt:

View File

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

View File

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

View File

@ -1,7 +1,7 @@
#
# 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
# it under the terms of the GNU General Public License as published by
@ -46,11 +46,16 @@ try:
import locale
lang = locale.getlocale()[0]
gtkspell.Spell(gtk.TextView()).set_language(lang)
success = True
if lang == None:
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:
print _("Spelling checker is not installed")
except TypeError,msg:
print "Spell.py: ", msg
except RuntimeError,msg:
print "Spell.py: ", 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)
if death.get_date_object().get_start_date() != RelLib.Date.EMPTY:
death_year = death.get_date_object().get_year()
if death_year - limit < current_year:
if death_year + limit < current_year:
return False
# 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:
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_year() - limit < current_year:
if ev.get_date_object().get_year() + limit < current_year:
return False
# For any other event of this person, check whether it happened
# 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):
assert(self.init_called==False)
assert (not self.init_called)
self.init_called = True
current_locale = locale.getlocale()
@ -164,8 +164,6 @@ class ODFDoc(BaseDoc.BaseDoc):
self.cntnt.write(' >\n')
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():
self.cntnt.write('svg:stroke-width="%.2f" ' % (style.get_line_width()*10))
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-vertical-align="middle" ')
else:
print(" get_line_width non defini : style %s" % style_name )
self.cntnt.write('draw:stroke="none" ')
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:parent-style-name="photo">')
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:wrap-contour="false" style:vertical-pos="from-top"')
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('svg:width="%.2fcm" ' % act_width)
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(base)
self.cntnt.write('" xlink:type="simple" xlink:show="embed" ')

View File

@ -99,7 +99,7 @@ class OpenOfficeDoc(BaseDoc.BaseDoc):
def init(self):
assert(self.init_called==False)
assert (not self.init_called)
self.init_called = True
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:parent-style-name="photo">')
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:wrap-contour="false" style:vertical-pos="from-top"')
self.cntnt.write(' style:vertical-rel="paragraph-content"')

View File

@ -1,7 +1,7 @@
#
# 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
# it under the terms of the GNU General Public License as published by
@ -204,12 +204,12 @@ class OpenSpreadSheet(SpreadSheetDoc):
def _write_zip(self):
file = zipfile.ZipFile(self.filename,"w",zipfile.ZIP_DEFLATED)
file.write(self.manifest_xml,str("META-INF/manifest.xml"))
file.write(self.content_xml,str("content.xml"))
file.write(self.meta_xml,str("meta.xml"))
file.write(self.styles_xml,str("styles.xml"))
file.close()
the_file = zipfile.ZipFile(self.filename,"w",zipfile.ZIP_DEFLATED)
the_file.write(self.manifest_xml,str("META-INF/manifest.xml"))
the_file.write(self.content_xml,str("content.xml"))
the_file.write(self.meta_xml,str("meta.xml"))
the_file.write(self.styles_xml,str("styles.xml"))
the_file.close()
os.unlink(self.manifest_xml)
os.unlink(self.content_xml)

View File

@ -310,6 +310,8 @@ class PdfDoc(BaseDoc.BaseDoc):
self.tblstyle.append(('LINEABOVE', loc, loc, 1, black))
if self.my_table_style.get_bottom_border():
self.tblstyle.append(('LINEBELOW', loc, loc, 1, black))
# Set the alignment
if p.get_alignment() == BaseDoc.PARA_ALIGN_LEFT:
self.tblstyle.append(('ALIGN', loc, loc, 'LEFT'))
elif p.get_alignment() == BaseDoc.PARA_ALIGN_RIGHT:
@ -326,6 +328,13 @@ class PdfDoc(BaseDoc.BaseDoc):
#if self.span != 1:
# 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.text = ""
@ -336,6 +345,9 @@ class PdfDoc(BaseDoc.BaseDoc):
return
x,y = img.size()
if (x,y) == (0,0):
return
if (x,y) == (0,0):
return

View File

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

View File

@ -69,7 +69,7 @@ import ListModel
from PluginUtils import Plugins, Report, ReportOptions, \
bkitems_list, register_report
import BaseDoc
from QuestionDialog import WarningDialog
from QuestionDialog import WarningDialog, ErrorDialog
#------------------------------------------------------------------------
#
@ -710,7 +710,7 @@ class BookReportSelector:
self.book.append_item(item)
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"))
else:
pname = self.db.get_person_from_gramps_id(person_id)
@ -727,7 +727,7 @@ class BookReportSelector:
if not the_iter:
return
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"))
else:
data.append(self.person.get_primary_name().get_regular_name())

View File

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

View File

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

View File

@ -469,9 +469,9 @@ register_report(
report_class = DescendChart,
options_class = DescendChartOptions,
modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI,
translated_name = _("Descendant Graph"),
translated_name = _("Descendant Chart"),
status = _("Stable"),
author_name = "Donald N. Allingham",
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):
"""Display the relevant portion of GRAMPS manual"""
help('gramps-manual','tools-ae')
help('tools-ae')
def build_menu_names(self,obj):
return (_("Event Comparison Results"),None)

View File

@ -22,13 +22,6 @@
"Generate files/Family Group Report"
#------------------------------------------------------------------------
#
# python modules
#
#------------------------------------------------------------------------
from gettext import gettext as _
#------------------------------------------------------------------------
#
# Gnome/GTK modules
@ -46,6 +39,7 @@ from PluginUtils import Report, ReportOptions, register_report
import BaseDoc
import DateHandler
import Utils
from TransUtils import sgettext as _
#------------------------------------------------------------------------
#
@ -361,6 +355,42 @@ class FamilyGroup(Report.Report):
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):
date = ""
place = ""
@ -425,10 +455,11 @@ class FamilyGroup(Report.Report):
else:
self.doc.start_cell('FGR-TextChild2')
self.doc.start_paragraph('FGR-ChildText')
index_str = ("%d" % index)
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:
self.doc.write_text(_("%dF") % index)
self.doc.write_text(index_str + _("acronym for female|F"))
else:
self.doc.write_text(_("%dU") % index)
self.doc.end_paragraph()

View File

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

View File

@ -78,18 +78,38 @@ class _options:
)
fonts = (
# Last items tells whether strings need to be converted to Latin1
("", "Default", _("Default"), 1),
("Helvetica", "Postscript / Helvetica", _("Postscript / Helvetica"), 1),
("FreeSans", "Truetype / FreeSans", _("Truetype / FreeSans"), 0),
("", "Default", _("Default")),
("Helvetica", "Postscript / Helvetica", _("Postscript / Helvetica")),
("FreeSans", "Truetype / FreeSans", _("Truetype / FreeSans")),
)
colors = (
("outline", "B&W Outline", _("B&W outline")),
("colored", "Colored outline", _("Colored outline")),
("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 = (
("TB", "Vertical", _("Vertical")),
("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 = (
('d', "Descendants <- Ancestors", _("Descendants <- Ancestors")),
@ -98,7 +118,11 @@ class _options:
('', "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
returning the list of filters.
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.
showfamily - Whether to show family nodes.
incid - Whether to include IDs.
@ -132,12 +156,17 @@ class GraphViz:
justyears - Use years only.
placecause - Whether to replace missing dates with place or cause
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
dashedl - Whether to use dashed lines for non-birth relationships.
margin - Margins, in cm.
pagesh - Number of pages in horizontal 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 = {
'male': 'dodgerblue4',
@ -160,11 +189,14 @@ class GraphViz:
self.height = self.paper.get_height_inches()
options = options_class.handler.options_dict
self.pagedir = options['pagedir']
self.hpages = options['pagesh']
self.vpages = options['pagesv']
margin_cm = options['margin']
self.margin = round(margin_cm/2.54,2)
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)
else:
self.margin_small = 0
@ -176,8 +208,8 @@ class GraphViz:
self.just_years = options['justyears']
self.placecause = options['placecause']
self.rankdir = options['rankdir']
self.ratio = options['ratio']
self.fontname = options['font']
self.latin = options['latin']
self.colorize = options['color']
if self.colorize == 'colored':
self.colors = colored
@ -193,189 +225,295 @@ class GraphViz:
else:
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()
filters = options_class.get_report_filters(person)
filters.extend(GenericFilter.CustomFilters.get_filters())
self.filter = filters[filter_num]
self.f = open(options_class.get_output(),'w')
self.write_report()
the_buffer = self.get_report()
if self.latin:
self.f.write(the_buffer.encode('iso-8859-1'))
else:
self.f.write(the_buffer)
self.f.close()
def write_report(self):
self.ind_list = self.filter.apply(self.database,
def get_report(self):
"return string of the .dot file contents"
self.person_handles = self.filter.apply(self.database,
self.database.get_person_handles(sort_handles=False))
self.write_header()
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")
# graph size
if self.orient == PAPER_LANDSCAPE:
self.f.write("size=\"%3.2f,%3.2f\";\n" % (
(self.height-self.margin*2)*self.hpages,
(self.width-self.margin*2)*self.vpages
))
rotate = 90
sizew = (self.height - self.margin*2) * self.hpages
sizeh = (self.width - self.margin*2) * self.vpages
else:
self.f.write("size=\"%3.2f,%3.2f\";\n" % (
(self.width-self.margin*2)*self.hpages,
(self.height-self.margin*2)*self.vpages
))
self.f.write("page=\"%3.2f,%3.2f\";\n" % (self.width,self.height))
rotate = 0
sizew = (self.width - self.margin*2) * self.hpages
sizeh = (self.height - self.margin*2) * self.vpages
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:
self.f.write("rotate=90;\n")
if self.fontname:
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:
self.dump_index()
self.dump_person()
if self.note:
buffer += 'labelloc="%s";\n' % self.noteloc
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 = {}
for p_id in self.ind_list:
person_dict[p_id] = 1
for person_handle in self.ind_list:
# Hash people in a dictionary for faster inclusion checking
for person_handle in self.person_handles:
person_dict[person_handle] = 1
the_buffer = ""
for person_handle in self.person_handles:
person = self.database.get_person_from_handle(person_handle)
pid = person.get_gramps_id().replace('-','_')
for family_handle in person.get_parent_family_handle_list():
family = self.database.get_family_from_handle(family_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
p_id = person.get_gramps_id()
for fam_handle in person.get_parent_family_handle_list():
family = self.database.get_family_from_handle(fam_handle)
father_handle = family.get_father_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
(father_handle and person_dict.has_key(father_handle) or
mother_handle and person_dict.has_key(mother_handle))):
# Link to the family node.
self.f.write('p%s -> f%s [' % (pid, famid))
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')
((father_handle and father_handle in person_dict) or
(mother_handle and mother_handle in person_dict))):
# Link to the family node if either parent is in graph
the_buffer += self.get_family_link(p_id,family,frel,mrel)
else:
# Link to the parents' nodes directly.
if father_handle and person_dict.has_key(father_handle):
father = self.database.get_person_from_handle(father_handle)
fid = father.get_gramps_id().replace('-','_')
self.f.write('p%s -> p%s [' % (pid, fid))
self.f.write('arrowhead=%s, arrowtail=%s, ' %
(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))
# Link to the parents' nodes directly, if they are in graph
if father_handle and father_handle in person_dict:
the_buffer += self.get_parent_link(p_id,father_handle,frel)
if mother_handle and mother_handle in person_dict:
the_buffer += self.get_parent_link(p_id,mother_handle,mrel)
return the_buffer
# 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:
family_list = person.get_family_handle_list()
for fam_handle in family_list:
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:
families_done.append(fam_handle)
self.f.write('f%s [shape=ellipse, ' % fid)
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 = ""
families_done[fam_handle] = 1
label = ""
for event_ref in fam.get_event_ref_list():
if event_ref:
event = self.database.get_event_from_handle(event_ref.ref)
if int(event.get_type()) == RelLib.EventType.MARRIAGE:
m = event
break
else:
m = None
if m:
marriage = self.dump_event(m)
event = self.database.get_event_from_handle(
event_ref.ref)
if int(event.get_type()) == RelLib.EventType.MARRIAGE:
label = self.get_event_string(event)
break
if self.includeid:
marriage = marriage + " (%s)" % fid
self.f.write('fontname="%s", label="%s"];\n'
% (self.fontname,marriage))
label = "%s (%s)" % (label, fam_id)
color = ""
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.
self.f.write('f%s -> p%s [' % (fid, the_id))
self.f.write('arrowhead=%s, arrowtail=%s, ' %
(self.arrowheadstyle, self.arrowtailstyle))
self.f.write('style=solid];\n')
buffer += '"f%s" -> "p%s";\n' % (fam_id, p_id)
return buffer
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
of the following for a given event:
@ -399,33 +537,6 @@ class GraphViz:
return event.get_cause()
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,
'placecause' : 1,
'url' : 1,
'ratio' : "compress",
'rankdir' : "LR",
'color' : "filled",
'dashedl' : 1,
'margin' : 1.0,
'pagedir' : 'BL',
'pagesh' : 1,
'pagesv' : 1,
'note' : '',
'noteloc' : 'b',
'notesize' : 32,
'gvof' : 'ps',
}
@ -490,7 +606,10 @@ class GraphVizOptions(ReportOptions.ReportOptions):
'url' : ("=0/1","Whether to include URLs.",
["Do not include URLs","Include URLs"],
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 ],
False),
'color' : ("=str","Whether and how to colorize graph.",
@ -501,10 +620,20 @@ class GraphVizOptions(ReportOptions.ReportOptions):
True),
'margin' : ("=num","Margin size.",
"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.",
"Integer values"),
'pagesv' : ("=num","Number of pages in vertical direction.",
"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.",
[ "%s\t%s" % (item[0],item[1]) for item in _options.formats ],
False),
@ -546,6 +675,22 @@ class GraphVizOptions(ReportOptions.ReportOptions):
def make_doc_menu(self,dialog,active=None):
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):
if self.handler.module_name == "rel_graph2":
dialog.make_doc_menu = self.make_doc_menu
@ -599,36 +744,8 @@ class GraphVizOptions(ReportOptions.ReportOptions):
_("Include individual and family IDs."))
# GraphViz output options tab
self.rank_box = gtk.ComboBox()
store = gtk.ListStore(str)
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
self.color_box = self.add_list(_options.colors,
self.options_dict['color'])
dialog.add_frame_option(_("GraphViz Options"),
_("Graph coloring"),
self.color_box,
@ -636,39 +753,15 @@ class GraphVizOptions(ReportOptions.ReportOptions):
"with red. If the sex of an individual "
"is unknown it will be shown with gray."))
self.arrowstyle_box = gtk.ComboBox()
store = gtk.ListStore(str)
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
self.arrowstyle_box = self.add_list(_options.arrowstyles,
self.options_dict['arrow'])
dialog.add_frame_option(_("GraphViz Options"),
_("Arrowhead direction"),
self.arrowstyle_box,
_("Choose the direction that the arrows point."))
self.font_box = gtk.ComboBox()
store = gtk.ListStore(str)
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
self.font_box = self.add_list(_options.fonts,
self.options_dict['font'])
dialog.add_frame_option(_("GraphViz Options"),
_("Font family"),
self.font_box,
@ -677,6 +770,13 @@ class GraphVizOptions(ReportOptions.ReportOptions):
"FreeSans is available from: "
"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.set_active(self.options_dict['dashedl'])
dialog.add_frame_option(_("GraphViz Options"), '',
@ -691,13 +791,30 @@ class GraphVizOptions(ReportOptions.ReportOptions):
_("Families will show up as ellipses, linked "
"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'],
lower=0.0, upper=10.0, step_incr=1.0)
self.margin_sb = gtk.SpinButton(adjustment=margin_adj, digits=1)
dialog.add_frame_option(_("Page Options"),
dialog.add_frame_option(_("Layout Options"),
_("Margin size"),
self.margin_sb)
@ -709,14 +826,14 @@ class GraphVizOptions(ReportOptions.ReportOptions):
self.hpages_sb = gtk.SpinButton(adjustment=hpages_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"),
self.hpages_sb,
_("GraphViz can create very large graphs by "
"spreading the graph across a rectangular "
"array of pages. This controls the number "
"pages in the array horizontally."))
dialog.add_frame_option(_("Page Options"),
dialog.add_frame_option(_("Layout Options"),
_("Number of Vertical Pages"),
self.vpages_sb,
_("GraphViz can create very large graphs "
@ -724,6 +841,41 @@ class GraphVizOptions(ReportOptions.ReportOptions):
"rectangular array of pages. This "
"controls the number pages in the array "
"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):
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['justyears'] = int(self.just_years_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'] = \
_options.rankdir[self.rank_box.get_active()][0]
self.options_dict['color'] = \
@ -748,8 +902,15 @@ class GraphVizOptions(ReportOptions.ReportOptions):
_options.arrowstyles[self.arrowstyle_box.get_active()][0]
self.options_dict['font'] = \
_options.fonts[self.font_box.get_active()][0]
self.options_dict['latin'] = \
_options.fonts[self.font_box.get_active()][3]
self.options_dict['pagedir'] = \
_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":
self.options_dict['gvof'] = dialog.format_menu.get_format_str()
@ -837,7 +998,24 @@ class FormatComboBox(gtk.ComboBox):
return '.dot'
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):
return 'dot'
@ -907,7 +1085,6 @@ class GraphicsFormatComboBox(gtk.ComboBox):
class EmptyDoc:
def __init__(self,styles,type,template,orientation,source=None):
self.print_req = 0
pass
def init(self):
pass
@ -955,9 +1132,31 @@ class GraphVizGraphics(Report.Report):
GraphViz(self.database,self.start_person,self.options_class)
def end_report(self):
os.system('dot -T%s -o%s %s ; rm %s' %
(self.the_format,self.user_output,
self.junk_output,self.junk_output))
if self.the_format == "pdf":
command = ('dot -Tps %s | ' + _pdf_pipe + ' ; rm %s') % \
(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:
_apptype = None
@ -1011,7 +1210,7 @@ register_report(
author_email="don@gramps-project.org"
)
if dot_found:
if _dot_found:
register_report(
name = 'rel_graph2',
category = Report.CATEGORY_DRAW,

View File

@ -153,6 +153,7 @@ class BasePage:
self.exclude_private = not options.handler.options_dict['NWEBincpriv']
self.usegraph = options.handler.options_dict['NWEBgraph']
self.use_home = self.options.handler.options_dict['NWEBhomenote'] != ""
self.page_title = ""
def store_file(self,archive,html_dir,from_path,to_path):
if archive:
@ -901,7 +902,6 @@ class MediaPage(BasePage):
return None
def copy_thumbnail(self,handle,photo):
ext = os.path.splitext(photo.get_path())[1]
to_dir = self.build_path(handle,'thumb')
to_path = os.path.join(to_dir,handle+".png")
if photo.get_mime_type():
@ -923,16 +923,6 @@ class MediaPage(BasePage):
except IOError:
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(),
newpath)
dirpath = self.build_path(note_id,'img')
of.write('<div class="rightwrap">\n')
of.write('<table><tr>')
of.write('<td height="205">')
@ -2050,6 +2038,7 @@ class WebReport(Report.Report):
NWEBhomenote
NWEBnoid
"""
self.database = database
self.start_person = person
self.options = options
@ -2196,7 +2185,6 @@ class WebReport(Report.Report):
# people rule
if self.restrict:
self.progress.set_pass(_('Filtering living people'),len(ind_list))
new_list = []
for key in ind_list:
self.progress.step()
p = self.database.get_person_from_handle(key)
@ -2331,19 +2319,6 @@ class WebReport(Report.Report):
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:
HomePage(self.database, self.title, self.options, archive, photo_list)
@ -2380,7 +2355,7 @@ class WebReportOptions(ReportOptions.ReportOptions):
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)
self.db = database
@ -2556,18 +2531,21 @@ class WebReportOptions(ReportOptions.ReportOptions):
title = _("Page Generation")
cursor = self.db.get_media_cursor()
media_list = [['','']]
html_list = [['','']]
data = cursor.first()
while data:
(handle, value) = data
if value[3]:
media_list.append([value[4],handle])
else:
html_list.append([value[4],handle])
data = cursor.next()
cursor.close()
if self.db:
cursor = self.db.get_media_cursor()
data = cursor.first()
while data:
(handle, value) = data
if value[3]:
media_list.append([value[4],handle])
else:
html_list.append([value[4],handle])
data = cursor.next()
cursor.close()
media_list.sort()
html_list.sort()
@ -2901,7 +2879,7 @@ register_report(
category = Report.CATEGORY_WEB,
report_class = WebReportDialog,
options_class = cl_report,
modes = Report.MODE_GUI,
modes = Report.MODE_GUI | Report.MODE_CLI,
translated_name = _("Narrative Web Site"),
status = _("Stable"),
author_name="Donald N. Allingham",

View File

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

View File

@ -154,7 +154,7 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
other_birth_event = other_person.get_birth()
other_birth_date = other_birth_event.get_date_object()
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):
@ -203,7 +203,7 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
family = self.db.get_family_from_handle(g)
if family:
if sp_id in family.get_child_handle_list():
return [sp]
return [sp_id]
return []
#------------------------------------------------------------------------
@ -246,7 +246,7 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
if family:
c = family.get_child_handle_list()
if (other.get_handle() in c) and (sp_id in c):
return [sp]
return [sp_id]
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
#
# Import/export test for GRAMPS: Import example XML data and create GRDB,
# check data for integrity, output in all formats, check resulting XML for
# well-formedness and validate it against DTD and RelaxNG schema.
# Import/export test for GRAMPS:
# o Import example XML data and create GRDB
# 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$
@ -13,6 +18,7 @@ PRG="python gramps.py"
EXAMPLE_XML=$TOP_DIR/example/gramps/example.gramps
OUT_FMT="gedcom gramps-xml gramps-pkg wft geneweb"
IN_FMT="gedcom gramps-xml gramps-pkg"
DATA_DIR=$TEST_DIR/data
mkdir -p $DATA_DIR
if [ -f $DATA_DIR/example.grdb ]; then
@ -53,3 +59,12 @@ echo "* Post-parsing DTD validation"
xmllint --noout --postvalid $DATA_DIR/example.gramps-xml
echo "* Validate against RelaxNG schema"
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