Merge branch 'gramps51'
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
@ -251,7 +251,7 @@ PLACES
|
||||
|
||||
<!ELEMENT places (placeobj)*>
|
||||
|
||||
<!ELEMENT placeobj (ptitle?, pname+, code?, coord?, placeref*, location*,
|
||||
<!ELEMENT placeobj (ptitle?, code?, pname+, coord?, placeref*, location*,
|
||||
objref*, url*, noteref*, citationref*, tagref*)>
|
||||
<!ATTLIST placeobj
|
||||
id CDATA #IMPLIED
|
||||
|
@ -453,10 +453,10 @@
|
||||
<ref name="primary-object"/>
|
||||
<attribute name="type"><text/></attribute>
|
||||
<optional><element name="ptitle"><text/></element></optional>
|
||||
<optional><element name="code"><text/></element></optional>
|
||||
<oneOrMore><element name="pname">
|
||||
<ref name="placename-content"/>
|
||||
</element></oneOrMore>
|
||||
<optional><element name="code"><text/></element></optional>
|
||||
<optional><element name="coord">
|
||||
<attribute name="long"><text/></attribute>
|
||||
<attribute name="lat"><text/></attribute>
|
||||
|
16
debian/changelog
vendored
@ -1,3 +1,19 @@
|
||||
gramps (5.1.4-1) unstable; urgency=medium
|
||||
|
||||
* New release
|
||||
* Add new copyrights
|
||||
* Update watch file
|
||||
* Patch probably alive test to fix FTBFS
|
||||
|
||||
-- Ross Gammon <rossgammon@debian.org> Sun, 15 Aug 2021 18:31:56 +0200
|
||||
|
||||
gramps (5.1.3-1) focal; urgency=medium
|
||||
|
||||
* New release
|
||||
* Update debian/copyright for Alex Roitman
|
||||
|
||||
-- Ross Gammon <rosco2@ubuntu.com> Sun, 16 Aug 2020 20:23:34 +0200
|
||||
|
||||
gramps (5.1.2-1) unstable; urgency=medium
|
||||
|
||||
* New release
|
||||
|
2
debian/copyright
vendored
@ -92,6 +92,8 @@ Copyright: 2000-2007, Alex Roitman
|
||||
2018, Robin van der Vliet
|
||||
2018, Theo van Rijn
|
||||
2019, Matthias Kemmer
|
||||
2020, Jan Sparreboom
|
||||
2021, Mirko Leonhaeuser
|
||||
License: GPL-2+
|
||||
|
||||
Files: debian/*
|
||||
|
22
debian/patches/fix-probably_alive_test.patch
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
Description: Fix probably alive test
|
||||
The probably alive funtion was fixed just prior to the Gramps 5.1.4
|
||||
release. It appears the relevant unit test was not updated to match.
|
||||
The relevant commit:
|
||||
https://github.com/gramps-project/gramps/commit/a685b96f700dcfc6b953413cb3adc8be61d87438
|
||||
Author: Ross Gammon <rossgammon@debian.org>
|
||||
Forwarded: no
|
||||
Applied-Upstream: no
|
||||
Last-Update: 2021-08-09
|
||||
---
|
||||
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
|
||||
--- a/gramps/gen/filters/rules/test/person_rules_test.py
|
||||
+++ b/gramps/gen/filters/rules/test/person_rules_test.py
|
||||
@@ -347,7 +347,7 @@
|
||||
"""
|
||||
rule = ProbablyAlive(['1900'])
|
||||
res = self.filter_with_rule(rule)
|
||||
- self.assertEqual(len(res), 766)
|
||||
+ self.assertEqual(len(res), 733)
|
||||
|
||||
def test_RegExpName(self):
|
||||
"""
|
1
debian/patches/series
vendored
Normal file
@ -0,0 +1 @@
|
||||
fix-probably_alive_test.patch
|
8
debian/watch
vendored
@ -1,8 +1,6 @@
|
||||
version=3
|
||||
|
||||
version=4
|
||||
opts=\
|
||||
dversionmangle=s/(\~|\+)(debian|dfsg|ds|deb)(\.\d+)?$//,\
|
||||
filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/$1\.tar\.gz/,\
|
||||
filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/gramps-project-$1\.tar\.gz/,\
|
||||
repacksuffix=~dfsg \
|
||||
https://github.com/gramps-project/gramps/tags \
|
||||
.*/archive/v?([\d\.]+).tar.gz
|
||||
.*/v?(\d\S+)\.tar\.gz
|
||||
|
@ -226,7 +226,7 @@ GTK_GETTEXT_DOMAIN = 'gtk30'
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
COPYRIGHT_MSG = "© 2001-2006 Donald N. Allingham\n" \
|
||||
"© 2007-2020 The Gramps Developers"
|
||||
"© 2007-2022 The Gramps Developers"
|
||||
COMMENTS = _("Gramps\n (Genealogical Research and Analysis "
|
||||
"Management Programming System)\n"
|
||||
"is a personal genealogy program.")
|
||||
|
@ -83,35 +83,37 @@ class DateParserNL(DateParser):
|
||||
month_to_int["xbris"] = 12
|
||||
|
||||
modifier_to_int = {
|
||||
'voor' : Date.MOD_BEFORE,
|
||||
'na' : Date.MOD_AFTER,
|
||||
'tegen' : Date.MOD_ABOUT,
|
||||
'om' : Date.MOD_ABOUT,
|
||||
'rond' : Date.MOD_ABOUT,
|
||||
'circa' : Date.MOD_ABOUT,
|
||||
'ca.' : Date.MOD_ABOUT,
|
||||
'voor' : Date.MOD_BEFORE,
|
||||
'na' : Date.MOD_AFTER,
|
||||
'ca.' : Date.MOD_ABOUT,
|
||||
'circa' : Date.MOD_ABOUT,
|
||||
'om' : Date.MOD_ABOUT,
|
||||
'omstreeks' : Date.MOD_ABOUT,
|
||||
'ongeveer' : Date.MOD_ABOUT,
|
||||
'rond' : Date.MOD_ABOUT,
|
||||
'tegen' : Date.MOD_ABOUT,
|
||||
}
|
||||
|
||||
calendar_to_int = {
|
||||
'gregoriaans' : Date.CAL_GREGORIAN,
|
||||
'greg.' : Date.CAL_GREGORIAN,
|
||||
'juliaans' : Date.CAL_JULIAN,
|
||||
'jul.' : Date.CAL_JULIAN,
|
||||
'hebreeuws' : Date.CAL_HEBREW,
|
||||
'hebr.' : Date.CAL_HEBREW,
|
||||
'islamitisch' : Date.CAL_ISLAMIC,
|
||||
'isl.' : Date.CAL_ISLAMIC,
|
||||
'franse republiek': Date.CAL_FRENCH,
|
||||
'fran.' : Date.CAL_FRENCH,
|
||||
'persisch' : Date.CAL_PERSIAN,
|
||||
'zweeds' : Date.CAL_SWEDISH,
|
||||
'z' : Date.CAL_SWEDISH,
|
||||
'gregoriaans' : Date.CAL_GREGORIAN,
|
||||
'greg.' : Date.CAL_GREGORIAN,
|
||||
'juliaans' : Date.CAL_JULIAN,
|
||||
'jul.' : Date.CAL_JULIAN,
|
||||
'hebreeuws' : Date.CAL_HEBREW,
|
||||
'hebr.' : Date.CAL_HEBREW,
|
||||
'islamitisch' : Date.CAL_ISLAMIC,
|
||||
'isl.' : Date.CAL_ISLAMIC,
|
||||
'frans republiekeins' : Date.CAL_FRENCH,
|
||||
'fran.' : Date.CAL_FRENCH,
|
||||
'persisch' : Date.CAL_PERSIAN,
|
||||
'zweeds' : Date.CAL_SWEDISH,
|
||||
'z' : Date.CAL_SWEDISH,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
'geschat' : Date.QUAL_ESTIMATED,
|
||||
'geschat' : Date.QUAL_ESTIMATED,
|
||||
'gesch.' : Date.QUAL_ESTIMATED,
|
||||
'berekend' : Date.QUAL_CALCULATED,
|
||||
'berekend' : Date.QUAL_CALCULATED,
|
||||
'ber.' : Date.QUAL_CALCULATED,
|
||||
}
|
||||
|
||||
@ -147,17 +149,17 @@ class DateDisplayNL(DateDisplay):
|
||||
|
||||
calendar = (
|
||||
"", "juliaans", "hebreeuws",
|
||||
"franse republiek", "persisch", "islamitisch",
|
||||
"frans republikeins", "persisch", "islamitisch",
|
||||
"zweeds" )
|
||||
|
||||
_mod_str = ("", "voor ", "na ", "rond ", "", "", "")
|
||||
_mod_str = ("", "voor ", "na ", "omstreeks ", "", "", "")
|
||||
|
||||
_qual_str = ("", "geschat ", "berekend ")
|
||||
|
||||
_bce_str = "%s v. Chr."
|
||||
|
||||
formats = (
|
||||
"JJJJ-MM-DD (ISO)", "Numerisch DD/MM/JJ", "Maand Dag, Jaar",
|
||||
"JJJJ-MM-DD (ISO)", "Numeriek DD/MM/JJJJ", "Maand Dag, Jaar",
|
||||
"Mnd. Dag Jaar", "Dag Maand Jaar", "Dag Mnd. Jaar"
|
||||
)
|
||||
# this definition must agree with its "_display_gregorian" method
|
||||
|
@ -52,7 +52,6 @@ methods should be changed to generate exceptions. Possibly by globally changing
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import logging
|
||||
import os
|
||||
import inspect
|
||||
from abc import ABCMeta
|
||||
from types import FunctionType
|
||||
@ -160,10 +159,12 @@ def wrapper(method):
|
||||
"""
|
||||
class_name = args[0].__class__.__name__
|
||||
func_name = method.__name__
|
||||
caller_frame = inspect.stack()[1]
|
||||
frame = inspect.currentframe()
|
||||
c_frame = frame.f_back
|
||||
c_code = c_frame.f_code
|
||||
LOG.debug('calling %s.%s()... from file %s, line %s in %s',
|
||||
class_name, func_name, os.path.split(caller_frame[1])[1],
|
||||
caller_frame[2], caller_frame[3])
|
||||
class_name, func_name, c_code.co_filename, c_frame.f_lineno,
|
||||
c_code.co_name)
|
||||
return method(*args, **keywargs)
|
||||
return wrapped
|
||||
|
||||
|
@ -78,15 +78,13 @@ class DbTxn(defaultdict):
|
||||
|
||||
elapsed_time = time.time() - self.start_time
|
||||
if __debug__:
|
||||
caller_frame = inspect.stack()[1]
|
||||
frame = inspect.currentframe()
|
||||
c_frame = frame.f_back
|
||||
c_code = c_frame.f_code
|
||||
_LOG.debug(" **** DbTxn %s exited. Called from file %s, "
|
||||
"line %s, in %s **** %.2f seconds" %
|
||||
((hex(id(self)),)+
|
||||
(os.path.split(caller_frame[1])[1],)+
|
||||
tuple(caller_frame[i] for i in range(2, 4))+
|
||||
(elapsed_time,)
|
||||
)
|
||||
)
|
||||
"line %s, in %s **** %.2f seconds",
|
||||
hex(id(self)), c_code.co_filename, c_frame.f_lineno,
|
||||
c_code.co_name, elapsed_time)
|
||||
|
||||
return False
|
||||
|
||||
|
@ -42,6 +42,8 @@ from ..const import PLUGINS_DIR, USER_PLUGINS
|
||||
from ..constfunc import win, get_env_var
|
||||
from ..config import config
|
||||
from .dbconst import DBLOGNAME, DBLOCKFN, DBBACKEND
|
||||
from ..const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -70,12 +72,14 @@ def make_database(plugin_id):
|
||||
database = getattr(mod, pdata.databaseclass)
|
||||
db = database()
|
||||
import inspect
|
||||
caller_frame = inspect.stack()[1]
|
||||
frame = inspect.currentframe()
|
||||
c_frame = frame.f_back
|
||||
c_code = c_frame.f_code
|
||||
_LOG.debug("Database class instance created Class:%s instance:%s. "
|
||||
"Called from File %s, line %s, in %s"
|
||||
% ((db.__class__.__name__, hex(id(db)))
|
||||
+ (os.path.split(caller_frame[1])[1],)
|
||||
+ tuple(caller_frame[i] for i in range(2, 4))))
|
||||
"Called from File %s, line %s, in %s",
|
||||
db.__class__.__name__, hex(id(db)), c_code.co_filename,
|
||||
c_frame.f_lineno, c_code.co_name)
|
||||
|
||||
return db
|
||||
else:
|
||||
raise Exception("can't load database backend: '%s'" % plugin_id)
|
||||
@ -209,8 +213,8 @@ def write_lock_file(name):
|
||||
if win():
|
||||
user = get_env_var('USERNAME')
|
||||
host = get_env_var('USERDOMAIN')
|
||||
if host is None:
|
||||
host = ""
|
||||
if not user:
|
||||
user = _("Unknown")
|
||||
else:
|
||||
host = os.uname()[1]
|
||||
# An ugly workaround for os.getlogin() issue with Konsole
|
||||
|
@ -29,7 +29,6 @@ Provide the database state class
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
import inspect
|
||||
|
||||
@ -88,10 +87,12 @@ class DbState(Callback):
|
||||
"""
|
||||
class_name = self.__class__.__name__
|
||||
func_name = "is_open"
|
||||
caller_frame = inspect.stack()[1]
|
||||
frame = inspect.currentframe()
|
||||
c_frame = frame.f_back
|
||||
c_code = c_frame.f_code
|
||||
_LOG.debug('calling %s.%s()... from file %s, line %s in %s',
|
||||
class_name, func_name, os.path.split(caller_frame[1])[1],
|
||||
caller_frame[2], caller_frame[3])
|
||||
class_name, func_name, c_code.co_filename, c_frame.f_lineno,
|
||||
c_code.co_name)
|
||||
return (self.db is not None) and self.db.is_open()
|
||||
|
||||
def change_database(self, database):
|
||||
|
@ -999,6 +999,8 @@ class NameDisplay:
|
||||
1. if group name is defined, use that
|
||||
2. if group name is defined for the primary surname, use that
|
||||
3. use primary surname itself otherwise
|
||||
4. if no primary surname, do we have a ma/patronymic surname ?
|
||||
in this case, group name will be the ma/patronymic name.
|
||||
|
||||
:param pn: raw unserialized data of name
|
||||
:type pn: tuple
|
||||
@ -1007,8 +1009,25 @@ class NameDisplay:
|
||||
"""
|
||||
if pn[_GROUP]:
|
||||
return pn[_GROUP]
|
||||
return db.get_name_group_mapping(_raw_primary_surname_only(
|
||||
pn[_SURNAME_LIST]))
|
||||
name = pn[_GROUP]
|
||||
if not name:
|
||||
# if we have no primary surname, perhaps we have a
|
||||
# patronymic/matronynic name ?
|
||||
srnme = pn[_ORIGINPATRO]
|
||||
surname = []
|
||||
for _surname in srnme:
|
||||
if (_surname[_TYPE_IN_LIST][0] == _ORIGINPATRO
|
||||
or _surname[_TYPE_IN_LIST][0] == _ORIGINMATRO):
|
||||
# Yes, we have one.
|
||||
surname = [_surname]
|
||||
# name1 is the ma/patronymic name.
|
||||
name1 = _raw_patro_surname_only(surname)
|
||||
if name1 and len(srnme) == 1:
|
||||
name = db.get_name_group_mapping(name1)
|
||||
if not name:
|
||||
name = db.get_name_group_mapping(_raw_primary_surname_only(
|
||||
pn[_SURNAME_LIST]))
|
||||
return name
|
||||
|
||||
def _make_fn(self, format_str, d, args):
|
||||
"""
|
||||
|
@ -51,6 +51,7 @@ editor_rule_list = [
|
||||
MediaPrivate,
|
||||
MatchesFilter,
|
||||
MatchesSourceConfidence,
|
||||
HasMedia,
|
||||
HasAttribute,
|
||||
ChangedSince,
|
||||
HasTag,
|
||||
|
@ -52,7 +52,7 @@ class MatchesEventFilter(MatchesEventFilterBase):
|
||||
name = _('Persons with events matching the <event filter>')
|
||||
description = _("Matches persons who have events that match a certain"
|
||||
" event filter")
|
||||
category = _('General filters')
|
||||
category = _('Event filters')
|
||||
|
||||
# we want to have this filter show event filters
|
||||
namespace = 'Event'
|
||||
|
@ -98,9 +98,10 @@ class BaseTest(unittest.TestCase):
|
||||
filter_.set_invert(invert)
|
||||
stime = perf_counter()
|
||||
results = filter_.apply(self.db)
|
||||
if __debug__:
|
||||
rulename = inspect.stack()[1][3]
|
||||
print("%s: %.2f\n" % (rulename, perf_counter() - stime))
|
||||
# if __debug__:
|
||||
# frame = inspect.currentframe()
|
||||
# rulename = frame.f_back.f_code.co_name
|
||||
# print("%s: %.2f\n" % (rulename, perf_counter() - stime))
|
||||
return set(results)
|
||||
|
||||
def test_Complex_1(self):
|
||||
@ -346,7 +347,7 @@ class BaseTest(unittest.TestCase):
|
||||
"""
|
||||
rule = ProbablyAlive(['1900'])
|
||||
res = self.filter_with_rule(rule)
|
||||
self.assertEqual(len(res), 766)
|
||||
self.assertEqual(len(res), 733)
|
||||
|
||||
def test_RegExpName(self):
|
||||
"""
|
||||
|
@ -77,14 +77,14 @@ class Span:
|
||||
self.precision = 2
|
||||
self.negative = False
|
||||
if self.valid:
|
||||
if self.date1.calendar != Date.CAL_GREGORIAN:
|
||||
self.date1 = self.date1.to_calendar("gregorian")
|
||||
if self.date2.calendar != Date.CAL_GREGORIAN:
|
||||
self.date2 = self.date2.to_calendar("gregorian")
|
||||
if self.date1.sortval < self.date2.sortval:
|
||||
self.date1 = date2
|
||||
self.date2 = date1
|
||||
self.negative = True
|
||||
if self.date1.calendar != Date.CAL_GREGORIAN:
|
||||
self.date1 = self.date1.to_calendar("gregorian")
|
||||
if self.date2.calendar != Date.CAL_GREGORIAN:
|
||||
self.date2 = self.date2.to_calendar("gregorian")
|
||||
if self.date1.get_modifier() == Date.MOD_NONE:
|
||||
if self.date2.get_modifier() == Date.MOD_NONE:
|
||||
val = self.date1.sortval - self.date2.sortval
|
||||
|
@ -38,7 +38,7 @@ from ...datehandler import get_date_formats, set_format
|
||||
from ...datehandler import parser as _dp
|
||||
from ...datehandler import displayer as _dd
|
||||
from ...datehandler._datedisplay import DateDisplayEn
|
||||
from ...lib.date import Date, DateError, Today, calendar_has_fixed_newyear
|
||||
from ...lib.date import Date, DateError, Today, calendar_has_fixed_newyear, Span
|
||||
|
||||
date_tests = {}
|
||||
|
||||
@ -432,6 +432,36 @@ class ArithmeticDateTest(BaseDateTest):
|
||||
self.assertEqual(val1, val2,
|
||||
"'%s' should be '%s' but was '%s'" % (exp1, val2, val1))
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# SpanTest
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class SpanTest(BaseDateTest):
|
||||
"""
|
||||
Test spans.
|
||||
"""
|
||||
tests = [((2000, 1, 31), (2000, 1, 1), 30),
|
||||
((1799, 11, 19), (8, 2, 18, Date.CAL_FRENCH), 10),
|
||||
((8, 2, 18, Date.CAL_FRENCH), (1799, 11, 4), 5),
|
||||
((8, 2, 18, Date.CAL_FRENCH), (3, 2, 9, Date.CAL_FRENCH), 1836)]
|
||||
|
||||
def test_evaluate(self):
|
||||
for value1, value2, duration in self.tests:
|
||||
date1 = self._get_date(value1)
|
||||
date2 = self._get_date(value2)
|
||||
span1 = Span(date1, date2)
|
||||
self.assertEqual(int(span1), duration)
|
||||
span2 = Span(date2, date1)
|
||||
self.assertEqual(int(span2), -duration)
|
||||
|
||||
def _get_date(self, value):
|
||||
date = Date()
|
||||
if len(value) == 4:
|
||||
date.set_calendar(value[3])
|
||||
date.set_yr_mon_day(value[0], value[1], value[2])
|
||||
return date
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# SwedishDateTest
|
||||
|
@ -31,8 +31,8 @@ Provide merge capabilities for persons.
|
||||
#-------------------------------------------------------------------------
|
||||
from ..db import DbTxn
|
||||
from ..const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.sgettext
|
||||
from ..errors import MergeError
|
||||
_ = glocale.translation.sgettext
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -49,11 +49,12 @@ class MergePersonQuery:
|
||||
self.titanic = titanic
|
||||
if self.check_for_spouse(self.phoenix, self.titanic):
|
||||
raise MergeError(_("Spouses cannot be merged. To merge these "
|
||||
"people, you must first break the relationship between them."))
|
||||
"people, you must first break the relationship"
|
||||
" between them."))
|
||||
if self.check_for_child(self.phoenix, self.titanic):
|
||||
raise MergeError(_("A parent and child cannot be merged. To merge "
|
||||
"these people, you must first break the relationship between "
|
||||
"them."))
|
||||
"these people, you must first break the relatio"
|
||||
"nship between them."))
|
||||
|
||||
def check_for_spouse(self, person1, person2):
|
||||
"""Return if person1 and person2 are spouses of eachother."""
|
||||
@ -80,12 +81,12 @@ class MergePersonQuery:
|
||||
main_family.merge(family)
|
||||
for childref in family.get_child_ref_list():
|
||||
child = self.database.get_person_from_handle(
|
||||
childref.get_reference_handle())
|
||||
childref.get_reference_handle())
|
||||
if main_family_handle in child.parent_family_list:
|
||||
child.remove_handle_references('Family', [family_handle])
|
||||
else:
|
||||
child.replace_handle_reference('Family', family_handle,
|
||||
main_family_handle)
|
||||
main_family_handle)
|
||||
self.database.commit_person(child, trans)
|
||||
if self.phoenix:
|
||||
self.phoenix.remove_family_handle(family_handle)
|
||||
@ -143,7 +144,8 @@ class MergePersonQuery:
|
||||
for family_handle in self.phoenix.get_parent_family_handle_list():
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
if family.has_handle_reference('Person', old_handle):
|
||||
family.replace_handle_reference('Person', old_handle,new_handle)
|
||||
family.replace_handle_reference('Person', old_handle,
|
||||
new_handle)
|
||||
self.database.commit_family(family, trans)
|
||||
|
||||
family_merge_guard = False
|
||||
@ -182,7 +184,10 @@ class MergePersonQuery:
|
||||
self.database.commit_family(family, trans)
|
||||
parent_list.append(parents)
|
||||
|
||||
if self.database.get_default_handle() == old_handle:
|
||||
self.database.set_default_person_handle(None)
|
||||
hp_hdl = self.database.get_default_handle()
|
||||
if (hp_hdl in (self.phoenix.get_handle(), self.titanic.get_handle())
|
||||
and hp_hdl != self.phoenix.get_handle()):
|
||||
self.database.set_default_person_handle(self.phoenix.get_handle())
|
||||
|
||||
self.database.remove_person(old_handle, trans)
|
||||
return family_merge_ok
|
||||
|
@ -113,6 +113,10 @@ else:
|
||||
_GS_CMD = where_is("gs")
|
||||
|
||||
|
||||
def esc(id_txt):
|
||||
return id_txt.replace('"', '\\"')
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# GVOptions
|
||||
@ -575,7 +579,7 @@ class GVDocBase(BaseDoc, GVDoc):
|
||||
text += ' URL="%s"' % url
|
||||
|
||||
text += " ]"
|
||||
self.write(' "%s" %s;\n' % (node_id, text))
|
||||
self.write(' "%s" %s;\n' % (esc(node_id), text))
|
||||
|
||||
def add_link(self, id1, id2, style="", head="", tail="", comment=""):
|
||||
"""
|
||||
@ -583,7 +587,7 @@ class GVDocBase(BaseDoc, GVDoc):
|
||||
|
||||
Implements GVDocBase.add_link().
|
||||
"""
|
||||
self.write(' "%s" -> "%s"' % (id1, id2))
|
||||
self.write(' "%s" -> "%s"' % (esc(id1), esc(id2)))
|
||||
|
||||
if style or head or tail:
|
||||
self.write(' [')
|
||||
@ -635,7 +639,7 @@ class GVDocBase(BaseDoc, GVDoc):
|
||||
|
||||
Implements GVDocBase.add_samerank().
|
||||
"""
|
||||
self.write(' {rank=same "%s" "%s"}\n' % (id1, id2))
|
||||
self.write(' {rank=same "%s" "%s"}\n' % (esc(id1), esc(id2)))
|
||||
|
||||
def rewrite_label(self, id, label):
|
||||
"""
|
||||
@ -643,7 +647,7 @@ class GVDocBase(BaseDoc, GVDoc):
|
||||
|
||||
Implements GVDocBase.rewrite_label().
|
||||
"""
|
||||
self.write(' "%s" [label = "%s"]\n' % (id, label))
|
||||
self.write(' "%s" [label = "%s"]\n' % (esc(id), label))
|
||||
|
||||
def start_subgraph(self, graph_id):
|
||||
""" Implement GVDocBase.start_subgraph() """
|
||||
|
@ -142,6 +142,8 @@ class ProbablyAlive:
|
||||
# person died more than MAX after current year
|
||||
if death_date.is_valid():
|
||||
birth_date = death_date.copy_offset_ymd(year=-self.MAX_AGE_PROB_ALIVE)
|
||||
else:
|
||||
birth_date = death_date
|
||||
explain = _("death date")
|
||||
|
||||
if not death_date and birth_date:
|
||||
|
@ -324,12 +324,16 @@ class Callback:
|
||||
return
|
||||
|
||||
# Check signal exists
|
||||
frame = inspect.currentframe()
|
||||
c_frame = frame.f_back
|
||||
c_code = c_frame.f_code
|
||||
frame_info = (c_code.co_filename, c_frame.f_lineno, c_code.co_name)
|
||||
if signal_name not in self.__signal_map:
|
||||
self._warn("Attempt to emit to unknown signal: %s\n"
|
||||
" from: file: %s\n"
|
||||
" line: %d\n"
|
||||
" func: %s\n"
|
||||
% ((str(signal_name), ) + inspect.stack()[1][1:4]))
|
||||
% ((str(signal_name), ) + frame_info))
|
||||
return
|
||||
|
||||
# check that the signal is not already being emitted. This prevents
|
||||
@ -340,7 +344,7 @@ class Callback:
|
||||
" from: file: %s\n"
|
||||
" line: %d\n"
|
||||
" func: %s\n"
|
||||
% ((str(signal_name), ) + inspect.stack()[1][1:4]))
|
||||
% ((str(signal_name), ) + frame_info))
|
||||
return
|
||||
|
||||
try:
|
||||
@ -358,7 +362,7 @@ class Callback:
|
||||
" from: file: %s\n"
|
||||
" line: %d\n"
|
||||
" func: %s\n"
|
||||
% ((str(signal_name), ) + inspect.stack()[1][1:4]))
|
||||
% ((str(signal_name), ) + frame_info))
|
||||
return
|
||||
|
||||
# type check arguments
|
||||
@ -369,7 +373,7 @@ class Callback:
|
||||
" from: file: %s\n"
|
||||
" line: %d\n"
|
||||
" func: %s\n"
|
||||
% ((str(signal_name), ) + inspect.stack()[1][1:4]))
|
||||
% ((str(signal_name), ) + frame_info))
|
||||
return
|
||||
|
||||
if len(args) > 0:
|
||||
@ -379,7 +383,7 @@ class Callback:
|
||||
" from: file: %s\n"
|
||||
" line: %d\n"
|
||||
" func: %s\n"
|
||||
% ((str(signal_name), ) + inspect.stack()[1][1:4]))
|
||||
% ((str(signal_name), ) + frame_info))
|
||||
return
|
||||
|
||||
if arg_types is not None:
|
||||
@ -391,7 +395,7 @@ class Callback:
|
||||
" line: %d\n"
|
||||
" func: %s\n"
|
||||
" arg passed was: %s, type of arg passed %s, type should be: %s\n"
|
||||
% ((str(signal_name), ) + inspect.stack()[1][1:4] +\
|
||||
% ((str(signal_name), ) + frame_info +\
|
||||
(args[i], repr(type(args[i])), repr(arg_types[i]))))
|
||||
return
|
||||
if signal_name in self.__callback_map:
|
||||
|
@ -49,7 +49,7 @@ class CSVTab(TabbedDoc):
|
||||
else:
|
||||
self.filename = filename
|
||||
|
||||
self.f = open(self.filename, "w",
|
||||
self.f = open(self.filename, "w", newline='',
|
||||
encoding='utf_8_sig' if win() else 'utf_8')
|
||||
self.writer = csv.writer(self.f)
|
||||
|
||||
|
@ -526,6 +526,8 @@ class GrampsLocale:
|
||||
# with locale instead of gettext. Win32 doesn't support bindtextdomain.
|
||||
if self.localedir:
|
||||
if not sys.platform == 'win32':
|
||||
# bug12278, _build_popup_ui() under linux and macOS
|
||||
locale.textdomain(self.localedomain)
|
||||
locale.bindtextdomain(self.localedomain, self.localedir)
|
||||
else:
|
||||
self._win_bindtextdomain(self.localedomain.encode('utf-8'),
|
||||
|
@ -127,15 +127,32 @@ if win():
|
||||
elif not os.path.isdir(HOME_DIR):
|
||||
os.makedirs(HOME_DIR)
|
||||
sys.stdout = sys.stderr = open(logfile, "w", encoding='utf-8')
|
||||
stderrh = logging.StreamHandler(sys.stderr)
|
||||
stderrh.setFormatter(form)
|
||||
stderrh.setLevel(logging.DEBUG)
|
||||
# macOS sets stderr to /dev/null when running without a terminal,
|
||||
# e.g. if Gramps.app is lauched by double-clicking on it in
|
||||
# finder. Write to a file instead.
|
||||
if mac() and not sys.stdin.isatty():
|
||||
from tempfile import gettempdir
|
||||
|
||||
# Setup the base level logger, this one gets
|
||||
# everything.
|
||||
l = logging.getLogger()
|
||||
l.setLevel(logging.WARNING)
|
||||
l.addHandler(stderrh)
|
||||
log_file_name = 'gramps-' + str(os.getpid()) + '.log'
|
||||
log_file_path = os.path.join(gettempdir(), log_file_name)
|
||||
log_file_handler = logging.FileHandler(log_file_path, mode='a',
|
||||
encoding='utf-8')
|
||||
log_file_handler.setFormatter(form)
|
||||
log_file_handler.setLevel(logging.DEBUG)
|
||||
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(logging.WARNING)
|
||||
logger.addHandler(log_file_handler)
|
||||
else:
|
||||
stderrh = logging.StreamHandler(sys.stderr)
|
||||
stderrh.setFormatter(form)
|
||||
stderrh.setLevel(logging.DEBUG)
|
||||
|
||||
# Setup the base level logger, this one gets
|
||||
# everything.
|
||||
l = logging.getLogger()
|
||||
l.setLevel(logging.WARNING)
|
||||
l.addHandler(stderrh)
|
||||
|
||||
|
||||
def exc_hook(err_type, value, t_b):
|
||||
|
@ -471,27 +471,36 @@ class ClipCitation(ClipHandleWrapper):
|
||||
|
||||
def refresh(self):
|
||||
if self._handle:
|
||||
citation = clipdb.get_citation_from_handle(self._handle)
|
||||
if citation:
|
||||
self._title = citation.get_gramps_id()
|
||||
notelist = list(map(clipdb.get_note_from_handle,
|
||||
citation.get_note_list()))
|
||||
srctxtlist = [note for note in notelist
|
||||
if note.get_type() == NoteType.SOURCE_TEXT]
|
||||
page = citation.get_page()
|
||||
if not page:
|
||||
page = _('NA', 'not available')
|
||||
text = ""
|
||||
if srctxtlist:
|
||||
text = " ".join(srctxtlist[0].get().split())
|
||||
#String must be unicode for truncation to work for non
|
||||
#ascii characters
|
||||
text = str(text)
|
||||
if len(text) > 60:
|
||||
text = text[:60] + "..."
|
||||
self._value = _("Volume/Page: %(pag)s -- %(sourcetext)s") % {
|
||||
'pag' : page,
|
||||
'sourcetext' : text}
|
||||
try:
|
||||
citation = clipdb.get_citation_from_handle(self._handle)
|
||||
if citation:
|
||||
self._title = citation.get_gramps_id()
|
||||
notelist = list(map(clipdb.get_note_from_handle,
|
||||
citation.get_note_list()))
|
||||
srctxtlist = [note for note in notelist
|
||||
if note.get_type() == NoteType.SOURCE_TEXT]
|
||||
page = citation.get_page()
|
||||
if not page:
|
||||
page = _('NA', 'not available')
|
||||
text = ""
|
||||
if srctxtlist:
|
||||
text = " ".join(srctxtlist[0].get().split())
|
||||
#String must be unicode for truncation to work for non
|
||||
#ascii characters
|
||||
text = str(text)
|
||||
if len(text) > 60:
|
||||
text = text[:60] + "..."
|
||||
self._value = _("Volume/Page: %(pag)s -- %(sourcetext)s"
|
||||
) % { 'pag' : page,
|
||||
'sourcetext' : text}
|
||||
except:
|
||||
# We are in the Source tree view. The shortcuts only
|
||||
# work for citations.
|
||||
print("We cannot copy the source from this view."
|
||||
" Use drag and drop.")
|
||||
self._title = self._value = ''
|
||||
self._pickle = self._type = self._objclass = None
|
||||
self._handle = self._dbid = self._dbname = None
|
||||
|
||||
|
||||
class ClipRepoRef(ClipObjWrapper):
|
||||
@ -1281,6 +1290,14 @@ class ClipboardListView:
|
||||
model.insert_before(node, data)
|
||||
else:
|
||||
model.insert_after(node, data)
|
||||
elif isinstance(data[1], ClipCitation):
|
||||
if data[3]:
|
||||
# we have a real citation
|
||||
model.append(data)
|
||||
#else:
|
||||
# We are in a Source treeview and trying
|
||||
# to copy a source with a shortcut.
|
||||
# Use drag and drop to do that.
|
||||
else:
|
||||
model.append(data)
|
||||
|
||||
|
@ -469,7 +469,7 @@ class GrampsImportFileDialog(ManagedWindow):
|
||||
return True
|
||||
else:
|
||||
try:
|
||||
f = open(filename,'w')
|
||||
f = open(filename, 'w')
|
||||
f.close()
|
||||
os.remove(filename)
|
||||
except IOError:
|
||||
@ -485,7 +485,6 @@ class GrampsImportFileDialog(ManagedWindow):
|
||||
self.import_info = None
|
||||
self._begin_progress()
|
||||
self.uistate.set_sensitive(False)
|
||||
self.uistate.viewmanager.enable_menu(False)
|
||||
|
||||
try:
|
||||
#an importer can return an object with info, object.info_text()
|
||||
@ -506,7 +505,6 @@ class GrampsImportFileDialog(ManagedWindow):
|
||||
except Exception:
|
||||
_LOG.error("Failed to import database.", exc_info=True)
|
||||
self.uistate.set_sensitive(True)
|
||||
self.uistate.viewmanager.enable_menu(True)
|
||||
self._end_progress()
|
||||
|
||||
def build_menu_names(self, obj): # this is meaningless since it's modal
|
||||
|
@ -1013,7 +1013,7 @@ class DbManager(CLIDbManager, ManagedWindow):
|
||||
"""
|
||||
Handle the reception of drag data
|
||||
"""
|
||||
drag_value = selection.get_data().decode()
|
||||
drag_value = selection.get_data().decode().strip(' \r\n\x00')
|
||||
fname = None
|
||||
type = None
|
||||
title = None
|
||||
|
@ -538,7 +538,10 @@ class DisplayState(Callback):
|
||||
history.push(handle)
|
||||
|
||||
def set_sensitive(self, state):
|
||||
self.window.set_sensitive(state)
|
||||
tbar = self.uimanager.get_widget('ToolBar')
|
||||
tbar.set_sensitive(state)
|
||||
self.viewmanager.hpane.set_sensitive(state)
|
||||
self.uimanager.enable_all_actions(state)
|
||||
|
||||
def db_changed(self, db):
|
||||
db.connect('long-op-start', self.progress_monitor.add_op)
|
||||
|
@ -366,6 +366,7 @@ class EditName(EditSecondary):
|
||||
5/ local set, not global set --> set (change local)
|
||||
6/ local set, global set --> set (set to global if possible)
|
||||
"""
|
||||
ngm = False # name group mapping setting
|
||||
closeit = True
|
||||
surname = self.obj.get_primary_surname().get_surname()
|
||||
group_as= self.obj.get_group_as()
|
||||
@ -388,7 +389,7 @@ class EditName(EditSecondary):
|
||||
val = q.run()
|
||||
if val:
|
||||
#delete the grouping link on database
|
||||
self.db.set_name_group_mapping(surname, None)
|
||||
ngm = None # delay setting until dialog closes
|
||||
self.obj.set_group_as("")
|
||||
else :
|
||||
closeit = False
|
||||
@ -421,9 +422,9 @@ class EditName(EditSecondary):
|
||||
val = q.run()
|
||||
if val:
|
||||
if group_as == surname :
|
||||
self.db.set_name_group_mapping(surname, None)
|
||||
ngm = None # delay setting until dialog closes
|
||||
else:
|
||||
self.db.set_name_group_mapping(surname, group_as)
|
||||
ngm = group_as # delay setting until dialog closes
|
||||
self.obj.set_group_as("")
|
||||
else:
|
||||
if self.global_group_set :
|
||||
@ -455,10 +456,15 @@ class EditName(EditSecondary):
|
||||
pass
|
||||
|
||||
if closeit:
|
||||
db = self.db # close cleanup loses self.db, so save for later
|
||||
if self.callback:
|
||||
self.callback(self.obj)
|
||||
self.callback = None
|
||||
self.close()
|
||||
# bug 12328 to avoid gui interaction during view rebuild, delay
|
||||
# the rebuild until closeing this dialog
|
||||
if ngm is not False:
|
||||
db.set_name_group_mapping(surname, ngm)
|
||||
|
||||
def _cleanup_on_exit(self):
|
||||
"""
|
||||
|
@ -186,13 +186,40 @@ class EditPlace(EditPrimary):
|
||||
self.db.readonly)
|
||||
|
||||
def set_latlongitude(self, value):
|
||||
"""
|
||||
This method is useful for directly copying the coordinates
|
||||
of openstreetmap, googlemaps, and perhaps other if they
|
||||
provide coordinates like it is define in conv_lat_lon
|
||||
(see gramps/gen/utils/place.py)
|
||||
|
||||
To copy the coordinates:
|
||||
|
||||
- openstreetmap:
|
||||
1 - choose the place where you want to save the coordinates.
|
||||
2 - right click on this place
|
||||
3 - select "show address"
|
||||
4 - On the left side of the map, copy the coordinates of
|
||||
"Result from internal"
|
||||
5 - In the latlon field of the edit place window of gramps,
|
||||
type <CTRL> V
|
||||
|
||||
- googlemap:
|
||||
1 - choose the place where you want to save the coordinates.
|
||||
2 - right click on this place
|
||||
3 - select the coordinates at the top of the popup window.
|
||||
They are automaticaly copied.
|
||||
4 - In the latlon field of the edit place window of gramps,
|
||||
type <CTRL> V
|
||||
|
||||
"""
|
||||
try:
|
||||
parts = value.index(', ')
|
||||
# Bug 12349, 12374
|
||||
parts = value.split(', ')
|
||||
if len(parts) == 2:
|
||||
longitude = parts[0].strip().replace(',', '.')
|
||||
latitude = parts[1].strip().replace(',', '.')
|
||||
latitude = parts[0].strip().replace(',', '.')
|
||||
longitude = parts[1].strip().replace(',', '.')
|
||||
else:
|
||||
longitude, latitude = value.split(',')
|
||||
latitude, longitude = value.split(',')
|
||||
|
||||
self.longitude.set_text(longitude)
|
||||
self.latitude.set_text(latitude)
|
||||
|
@ -181,12 +181,13 @@ class EditPlaceRef(EditReference):
|
||||
|
||||
def set_latlongitude(self, value):
|
||||
try:
|
||||
parts = value.index(', ')
|
||||
# Bug 12349, 12374
|
||||
parts = value.split(', ')
|
||||
if len(parts) == 2:
|
||||
longitude = parts[0].strip().replace(',', '.')
|
||||
latitude = parts[1].strip().replace(',', '.')
|
||||
latitude = parts[0].strip().replace(',', '.')
|
||||
longitude = parts[1].strip().replace(',', '.')
|
||||
else:
|
||||
longitude, latitude = value.split(',')
|
||||
latitude, longitude = value.split(',')
|
||||
|
||||
self.longitude.set_text(longitude)
|
||||
self.latitude.set_text(latitude)
|
||||
|
@ -1,11 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.18.3 -->
|
||||
<!-- Generated with glade 3.22.2 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.10"/>
|
||||
<requires lib="grampswidgets" version="0.0"/>
|
||||
<object class="GtkDialog" id="editplace">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog-vbox19">
|
||||
<property name="visible">True</property>
|
||||
@ -101,7 +103,7 @@
|
||||
<child>
|
||||
<object class="GtkLabel" id="comment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Either use the two fields below to enter coordinates (latitude and longitude),</property>
|
||||
<property name="hexpand">True</property>
|
||||
|
@ -325,7 +325,6 @@ class BaseSelector(ManagedWindow):
|
||||
self.sortorder = Gtk.SortType.ASCENDING
|
||||
else:
|
||||
self.sortorder = Gtk.SortType.DESCENDING
|
||||
self.model.reverse_order()
|
||||
self.build_tree()
|
||||
|
||||
return True
|
||||
|
@ -496,6 +496,16 @@ class UIManager():
|
||||
"""
|
||||
return group.act_group.lookup_action(actionname)
|
||||
|
||||
def enable_all_actions(self, state):
|
||||
for group in self.action_groups:
|
||||
if group.act_group:
|
||||
for item in group.actionlist:
|
||||
action = group.act_group.lookup_action(item[ACTION_NAME])
|
||||
if action:
|
||||
# We check in case the group has not been inserted into
|
||||
# UIManager yet
|
||||
action.set_enabled(group.sensitive if state else False)
|
||||
|
||||
def dump_all_accels(self):
|
||||
''' A function used diagnostically to see what accels are present.
|
||||
This will only dump the current accel set, if other non-open windows
|
||||
|
@ -450,7 +450,7 @@ def open_file_with_default_application(path, uistate):
|
||||
GLib.timeout_add_seconds(1, poll_external, (proc, errstrings, uistate))
|
||||
return
|
||||
|
||||
def process_pending_events(max_count=10):
|
||||
def process_pending_events(max_count=20):
|
||||
"""
|
||||
Process pending events, but don't get into an infinite loop.
|
||||
"""
|
||||
|
@ -277,13 +277,13 @@ class ViewManager(CLIManager):
|
||||
Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.MOD1_MASK)
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
self.window.add(vbox)
|
||||
hpane = Gtk.Paned()
|
||||
self.hpane = Gtk.Paned()
|
||||
self.ebox = Gtk.EventBox()
|
||||
|
||||
self.navigator = Navigator(self)
|
||||
self.ebox.add(self.navigator.get_top())
|
||||
hpane.pack1(self.ebox, False, False)
|
||||
hpane.show()
|
||||
self.hpane.pack1(self.ebox, False, False)
|
||||
self.hpane.show()
|
||||
|
||||
self.notebook = Gtk.Notebook()
|
||||
self.notebook.set_scrollable(True)
|
||||
@ -292,13 +292,14 @@ class ViewManager(CLIManager):
|
||||
self.__init_lists()
|
||||
self.__build_ui_manager()
|
||||
|
||||
hpane.add2(self.notebook)
|
||||
self.hpane.add2(self.notebook)
|
||||
toolbar = self.uimanager.get_widget('ToolBar')
|
||||
toolbar.show_all()
|
||||
self.statusbar = Statusbar()
|
||||
self.statusbar.show()
|
||||
vbox.pack_end(self.statusbar, False, True, 0)
|
||||
vbox.pack_start(toolbar, False, True, 0)
|
||||
vbox.pack_end(hpane, True, True, 0)
|
||||
vbox.pack_end(self.hpane, True, True, 0)
|
||||
vbox.show()
|
||||
|
||||
self.uistate = DisplayState(self.window, self.statusbar,
|
||||
@ -839,6 +840,7 @@ class ViewManager(CLIManager):
|
||||
hbox.add(Gtk.Label(label=pdata.name))
|
||||
hbox.show_all()
|
||||
page_num = self.notebook.append_page(page.get_display(), hbox)
|
||||
self.active_page.post_create()
|
||||
if not self.file_loaded:
|
||||
self.uimanager.set_actions_visible(self.actiongroup, False)
|
||||
self.uimanager.set_actions_visible(self.readonlygroup, False)
|
||||
@ -887,12 +889,17 @@ class ViewManager(CLIManager):
|
||||
while Gtk.events_pending():
|
||||
Gtk.main_iteration()
|
||||
|
||||
self.uimanager.update_menu()
|
||||
# bug 12048 this avoids crash if part of toolbar in view is not shown
|
||||
# because of a small screen when changing views. Part of the Gtk code
|
||||
# was deleting a toolbar object too soon; and another part of Gtk still
|
||||
# had a reference.
|
||||
def page_changer(self):
|
||||
self.uimanager.update_menu()
|
||||
self.active_page.change_page()
|
||||
return False
|
||||
|
||||
while Gtk.events_pending():
|
||||
Gtk.main_iteration()
|
||||
|
||||
self.active_page.change_page()
|
||||
GLib.idle_add(page_changer, self,
|
||||
priority=GLib.PRIORITY_DEFAULT_IDLE - 10)
|
||||
|
||||
def __delete_pages(self):
|
||||
"""
|
||||
@ -997,7 +1004,8 @@ class ViewManager(CLIManager):
|
||||
The method called after load of a new database.
|
||||
Inherit CLI method to add GUI part
|
||||
"""
|
||||
self._post_load_newdb_nongui(filename, title)
|
||||
if self.dbstate.db.is_open():
|
||||
self._post_load_newdb_nongui(filename, title)
|
||||
self._post_load_newdb_gui(filename, filetype, title)
|
||||
|
||||
def _post_load_newdb_gui(self, filename, filetype, title=None):
|
||||
@ -1065,51 +1073,6 @@ class ViewManager(CLIManager):
|
||||
config.set('paths.recent-file', '')
|
||||
config.save()
|
||||
|
||||
def enable_menu(self, enable):
|
||||
""" Enable/disable the menues. Used by the dbloader for import to
|
||||
prevent other operations during import. Needed because simpler methods
|
||||
don't work under Gnome with application menus at top of screen (instead
|
||||
of Gramps window).
|
||||
Note: enable must be set to False on first call.
|
||||
"""
|
||||
if not enable:
|
||||
self.action_st = (
|
||||
self.uimanager.get_actions_sensitive(self.actiongroup),
|
||||
self.uimanager.get_actions_sensitive(self.readonlygroup),
|
||||
self.uimanager.get_actions_sensitive(self.undoactions),
|
||||
self.uimanager.get_actions_sensitive(self.redoactions),
|
||||
self.uimanager.get_actions_sensitive(self.fileactions),
|
||||
self.uimanager.get_actions_sensitive(self.toolactions),
|
||||
self.uimanager.get_actions_sensitive(self.reportactions),
|
||||
self.uimanager.get_actions_sensitive(
|
||||
self.recent_manager.action_group))
|
||||
self.uimanager.set_actions_sensitive(self.actiongroup, enable)
|
||||
self.uimanager.set_actions_sensitive(self.readonlygroup, enable)
|
||||
self.uimanager.set_actions_sensitive(self.undoactions, enable)
|
||||
self.uimanager.set_actions_sensitive(self.redoactions, enable)
|
||||
self.uimanager.set_actions_sensitive(self.fileactions, enable)
|
||||
self.uimanager.set_actions_sensitive(self.toolactions, enable)
|
||||
self.uimanager.set_actions_sensitive(self.reportactions, enable)
|
||||
self.uimanager.set_actions_sensitive(
|
||||
self.recent_manager.action_group, enable)
|
||||
else:
|
||||
self.uimanager.set_actions_sensitive(
|
||||
self.actiongroup, self.action_st[0])
|
||||
self.uimanager.set_actions_sensitive(
|
||||
self.readonlygroup, self.action_st[1])
|
||||
self.uimanager.set_actions_sensitive(
|
||||
self.undoactions, self.action_st[2])
|
||||
self.uimanager.set_actions_sensitive(
|
||||
self.redoactions, self.action_st[3])
|
||||
self.uimanager.set_actions_sensitive(
|
||||
self.fileactions, self.action_st[4])
|
||||
self.uimanager.set_actions_sensitive(
|
||||
self.toolactions, self.action_st[5])
|
||||
self.uimanager.set_actions_sensitive(
|
||||
self.reportactions, self.action_st[6])
|
||||
self.uimanager.set_actions_sensitive(
|
||||
self.recent_manager.action_group, self.action_st[7])
|
||||
|
||||
def __change_undo_label(self, label, update_menu=True):
|
||||
"""
|
||||
Change the UNDO label
|
||||
|
@ -138,6 +138,7 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
|
||||
self.sidebar = None
|
||||
self.bottombar = None
|
||||
self.widget = None
|
||||
self.vpane = None
|
||||
|
||||
DbGUIElement.__init__(self, dbstate.db)
|
||||
|
||||
@ -154,18 +155,20 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
|
||||
self.ident + "_bottombar",
|
||||
defaults[1])
|
||||
hpane = Gtk.Paned()
|
||||
vpane = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
||||
hpane.pack1(vpane, resize=True, shrink=False)
|
||||
self.vpane = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
||||
hpane.pack1(self.vpane, resize=True, shrink=False)
|
||||
hpane.pack2(self.sidebar, resize=False, shrink=False)
|
||||
hpane.show()
|
||||
vpane.show()
|
||||
self.vpane.show()
|
||||
|
||||
self.widget = self.build_widget()
|
||||
self.widget.show_all()
|
||||
self.widget.set_name('view')
|
||||
vpane.pack1(self.widget, resize=True, shrink=False)
|
||||
vpane.pack2(self.bottombar, resize=False, shrink=True)
|
||||
self._setup_slider_config(vpane, 'vpane.slider-position')
|
||||
self.vpane.pack1(self.widget, resize=True, shrink=False)
|
||||
self.vpane.pack2(self.bottombar, resize=False, shrink=False)
|
||||
self.vpane.show()
|
||||
self._config.register('vpane.slider-position', -1)
|
||||
self.vpane.set_position(self._config.get('vpane.slider-position'))
|
||||
|
||||
self.sidebar_toggled(self.sidebar.get_property('visible'))
|
||||
self.hpane_sig = hpane.connect("draw", self.set_page_slider)
|
||||
@ -343,6 +346,11 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
|
||||
self.bottombar.set_inactive()
|
||||
self.active = False
|
||||
|
||||
def post_create(self):
|
||||
if self.vpane:
|
||||
self._setup_slider_config(self.vpane, 'vpane.slider-position')
|
||||
self.vpane = None
|
||||
|
||||
@abstractmethod
|
||||
def build_tree(self):
|
||||
"""
|
||||
|
@ -373,10 +373,6 @@ class GrampletBar(Gtk.Notebook):
|
||||
"""
|
||||
Add a tab to the notebook for the given gramplet.
|
||||
"""
|
||||
width = -1 # Allow tab width to adjust (smaller) to sidebar
|
||||
height = min(int(self.uistate.screen_height() * 0.20), 400)
|
||||
gramplet.set_size_request(width, height)
|
||||
|
||||
label = self.__create_tab_label(gramplet)
|
||||
page_num = self.append_page(gramplet, label)
|
||||
return page_num
|
||||
|
@ -1240,6 +1240,12 @@ class GrampletPane(Gtk.ScrolledWindow):
|
||||
else:
|
||||
cnt = 0
|
||||
for item in base_opts["data"]:
|
||||
# If we have a "%" in a string,
|
||||
# escape it by writing "%%"
|
||||
# to avoid InterpolationSyntaxError
|
||||
# in python configparser module.
|
||||
if isinstance(item, str):
|
||||
item = item.replace("%", "%%")
|
||||
fp.write("data[%d]=%s\n" % (cnt, item))
|
||||
cnt += 1
|
||||
else:
|
||||
|
@ -225,6 +225,16 @@ class DBAPI(DbGeneric):
|
||||
if self.transaction == None:
|
||||
self.dbapi.rollback()
|
||||
|
||||
def _collation(self, locale):
|
||||
"""
|
||||
Get the adjusted collation if there is one, falling back on
|
||||
the locale.collation.
|
||||
"""
|
||||
collation = self.dbapi.check_collation(locale)
|
||||
if collation == None:
|
||||
return locale.get_collation()
|
||||
return collation
|
||||
|
||||
def transaction_begin(self, transaction):
|
||||
"""
|
||||
Transactions are handled automatically by the db layer.
|
||||
@ -365,12 +375,9 @@ class DBAPI(DbGeneric):
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM person '
|
||||
'ORDER BY surname '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
'COLLATE "%s"' % self._collation(locale))
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM person")
|
||||
rows = self.dbapi.fetchall()
|
||||
@ -387,9 +394,6 @@ class DBAPI(DbGeneric):
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
sql = ('SELECT family.handle ' +
|
||||
'FROM family ' +
|
||||
'LEFT JOIN person AS father ' +
|
||||
@ -404,7 +408,7 @@ class DBAPI(DbGeneric):
|
||||
'THEN mother.given_name ' +
|
||||
'ELSE father.given_name ' +
|
||||
'END) ' +
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
'COLLATE "%s"' % self._collation(locale))
|
||||
self.dbapi.execute(sql)
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM family")
|
||||
@ -431,12 +435,9 @@ class DBAPI(DbGeneric):
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM citation '
|
||||
'ORDER BY page '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
'COLLATE "%s"' % self._collation(locale))
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM citation")
|
||||
rows = self.dbapi.fetchall()
|
||||
@ -453,12 +454,9 @@ class DBAPI(DbGeneric):
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM source '
|
||||
'ORDER BY title '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
'COLLATE "%s"' % self._collation(locale))
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle from source")
|
||||
rows = self.dbapi.fetchall()
|
||||
@ -475,12 +473,9 @@ class DBAPI(DbGeneric):
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM place '
|
||||
'ORDER BY title '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
'COLLATE "%s"' % self._collation(locale))
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM place")
|
||||
rows = self.dbapi.fetchall()
|
||||
@ -506,12 +501,9 @@ class DBAPI(DbGeneric):
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM media '
|
||||
'ORDER BY desc '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
'COLLATE "%s"' % self._collation(locale))
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM media")
|
||||
rows = self.dbapi.fetchall()
|
||||
@ -537,12 +529,9 @@ class DBAPI(DbGeneric):
|
||||
:type locale: A GrampsLocale object.
|
||||
"""
|
||||
if sort_handles:
|
||||
if locale != glocale:
|
||||
self.dbapi.check_collation(locale)
|
||||
|
||||
self.dbapi.execute('SELECT handle FROM tag '
|
||||
'ORDER BY name '
|
||||
'COLLATE "%s"' % locale.get_collation())
|
||||
'COLLATE "%s"' % self._collation(locale))
|
||||
else:
|
||||
self.dbapi.execute("SELECT handle FROM tag")
|
||||
rows = self.dbapi.fetchall()
|
||||
@ -589,12 +578,13 @@ class DBAPI(DbGeneric):
|
||||
"WHERE name = ?", [grouping, name])
|
||||
elif row and grouping is None:
|
||||
self.dbapi.execute("DELETE FROM name_group WHERE name = ?", [name])
|
||||
grouping = ''
|
||||
else:
|
||||
self.dbapi.execute(
|
||||
"INSERT INTO name_group (name, grouping) VALUES (?, ?)",
|
||||
[name, grouping])
|
||||
self._txn_commit()
|
||||
if grouping is None:
|
||||
grouping = ''
|
||||
self.emit('person-groupname-rebuild', (name, grouping))
|
||||
|
||||
def _commit_base(self, obj, obj_key, trans, change_time):
|
||||
|
@ -117,6 +117,8 @@ class Connection:
|
||||
collation = locale.get_collation().translate(self.__tmap)
|
||||
if collation not in self.__collations:
|
||||
self.__connection.create_collation(collation, locale.strcoll)
|
||||
self.__collations.append(collation)
|
||||
return collation
|
||||
|
||||
def execute(self, *args, **kwargs):
|
||||
"""
|
||||
|
@ -31,7 +31,7 @@ SVG document generator.
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from io import StringIO
|
||||
|
||||
from xml.sax.saxutils import escape
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
@ -147,7 +147,7 @@ class SvgDrawDoc(BaseDoc, DrawDoc):
|
||||
linex = xpos + (width - self.string_width(font, line)) / 2
|
||||
self.buffer.write(
|
||||
'<tspan x="%4.2f" dy="%d">' % (linex, size) +
|
||||
line +
|
||||
escape(line) +
|
||||
'</tspan>'
|
||||
)
|
||||
self.buffer.write('</text>\n')
|
||||
@ -273,7 +273,7 @@ class SvgDrawDoc(BaseDoc, DrawDoc):
|
||||
self.buffer.write(' font-family:serif;')
|
||||
self.buffer.write(
|
||||
'">' +
|
||||
line +
|
||||
escape(line) +
|
||||
'</text>\n'
|
||||
)
|
||||
|
||||
@ -307,7 +307,7 @@ class SvgDrawDoc(BaseDoc, DrawDoc):
|
||||
self.buffer.write('font-family:serif;')
|
||||
self.buffer.write(
|
||||
'">' +
|
||||
text +
|
||||
escape(text) +
|
||||
'</text>\n'
|
||||
)
|
||||
|
||||
|
@ -267,7 +267,8 @@ class Calendar(Report):
|
||||
day_col * cell_width + cell_width/2,
|
||||
header + week_row * cell_height)
|
||||
list_ = self.calendar.get(month, {}).get(thisday.day, [])
|
||||
list_.sort() # to get CAL-Holiday on bottom
|
||||
# sort the list to get CAL-Holiday on bottom
|
||||
list_.sort(key=lambda x: (x[0], x[1]))
|
||||
position = spacing
|
||||
for (format, p, m_list) in list_:
|
||||
for line in reversed(p.split("\n")):
|
||||
|
@ -202,7 +202,7 @@ class CalendarWriter:
|
||||
date = event.get_date_object()
|
||||
place_handle = event.get_place_handle()
|
||||
date_string = self.format_date(date, 1)
|
||||
if date_string is not "":
|
||||
if date_string != "":
|
||||
# self.writeln("")
|
||||
self.writeln("BEGIN:VEVENT")
|
||||
time_s = time.gmtime(event.change)
|
||||
|
@ -125,13 +125,17 @@ class Backlinks(Gramplet):
|
||||
|
||||
edit_object(self.dbstate, self.uistate, objclass, handle)
|
||||
|
||||
def db_changed(self):
|
||||
for item in ['person', 'family', 'source', 'citation', 'event',
|
||||
'media', 'place', 'repository', 'note']:
|
||||
self.connect(self.dbstate.db, '%s-delete' % item, self.update)
|
||||
self.connect(self.dbstate.db, '%s-add' % item, self.update)
|
||||
self.connect(self.dbstate.db, '%s-update' % item, self.update)
|
||||
|
||||
class PersonBacklinks(Backlinks):
|
||||
"""
|
||||
Displays the back references for a person.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.connect(self.dbstate.db, 'person-update', self.update)
|
||||
|
||||
def active_changed(self, handle):
|
||||
self.update()
|
||||
|
||||
@ -152,7 +156,7 @@ class EventBacklinks(Backlinks):
|
||||
Displays the back references for an event.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.connect(self.dbstate.db, 'event-update', self.update)
|
||||
super().db_changed()
|
||||
self.connect_signal('Event', self.update)
|
||||
|
||||
def update_has_data(self):
|
||||
@ -172,7 +176,7 @@ class FamilyBacklinks(Backlinks):
|
||||
Displays the back references for a family.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.connect(self.dbstate.db, 'family-update', self.update)
|
||||
super().db_changed()
|
||||
self.connect_signal('Family', self.update)
|
||||
|
||||
def update_has_data(self):
|
||||
@ -192,7 +196,7 @@ class PlaceBacklinks(Backlinks):
|
||||
Displays the back references for a place.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.connect(self.dbstate.db, 'place-update', self.update)
|
||||
super().db_changed()
|
||||
self.connect_signal('Place', self.update)
|
||||
|
||||
def update_has_data(self):
|
||||
@ -212,7 +216,7 @@ class SourceBacklinks(Backlinks):
|
||||
Displays the back references for a source,.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.connect(self.dbstate.db, 'source-update', self.update)
|
||||
super().db_changed()
|
||||
self.connect_signal('Source', self.update)
|
||||
|
||||
def update_has_data(self):
|
||||
@ -232,7 +236,7 @@ class CitationBacklinks(Backlinks):
|
||||
Displays the back references for a Citation,.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.connect(self.dbstate.db, 'citation-update', self.update)
|
||||
super().db_changed()
|
||||
self.connect_signal('Citation', self.update)
|
||||
|
||||
def update_has_data(self):
|
||||
@ -252,7 +256,7 @@ class RepositoryBacklinks(Backlinks):
|
||||
Displays the back references for a repository.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.connect(self.dbstate.db, 'repository-update', self.update)
|
||||
super().db_changed()
|
||||
self.connect_signal('Repository', self.update)
|
||||
|
||||
def update_has_data(self):
|
||||
@ -272,7 +276,7 @@ class MediaBacklinks(Backlinks):
|
||||
Displays the back references for a media object.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.connect(self.dbstate.db, 'media-update', self.update)
|
||||
super().db_changed()
|
||||
self.connect_signal('Media', self.update)
|
||||
|
||||
def update_has_data(self):
|
||||
@ -292,7 +296,7 @@ class NoteBacklinks(Backlinks):
|
||||
Displays the back references for a note.
|
||||
"""
|
||||
def db_changed(self):
|
||||
self.connect(self.dbstate.db, 'note-update', self.update)
|
||||
super().db_changed()
|
||||
self.connect_signal('Note', self.update)
|
||||
|
||||
def update_has_data(self):
|
||||
|
@ -300,6 +300,8 @@ class DateRange:
|
||||
"""
|
||||
start = None
|
||||
stop = None
|
||||
if date.is_empty():
|
||||
return (None, None)
|
||||
if date.modifier == Date.MOD_NONE:
|
||||
start = date.sortval
|
||||
stop = date.sortval
|
||||
|
@ -206,8 +206,10 @@ class PlaceBaseView(ListView):
|
||||
"""
|
||||
if action:
|
||||
action.set_state(value)
|
||||
self.mapservice = mapkey = value.get_string()
|
||||
config.set('interface.mapservice', mapkey)
|
||||
self.mapservice = value.get_string()
|
||||
else:
|
||||
self.mapservice = value
|
||||
config.set('interface.mapservice', self.mapservice)
|
||||
config.save()
|
||||
_ui = self.__create_maps_menu_actions()
|
||||
self.uimanager.add_ui_from_string(_ui)
|
||||
|
@ -292,9 +292,6 @@ class GeoGraphyView(OsmGps, NavigationView):
|
||||
if self.active:
|
||||
self.bookmarks.redraw()
|
||||
self.build_tree()
|
||||
if self.osm:
|
||||
self.osm.grab_focus()
|
||||
self.set_crosshair(config.get("geography.show_cross"))
|
||||
|
||||
def can_configure(self):
|
||||
"""
|
||||
|
@ -191,14 +191,11 @@ class OsmGps:
|
||||
self.osm = DummyMapNoGpsPoint()
|
||||
else:
|
||||
if http_proxy:
|
||||
self.osm = osmgpsmap.Map(tile_cache=tiles_path,
|
||||
proxy_uri=http_proxy,
|
||||
map_source=constants.MAP_TYPE[
|
||||
map_type])
|
||||
self.osm = osmgpsmap.Map(proxy_uri=http_proxy)
|
||||
else:
|
||||
self.osm = osmgpsmap.Map(tile_cache=tiles_path,
|
||||
map_source=constants.MAP_TYPE[
|
||||
map_type])
|
||||
self.osm = osmgpsmap.Map()
|
||||
self.osm.set_property("tile_cache", tiles_path)
|
||||
self.osm.set_property("map_source", constants.MAP_TYPE[map_type])
|
||||
self.osm.props.tile_cache = osmgpsmap.MAP_CACHE_AUTO
|
||||
current_map = osmgpsmap.MapOsd(show_dpad=False, show_zoom=True)
|
||||
self.end_selection = None
|
||||
|
@ -5,6 +5,7 @@
|
||||
# Copyright (C) 2003-2005 Donald N. Allingham
|
||||
# Copyright (C) 2008 Brian G. Matherly
|
||||
# Copyright (C) 2018 Robin van der Vliet
|
||||
# Copyright (C) 2020 Jan Sparreboom
|
||||
#
|
||||
# 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
|
||||
@ -35,7 +36,7 @@ import gramps.gen.relationship
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# Levels
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -69,9 +70,207 @@ _child_level = [ "", "",
|
||||
_nibling_level = [ "", "",
|
||||
"achter", "achterachter", "achterachterachter" ]
|
||||
|
||||
_parents_level = ["",
|
||||
"ouders",
|
||||
"grootouders",
|
||||
"overgrootouders",
|
||||
"betovergrootouders",
|
||||
"overgrootouders 5e graad",
|
||||
"overgrootouders 6e graad",
|
||||
"overgrootouders 7e graad",
|
||||
"overgrootouders 8e graad",
|
||||
"overgrootouders 9e graad",
|
||||
"overgrootouders 10e graad",
|
||||
"overgrootouders 11e graad",
|
||||
"overgrootouders 12e graad",
|
||||
"overgrootouders 13e graad",
|
||||
"overgrootouders 14e graad",
|
||||
"overgrootouders 15e graad",
|
||||
"overgrootouders 16e graad",
|
||||
"overgrootouders 17e graad",
|
||||
"overgrootouders 18e graad",
|
||||
"overgrootouders 19e graad",
|
||||
"overgrootouders 20e graad",
|
||||
"overgrootouders 21e graad",
|
||||
"overgrootouders 22e graad",
|
||||
"overgrootouders 23e graad",
|
||||
"overgrootouders 24e graad",
|
||||
"overgrootouders 25e graad",
|
||||
"overgrootouders 26e graad",
|
||||
"overgrootouders 27e graad",
|
||||
"overgrootouders 28e graad",
|
||||
"overgrootouders 29e graad",
|
||||
"overgrootouders 30e graad",
|
||||
"overgrootouders 31e graad",
|
||||
"overgrootouders 32e graad",
|
||||
"overgrootouders 33e graad",
|
||||
"overgrootouders 34e graad",
|
||||
"overgrootouders 35e graad",
|
||||
"overgrootouders 36e graad",
|
||||
"overgrootouders 37e graad",
|
||||
"overgrootouders 38e graad",
|
||||
"overgrootouders 39e graad",
|
||||
"overgrootouders 40e graad",
|
||||
"overgrootouders 41e graad",
|
||||
"overgrootouders 42e graad",
|
||||
"overgrootouders 43e graad",
|
||||
"overgrootouders 44e graad",
|
||||
"overgrootouders 45e graad",
|
||||
"overgrootouders 46e graad",
|
||||
"overgrootouders 47e graad",
|
||||
"overgrootouders 48e graad",
|
||||
"overgrootouders 49e graad",
|
||||
"overgrootouders 50e graad", ]
|
||||
|
||||
_siblings_level = ["",
|
||||
"broers en zussen",
|
||||
"ooms en tantes",
|
||||
"oudooms en -tantes",
|
||||
"overoudooms en -tantes",
|
||||
"overoudooms en -tantes 5e graad",
|
||||
"overoudooms en -tantes 6e graad",
|
||||
"overoudooms en -tantes 7e graad",
|
||||
"overoudooms en -tantes 8e graad",
|
||||
"overoudooms en -tantes 9e graad",
|
||||
"overoudooms en -tantes 10e graad",
|
||||
"overoudooms en -tantes 11e graad",
|
||||
"overoudooms en -tantes 12e graad",
|
||||
"overoudooms en -tantes 13e graad",
|
||||
"overoudooms en -tantes 14e graad",
|
||||
"overoudooms en -tantes 15e graad",
|
||||
"overoudooms en -tantes 16e graad",
|
||||
"overoudooms en -tantes 17e graad",
|
||||
"overoudooms en -tantes 18e graad",
|
||||
"overoudooms en -tantes 19e graad",
|
||||
"overoudooms en -tantes 20e graad",
|
||||
"overoudooms en -tantes 21e graad",
|
||||
"overoudooms en -tantes 22e graad",
|
||||
"overoudooms en -tantes 23e graad",
|
||||
"overoudooms en -tantes 24e graad",
|
||||
"overoudooms en -tantes 25e graad",
|
||||
"overoudooms en -tantes 26e graad",
|
||||
"overoudooms en -tantes 27e graad",
|
||||
"overoudooms en -tantes 28e graad",
|
||||
"overoudooms en -tantes 29e graad",
|
||||
"overoudooms en -tantes 30e graad",
|
||||
"overoudooms en -tantes 41e graad",
|
||||
"overoudooms en -tantes 42e graad",
|
||||
"overoudooms en -tantes 43e graad",
|
||||
"overoudooms en -tantes 44e graad",
|
||||
"overoudooms en -tantes 45e graad",
|
||||
"overoudooms en -tantes 46e graad",
|
||||
"overoudooms en -tantes 47e graad",
|
||||
"overoudooms en -tantes 48e graad",
|
||||
"overoudooms en -tantes 49e graad",
|
||||
"overoudooms en -tantes 50e graad", ]
|
||||
|
||||
_children_level = ["",
|
||||
"kinderen",
|
||||
"kleinkinderen",
|
||||
"achterkleinkinderen",
|
||||
"betachterkleinkinderen",
|
||||
"kleinkinderen 5e graad",
|
||||
"kleinkinderen 6e graad",
|
||||
"kleinkinderen 7e graad",
|
||||
"kleinkinderen 8e graad",
|
||||
"kleinkinderen 9e graad",
|
||||
"kleinkinderen 10e graad",
|
||||
"kleinkinderen 11e graad",
|
||||
"kleinkinderen 12e graad",
|
||||
"kleinkinderen 13e graad",
|
||||
"kleinkinderen 14e graad",
|
||||
"kleinkinderen 15e graad",
|
||||
"kleinkinderen 16e graad",
|
||||
"kleinkinderen 17e graad",
|
||||
"kleinkinderen 18e graad",
|
||||
"kleinkinderen 19e graad",
|
||||
"kleinkinderen 20e graad",
|
||||
"kleinkinderen 21e graad",
|
||||
"kleinkinderen 22e graad",
|
||||
"kleinkinderen 23e graad",
|
||||
"kleinkinderen 24e graad",
|
||||
"kleinkinderen 25e graad",
|
||||
"kleinkinderen 26e graad",
|
||||
"kleinkinderen 27e graad",
|
||||
"kleinkinderen 28e graad",
|
||||
"kleinkinderen 29e graad",
|
||||
"kleinkinderen 30e graad",
|
||||
"kleinkinderen 31e graad",
|
||||
"kleinkinderen 32e graad",
|
||||
"kleinkinderen 33e graad",
|
||||
"kleinkinderen 34e graad",
|
||||
"kleinkinderen 35e graad",
|
||||
"kleinkinderen 36e graad",
|
||||
"kleinkinderen 37e graad",
|
||||
"kleinkinderen 38e graad",
|
||||
"kleinkinderen 39e graad",
|
||||
"kleinkinderen 40e graad",
|
||||
"kleinkinderen 41e graad",
|
||||
"kleinkinderen 42e graad",
|
||||
"kleinkinderen 43e graad",
|
||||
"kleinkinderen 44e graad",
|
||||
"kleinkinderen 45e graad",
|
||||
"kleinkinderen 46e graad",
|
||||
"kleinkinderen 47e graad",
|
||||
"kleinkinderen 48e graad",
|
||||
"kleinkinderen 49e graad",
|
||||
"kleinkinderen 50e graad", ]
|
||||
|
||||
_nephews_nieces_level = ["",
|
||||
"broers en zussen",
|
||||
"neven en nichten",
|
||||
"achterneven en -nichten",
|
||||
"achterneven en -nichten 4e graad",
|
||||
"achterneven en -nichten 5e graad",
|
||||
"achterneven en -nichten 6e graad",
|
||||
"achterneven en -nichten 7e graad",
|
||||
"achterneven en -nichten 8e graad",
|
||||
"achterneven en -nichten 9e graad",
|
||||
"achterneven en -nichten 10e graad",
|
||||
"achterneven en -nichten 11e graad",
|
||||
"achterneven en -nichten 12e graad",
|
||||
"achterneven en -nichten 13e graad",
|
||||
"achterneven en -nichten 14e graad",
|
||||
"achterneven en -nichten 15e graad",
|
||||
"achterneven en -nichten 16e graad",
|
||||
"achterneven en -nichten 17e graad",
|
||||
"achterneven en -nichten 18e graad",
|
||||
"achterneven en -nichten 19e graad",
|
||||
"achterneven en -nichten 20e graad",
|
||||
"achterneven en -nichten 21e graad",
|
||||
"achterneven en -nichten 22e graad",
|
||||
"achterneven en -nichten 23e graad",
|
||||
"achterneven en -nichten 24e graad",
|
||||
"achterneven en -nichten 25e graad",
|
||||
"achterneven en -nichten 26e graad",
|
||||
"achterneven en -nichten 27e graad",
|
||||
"achterneven en -nichten 28e graad",
|
||||
"achterneven en -nichten 29e graad",
|
||||
"achterneven en -nichten 30e graad",
|
||||
"achterneven en -nichten 31e graad",
|
||||
"achterneven en -nichten 32e graad",
|
||||
"achterneven en -nichten 33e graad",
|
||||
"achterneven en -nichten 34e graad",
|
||||
"achterneven en -nichten 35e graad",
|
||||
"achterneven en -nichten 36e graad",
|
||||
"achterneven en -nichten 37e graad",
|
||||
"achterneven en -nichten 38e graad",
|
||||
"achterneven en -nichten 39e graad",
|
||||
"achterneven en -nichten 40e graad",
|
||||
"achterneven en -nichten 41e graad",
|
||||
"achterneven en -nichten 42e graad",
|
||||
"achterneven en -nichten 43e graad",
|
||||
"achterneven en -nichten 44e graad",
|
||||
"achterneven en -nichten 45e graad",
|
||||
"achterneven en -nichten 46e graad",
|
||||
"achterneven en -nichten 47e graad",
|
||||
"achterneven en -nichten 48e graad",
|
||||
"achterneven en -nichten 49e graad",
|
||||
"achterneven en -nichten 50e graad", ]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# Relationship calculator Dutch version
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -273,6 +472,104 @@ class RelationshipCalculator(gramps.gen.relationship.RelationshipCalculator):
|
||||
else:
|
||||
return "%s%snicht (kozijn)" % (inlaw, step) \
|
||||
+ " " + _ordinal_level[removed] + " graad"
|
||||
# NIEUW
|
||||
def get_plural_relationship_string(self, Ga, Gb,
|
||||
reltocommon_a='', reltocommon_b='',
|
||||
only_birth=True,
|
||||
in_law_a=False, in_law_b=False):
|
||||
"""
|
||||
Provide a string that describes the relationsip between a person, and
|
||||
a group of people with the same relationship. E.g. "grandparents" or
|
||||
"children".
|
||||
|
||||
Ga and Gb can be used to mathematically calculate the relationship.
|
||||
|
||||
.. seealso::
|
||||
http://en.wikipedia.org/wiki/Cousin#Mathematical_definitions
|
||||
|
||||
:param Ga: The number of generations between the main person and the
|
||||
common ancestor.
|
||||
:type Ga: int
|
||||
:param Gb: The number of generations between the group of people and the
|
||||
common ancestor
|
||||
:type Gb: int
|
||||
:param reltocommon_a: relation path to common ancestor or common
|
||||
Family for person a.
|
||||
Note that length = Ga
|
||||
:type reltocommon_a: str
|
||||
:param reltocommon_b: relation path to common ancestor or common
|
||||
Family for person b.
|
||||
Note that length = Gb
|
||||
:type reltocommon_b: str
|
||||
:param only_birth: True if relation between a and b is by birth only
|
||||
False otherwise
|
||||
:type only_birth: bool
|
||||
:param in_law_a: True if path to common ancestors is via the partner
|
||||
of person a
|
||||
:type in_law_a: bool
|
||||
:param in_law_b: True if path to common ancestors is via the partner
|
||||
of person b
|
||||
:type in_law_b: bool
|
||||
:returns: A string describing the relationship between the person and
|
||||
the group.
|
||||
:rtype: str
|
||||
"""
|
||||
rel_str = "verre familie"
|
||||
if Ga == 0:
|
||||
# These are descendants
|
||||
if Gb < len(_children_level):
|
||||
rel_str = _children_level[Gb]
|
||||
else:
|
||||
rel_str = "verre afstammelingen"
|
||||
elif Gb == 0:
|
||||
# These are parents/grand parents
|
||||
if Ga < len(_parents_level):
|
||||
rel_str = _parents_level[Ga]
|
||||
else:
|
||||
rel_str = "verre voorouders"
|
||||
elif Gb == 1:
|
||||
# These are siblings/aunts/uncles
|
||||
if Ga < len(_siblings_level):
|
||||
rel_str = _siblings_level[Ga]
|
||||
else:
|
||||
rel_str = "verre ooms/tantes"
|
||||
elif Ga == 1:
|
||||
# These are nieces/nephews
|
||||
if Gb < len(_nephews_nieces_level):
|
||||
rel_str = _nephews_nieces_level[Gb]
|
||||
else:
|
||||
rel_str = "verre neven/nichten"
|
||||
elif Ga > 1 and Ga == Gb:
|
||||
# These are cousins in the same generation
|
||||
if Ga <= len(_ordinal_level):
|
||||
rel_str = "%s neven" % _ordinal_level[Ga-1]
|
||||
else:
|
||||
rel_str = "verre neven"
|
||||
elif Ga > 1 and Ga > Gb:
|
||||
# These are cousins in different generations with the second person
|
||||
# being in a higher generation from the common ancestor than the
|
||||
# first person.
|
||||
if Gb <= len(_LEVEL_NAME) and (Ga-Gb) < len(_removed_level):
|
||||
rel_str = "%s neven%s (omhoog)" % (_ordinal_level[Gb-1],
|
||||
_removed_level[Ga-Gb])
|
||||
else:
|
||||
rel_str = "verre neven"
|
||||
elif Gb > 1 and Gb > Ga:
|
||||
# These are cousins in different generations with the second person
|
||||
# being in a lower generation from the common ancestor than the
|
||||
# first person.
|
||||
if Ga <= len(_LEVEL_NAME) and (Gb-Ga) < len(_removed_level):
|
||||
rel_str = "%s neven%s (omlaag)" % (_ordinal_level[Ga-1],
|
||||
_removed_level[Gb-Ga])
|
||||
else:
|
||||
rel_str = "verre neven"
|
||||
|
||||
if in_law_b is True:
|
||||
rel_str = "echtgenoten van %s" % rel_str
|
||||
|
||||
return rel_str
|
||||
|
||||
|
||||
|
||||
def get_single_relationship_string(self, Ga, Gb, gender_a, gender_b,
|
||||
reltocommon_a, reltocommon_b,
|
||||
@ -424,3 +721,6 @@ if __name__ == "__main__":
|
||||
from gramps.gen.relationship import test
|
||||
RC = RelationshipCalculator()
|
||||
test(RC, True)
|
||||
|
||||
|
||||
|
||||
|
@ -132,7 +132,7 @@ class DbTestClassBase(object):
|
||||
self._log_sig("note-delete", args)
|
||||
|
||||
def _log_sig(self, sig, args):
|
||||
print("('%s', %s)," % (sig, args))
|
||||
# print("('%s', %s)," % (sig, args))
|
||||
self.sigs.append((sig, args[0]))
|
||||
|
||||
def _cm_pers_add(self, *args):
|
||||
|
@ -271,6 +271,7 @@ class BirthdayReport(Report):
|
||||
for person_handle in people:
|
||||
step()
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
short_name = self.get_name(person)
|
||||
birth_ref = person.get_birth_ref()
|
||||
birth_date = None
|
||||
if birth_ref:
|
||||
|
@ -441,7 +441,8 @@ class TagReport(Report):
|
||||
|
||||
for place_handle in place_list:
|
||||
place = self.database.get_place_from_handle(place_handle)
|
||||
place_title = _pd.display(self.database, place, self.place_format)
|
||||
place_title = _pd.display(self.database, place, None,
|
||||
self.place_format)
|
||||
|
||||
self.doc.start_row()
|
||||
|
||||
|
@ -247,6 +247,14 @@ class GeoClose(GeoGraphyView):
|
||||
self.add_item = None
|
||||
self.newmenu = None
|
||||
self.config_meeting_slider = None
|
||||
self.dbstate.connect('database-changed', self.reset_change_db)
|
||||
|
||||
def reset_change_db(self, dummy_dbase):
|
||||
"""
|
||||
Used to reset the family reference
|
||||
"""
|
||||
self.refperson = None
|
||||
|
||||
|
||||
def get_title(self):
|
||||
"""
|
||||
|
@ -244,6 +244,13 @@ class GeoFamClose(GeoGraphyView):
|
||||
self.cal = config.get('preferences.calendar-format-report')
|
||||
self.no_show_places_in_status_bar = False
|
||||
self.config_meeting_slider = None
|
||||
self.dbstate.connect('database-changed', self.reset_change_db)
|
||||
|
||||
def reset_change_db(self, dummy_dbase):
|
||||
"""
|
||||
Used to reset the family reference
|
||||
"""
|
||||
self.reffamily = None
|
||||
|
||||
def get_title(self):
|
||||
"""
|
||||
|
@ -370,8 +370,9 @@ class GeoFamily(GeoGraphyView):
|
||||
_("Family places for %s") % self.family_label(family))
|
||||
person = None
|
||||
if family:
|
||||
person = dbstate.db.get_person_from_handle(
|
||||
family.get_father_handle())
|
||||
handle = family.get_father_handle()
|
||||
if handle:
|
||||
person = dbstate.db.get_person_from_handle(handle)
|
||||
else:
|
||||
return
|
||||
family_id = family.gramps_id
|
||||
|
BIN
images/hicolor/128x128/apps/gramps.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
images/hicolor/256x256/apps/gramps.png
Normal file
After Width: | Height: | Size: 57 KiB |
@ -7,7 +7,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Gramps</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Gramps-5.1.3-1, (C) 1997-2020 The Gramps Team http://www.gramps-project.org</string>
|
||||
<string>Gramps-5.1.5-1, (C) 1997-2022 The Gramps Team http://www.gramps-project.org</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>gramps.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@ -17,15 +17,15 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>Gramps-5.1.3-1</string>
|
||||
<string>Gramps-5.1.5-1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>Gramps-5.1.3-1</string>
|
||||
<string>Gramps-5.1.5-1</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright 1997 - 2020 The Gramps Team, GNU General Public License.</string>
|
||||
<string>Copyright 1997 - 2022 The Gramps Team, GNU General Public License.</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.9</string>
|
||||
<string>10.12</string>
|
||||
<key>GtkOSXLaunchScriptFile</key>
|
||||
<string>gramps_launcher.py</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
|
@ -12,8 +12,9 @@
|
||||
</meta>
|
||||
|
||||
<plist>${project}/Info.plist</plist>
|
||||
<entitlements>${project}/release.entitlements.plist</entitlements>
|
||||
<!-- Build gramps-launcher with:
|
||||
gcc -L$PREFIX/lib `python-config -\-cflags -\-ldflags` \
|
||||
gcc -L$PREFIX/lib `python-config -\-cflags -\-ldflags -\-embed` \
|
||||
-o $PREFIX/bin/gramps-launcher \
|
||||
path/to/gtk-mac-bundler/examples/python-launcher.c
|
||||
with the obvious substitution.
|
||||
@ -41,19 +42,15 @@
|
||||
</binary>
|
||||
|
||||
<binary recurse="True">
|
||||
${prefix}/lib/python3.6/*.so
|
||||
${prefix}/lib/python3.9/*.so
|
||||
</binary>
|
||||
|
||||
<binary>
|
||||
${prefix}/lib/librsvg-2.2.dylib
|
||||
</binary>
|
||||
|
||||
<!--binary>
|
||||
${prefix}/lib/libwebkit-1.0.2.dylib
|
||||
</binary-->
|
||||
|
||||
<binary>
|
||||
${prefix}/lib/libgtkmacintegration-gtk3.2.dylib
|
||||
${prefix}/lib/libgtkmacintegration-gtk3.4.dylib
|
||||
</binary>
|
||||
|
||||
<binary>
|
||||
@ -65,7 +62,7 @@
|
||||
</binary>
|
||||
|
||||
<binary>
|
||||
${prefix}/lib/enchant
|
||||
${prefix}/lib/enchant-2
|
||||
</binary>
|
||||
|
||||
<binary>
|
||||
@ -77,7 +74,7 @@
|
||||
</binary>
|
||||
|
||||
<binary>
|
||||
${prefix}/lib/libhunspell-1.6.0.dylib
|
||||
${prefix}/lib/libhunspell-1.7.0.dylib
|
||||
</binary>
|
||||
|
||||
<binary>
|
||||
@ -96,6 +93,14 @@
|
||||
${prefix}/lib/libgexiv2.dylib
|
||||
</binary>
|
||||
|
||||
<binary>
|
||||
${prefix}/lib/libgeocode-glib.dylib
|
||||
</binary>
|
||||
|
||||
<binary>
|
||||
${prefix}/lib/gio/modules/libgiognutls.so
|
||||
</binary>
|
||||
|
||||
<gir>
|
||||
${prefix}/share/gir-1.0/*.gir
|
||||
</gir>
|
||||
@ -137,6 +142,10 @@
|
||||
${project}/gramps_launcher.py
|
||||
</data>
|
||||
|
||||
<data>
|
||||
${prefix}/etc/fonts
|
||||
</data>
|
||||
|
||||
<data>
|
||||
${prefix}/share/glib-2.0/schemas
|
||||
</data>
|
||||
@ -144,19 +153,19 @@
|
||||
<!-- We have to pull in the python modules, which are mixed python
|
||||
and loadable modules. -->
|
||||
<data recurse="True">
|
||||
${prefix}/lib/python3.6/*.py
|
||||
${prefix}/lib/python3.9/*.py
|
||||
</data>
|
||||
|
||||
<data>
|
||||
${prefix}/lib/python3.6/config-3.6m-darwin/
|
||||
${prefix}/lib/python3.9/config-3.9-darwin/
|
||||
</data>
|
||||
|
||||
<data>
|
||||
${prefix}/lib/python3.6/site-packages/gramps/gen/utils/resource-path
|
||||
${prefix}/lib/python3.9/site-packages/gramps/gen/utils/resource-path
|
||||
</data>
|
||||
|
||||
<data>
|
||||
${prefix}/include/python3.6m/pyconfig.h
|
||||
${prefix}/include/python3.9/pyconfig.h
|
||||
</data>
|
||||
|
||||
|
||||
@ -173,7 +182,7 @@
|
||||
</data>
|
||||
|
||||
<data recurse="True">
|
||||
${prefix}/lib/python3.6/site-packages/gramps/*.glade
|
||||
${prefix}/lib/python3.9/site-packages/gramps/*.glade
|
||||
</data>
|
||||
|
||||
<data>
|
||||
@ -205,6 +214,7 @@
|
||||
<data>
|
||||
${prefix}/share/icons
|
||||
</data>
|
||||
|
||||
<!-- Copy icons. Note that the .icns file is an Apple format which
|
||||
contains up to 4 sizes of icon. You can use
|
||||
/Developer/Applications/Utilities/Icon Composer.app to import
|
||||
|
@ -9,22 +9,12 @@
|
||||
href="http://pywebkitgtk.googlecode.com/files/"/>
|
||||
<repository type="tarball" name="ftp.gnome.org"
|
||||
href="http://ftp.gnome.org/pub/GNOME/sources/"/>
|
||||
<repository type="tarball" name="pyxdg"
|
||||
href="http://www.gnome.org/~fpeters/pyxdg/"/>
|
||||
<repository type="tarball" name="xdg-utils"
|
||||
href="http://portland.freedesktop.org/download/"/>
|
||||
<repository type="svn" name="gramps-addons"
|
||||
href="https://svn.code.sf.net/p/gramps-addons/code/"/>
|
||||
<repository type="tarball" name="oracle"
|
||||
href="http://download.oracle.com/"/>
|
||||
<repository type="tarball" name="pymodules"
|
||||
href="https://pypi.python.org/packages/"/>
|
||||
<repository type="tarball" name="stowers"
|
||||
href="http://www.johnstowers.co.nz/files/"/>
|
||||
<repository type="git" name="github" href="git://github.com/"/>
|
||||
<repository type="tarball" name="github-tarball" href="https://github.com/"/>
|
||||
<repository type="tarball" name="graphviz"
|
||||
href="https://graphviz.gitlab.io/pub/graphviz/stable/SOURCES/"/>
|
||||
<repository type="tarball" name="exiv2.org"
|
||||
href="http://www.exiv2.org/releases/"/>
|
||||
<repository type="tarball" name="pythonware"
|
||||
@ -52,8 +42,8 @@ gtk-mac-bundler gtk-osx-build/projects/gramps/gramps.bundle
|
||||
|
||||
-->
|
||||
|
||||
<include href="https://gitlab.gnome.org/GNOME/gtk-osx/raw/master/modulesets-stable/gtk-osx.modules"/>
|
||||
<!--include href="/Users/john/Development/GTK-OSX/gtk-osx-build/modulesets-stable/gtk-osx.modules"/-->
|
||||
<!--include href="https://gitlab.gnome.org/GNOME/gtk-osx/raw/master/modulesets-stable/gtk-osx.modules"/-->
|
||||
<include href="/Users/john/Development/GTK-OSX/gtk-osx-build/modulesets-stable/gtk-osx.modules"/>
|
||||
|
||||
<distutils id="gramps-git" supports-non-srcdir-builds="no">
|
||||
<branch module="gramps-project/gramps.git" repo="github"
|
||||
@ -65,9 +55,9 @@ gtk-mac-bundler gtk-osx-build/projects/gramps/gramps.bundle
|
||||
</distutils>
|
||||
|
||||
<distutils id="gramps" supports-non-srcdir-builds="no">
|
||||
<branch module="gramps-project/gramps/archive/v5.1.3.tar.gz"
|
||||
repo="github-tarball" version="5.1.3"
|
||||
checkoutdir="gramps-gramps-5.1.3"/>
|
||||
<branch module="gramps-project/gramps/archive/v5.1.5.tar.gz"
|
||||
repo="github-tarball" version="5.1.5"
|
||||
checkoutdir="gramps-gramps-5.1.5"/>
|
||||
<dependencies>
|
||||
<dep package="meta-gramps-modules"/>
|
||||
</dependencies>
|
||||
@ -81,35 +71,10 @@ gtk-mac-bundler gtk-osx-build/projects/gramps/gramps.bundle
|
||||
</dependencies>
|
||||
</distutils>
|
||||
|
||||
<autotools id="pyWebKitGtk" >
|
||||
<branch module="pywebkitgtk-1.1.7.tar.bz2" version="1.1.7"
|
||||
repo="pywebkitgtk"/>
|
||||
<dependencies>
|
||||
<dep package="WebKit"/>
|
||||
<dep package="sqlite"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
|
||||
<distutils id="pyenchant">
|
||||
<branch repo="pymodules" module="73/73/49f95fe636ab3deed0ef1e3b9087902413bcdf74ec00298c3059e660cfbb/pyenchant-1.6.8.tar.gz"
|
||||
version="1.6.1"/>
|
||||
</distutils>
|
||||
|
||||
<distutils id="pyxdg">
|
||||
<branch repo="pyxdg" module="pyxdg-0.17.tar.gz" version="0.17"
|
||||
hash="sha256:fbc87711922b2dd6ceb23ee041f1f96da9b7dbb6971df03a3081b439def069ce"
|
||||
md5sum="a086de99cc536095684d87f15594e4db" size="37372"/>
|
||||
</distutils>
|
||||
|
||||
<autotools id="xdg-utils">
|
||||
<branch module="xdg-utils-1.0.2.tgz" version="1.0.2" repo="xdg-utils"/>
|
||||
</autotools>
|
||||
|
||||
<meson id="json-glib">
|
||||
<branch module="json-glib/1.4/json-glib-1.4.4.tar.xz"
|
||||
version="1.4.4" repo="ftp.gnome.org"
|
||||
hash="sha256:720c5f4379513dc11fd97dc75336eb0c0d3338c53128044d9fabec4374f4bc47"/>
|
||||
<meson id="json-glib" mesonargs="-Dgtk_doc=disabled -Dman=false -Dtests=false">
|
||||
<branch module="json-glib/1.6/json-glib-1.6.6.tar.xz"
|
||||
version="1.6.6" repo="ftp.gnome.org"
|
||||
hash="sha256:96ec98be7a91f6dde33636720e3da2ff6ecbb90e76ccaa49497f31a6855a490e"/>
|
||||
<dependencies>
|
||||
<dep package="gobject-introspection"/>
|
||||
</dependencies>
|
||||
@ -128,46 +93,34 @@ gtk-mac-bundler gtk-osx-build/projects/gramps/gramps.bundle
|
||||
<autotools id="osmgpsmap" skip-autogen="never"
|
||||
autogenargs="--disable-gtk-doc-html"
|
||||
supports-non-srcdir-builds="no">
|
||||
<branch module="nzjrs/osm-gps-map" revision="1.1.0" repo="github"/>
|
||||
<branch module="nzjrs/osm-gps-map" revision="1.2.0" repo="github"/>
|
||||
<dependencies>
|
||||
<dep package="libsoup"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="meta-gtk-osx-gtk3"/>
|
||||
<dep package="meta-gtk-osx-gtk3.14"/>
|
||||
</after>
|
||||
</autotools>
|
||||
|
||||
<autotools id="graphviz" autogen-sh="configure"
|
||||
autogenargs="--disable-sharp --disable-guile --disable-java --disable-lua --disable-ocaml --disable-perl --disable-php --disable-r --disable-ruby --disable-tcl --with-pangocairo">
|
||||
<branch module="graphviz.tar.gz" version="2.40.1"
|
||||
repo="graphviz" checkoutdir="graphviz-2.40.1"/>
|
||||
<dependencies>
|
||||
<dep package="pango"/>
|
||||
<dep package="meta-gtk-osx-freetype"/>
|
||||
<dep package="librsvg"/>
|
||||
<dep package="gtk+-3.0"/>
|
||||
</dependencies>
|
||||
</autotools>
|
||||
|
||||
<cmake id="exiv2" cmakeargs="-DEXIV2_ENABLE_PNG=ON">
|
||||
<branch module="exiv2-0.27.0a-Source.tar.gz" repo="exiv2.org"
|
||||
checkoutdir="exiv2-0.27.0-Source" version="0.27.0"/>
|
||||
<branch module="exiv2-0.27.4-Source.tar.gz" repo="exiv2.org"
|
||||
checkoutdir="exiv2-0.27.4-Source" version="0.27.4"
|
||||
hash="sha256:84366dba7c162af9a7603bcd6c16f40fe0e9af294ba2fd2f66ffffb9fbec904e"/>
|
||||
</cmake>
|
||||
|
||||
<meson id="gexiv2" mesonargs="-Dvapi=false">
|
||||
<branch module="gexiv2/0.12/gexiv2-0.12.0.tar.xz"
|
||||
repo="ftp.gnome.org" version="0.12.0"
|
||||
hash="sha256:58f539b0386f36300b76f3afea3a508de4914b27e78f58ee4d142486a42f926a">
|
||||
<branch module="gexiv2/0.14/gexiv2-0.14.0.tar.xz"
|
||||
repo="ftp.gnome.org" version="0.14.0"
|
||||
hash="sha256:e58279a6ff20b6f64fa499615da5e9b57cf65ba7850b72fafdf17221a9d6d69e">
|
||||
</branch>
|
||||
<dependencies>
|
||||
<dep package="exiv2"/>
|
||||
<dep package="pygobject3"/>
|
||||
</dependencies>
|
||||
</meson>
|
||||
|
||||
<distutils id="pil">
|
||||
<branch module="93/73/66854f63b1941aad9af18a1de59f9cf95ad1a87c801540222e332f6688d7/Pillow-4.1.1.tar.gz" version="4.1.1"
|
||||
https://files.pythonhosted.org/packages/
|
||||
<distutils id="pillow">
|
||||
<branch module="21/23/af6bac2a601be6670064a817273d4190b79df6f74d8012926a39bc7aa77f/Pillow-8.2.0.tar.gz" version="8.2.0"
|
||||
repo="pymodules"
|
||||
hash="md5:f2565954955c8d10f3b4f1f72f852bf7">
|
||||
hash="sha256:a787ab10d7bb5494e5f76536ac460741788f1fbce851068d73a87ca7c35fc3e1">
|
||||
</branch>
|
||||
<dependencies>
|
||||
<!--dep package="setuptools"/-->
|
||||
@ -175,18 +128,74 @@ gtk-mac-bundler gtk-osx-build/projects/gramps/gramps.bundle
|
||||
</distutils>
|
||||
|
||||
<distutils id='pyicu'>
|
||||
<branch version='2.5' repo='pymodules'
|
||||
module='5a/99/c48c816095208bf3f4936ff67e571621fbddef461303a35a076f234e31f6/PyICU-2.5.tar.gz'/>
|
||||
<branch version='2.7.2' repo='pymodules'
|
||||
module='17/0f/9d6b7eb01650960239a5d4dc21cd6e7a96921807c043d287bae4b2f440e1/PyICU-2.7.2.tar.gz'
|
||||
hash="sha256:1382869b22d91cc99274f9b525fa7d9199b44d9007ff0036a09747839a01e9dc"/>
|
||||
|
||||
<dependencies>
|
||||
<dep package='icu'/>
|
||||
</dependencies>
|
||||
</distutils>
|
||||
|
||||
<!--Note the leading ; in autogen-template. It's there on purpose in case the user has set nice_build so that the nice prepended to the command doesn't eat the cd. -->
|
||||
<autotools id="berkeleydb" autogen-sh="configure"
|
||||
supports-non-srcdir-builds="no" makeargs="-C build_unix"
|
||||
autogen-template="cd .;cd build_unix; ../dist/%(autogen-sh)s --prefix %(prefix)s %(autogenargs)s"
|
||||
makeinstallargs="-C build_unix install">
|
||||
|
||||
<branch module="berkeley-db/db-4.8.30.NC.tar.gz" version="4.8.30"
|
||||
repo="oracle"
|
||||
hash="sha256:12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef" >
|
||||
<patch file="berkeleydb-4.8-atomic.patch" strip='1'/>
|
||||
</branch>
|
||||
</autotools>
|
||||
|
||||
<!-- For out-of-source-tree builds (i.e., builddir is defined either
|
||||
in .jhbuildrc-custom or passed as an option on the
|
||||
command-line, the normal berkeleydb module will build in its
|
||||
srcdir/build_unix directory. If you want to build it in the
|
||||
build directory with most of the other modules, use this module
|
||||
instead. -->
|
||||
<autotools id="berkeleydb-nonsrctree" autogen-sh="configure"
|
||||
autogen-template="%(srcdir)s/dist/%(autogen-sh)s --prefix %(prefix)s %(autogenargs)s" >
|
||||
|
||||
<branch module="berkeley-db/db-4.8.30.NC.tar.gz" version="4.8.30"
|
||||
repo="oracle"
|
||||
hash="sha256:12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef">
|
||||
<patch file="berkeleydb-4.8-atomic.patch" strip='1'/>
|
||||
</branch>
|
||||
</autotools>
|
||||
|
||||
|
||||
<distutils id="pybsddb">
|
||||
<branch repo="pymodules" version="6.2.9"
|
||||
module="f0/24/92034482656945fc6ceb10551222b43a0ff8d0c87e15839120487820067e/bsddb3-6.2.9.tar.gz"
|
||||
hash="sha256:70d05ec8dc568f42e70fc919a442e0daadc2a905a1cfb7ca77f549d49d6e7801" />
|
||||
<dependencies>
|
||||
<dep package="python3"/>
|
||||
</dependencies>
|
||||
<after>
|
||||
<dep package="berkeleydb"/>
|
||||
<dep package="berkeleydb-nonsrctree"/>
|
||||
</after>
|
||||
</distutils>
|
||||
|
||||
<distutils id='pyfontconfig'>
|
||||
<branch repo='pymodules' version="0.5.1"
|
||||
module="e6/01/a28b0160f82ca5e946e315251c797f07c74e5c5a53f2a9e706eebc680191/Python-fontconfig-0.5.1.tar.gz"
|
||||
hash="sha256:b7cfe366242f83b8cd7175b7d4dd95d19f42d619c58a51914f72b1e741739994">
|
||||
<patch file="pyfontconfig-curexc.patch" strip="1"/>
|
||||
</branch>
|
||||
<dependencies>
|
||||
<dep package="python3"/>
|
||||
<dep package="fontconfig"/>
|
||||
</dependencies>
|
||||
</distutils>
|
||||
|
||||
<metamodule id="meta-gramps-modules">
|
||||
<dependencies>
|
||||
<dep package="python3"/>
|
||||
<dep package="meta-gtk-osx-gtk3"/>
|
||||
<dep package="meta-gtk-osx-gtk3-core-themes"/>
|
||||
<dep package="goocanvas2"/>
|
||||
<dep package="librsvg"/>
|
||||
<dep package="shared-mime-info"/>
|
||||
@ -202,7 +211,7 @@ gtk-mac-bundler gtk-osx-build/projects/gramps/gramps.bundle
|
||||
<dep package="pygobject3"/>
|
||||
<dep package='pyicu'/>
|
||||
<dep package='pybsddb'/>
|
||||
<dep package="pil"/>
|
||||
<dep package="pillow"/>
|
||||
</dependencies>
|
||||
</metamodule>
|
||||
|
||||
|
@ -24,6 +24,7 @@ environ['GTK_PATH'] = bundle_res
|
||||
environ['PANGO_RC_FILE'] = join(bundle_etc, 'pango', 'pangorc')
|
||||
environ['PANGO_SYSCONFDIR'] = bundle_etc
|
||||
environ['PANGO_LIBDIR'] = bundle_lib
|
||||
environ['GIO_MODULE_DIR'] = join(bundle_lib, 'gio', 'modules')
|
||||
environ['GDK_PIXBUF_MODULE_FILE'] = join(bundle_lib, 'gdk-pixbuf-2.0',
|
||||
'2.10.0', 'loaders.cache')
|
||||
environ['GI_TYPELIB_PATH'] = join(bundle_lib, 'girepository-1.0')
|
||||
@ -40,6 +41,8 @@ environ['USERPROFILE'] = environ['HOME']
|
||||
environ['APPDATA'] = join(environ['HOME'], 'Library', 'Application Support')
|
||||
environ['PATH'] = join(bundle_contents, 'MacOS') + ':' + environ['PATH']
|
||||
|
||||
if __name__ == '__main__':
|
||||
__file__ = 'gramps_launcher.py'
|
||||
import gramps.grampsapp as app
|
||||
app.main()
|
||||
|
||||
|
40
mac/patches/berkeleydb-4.8-atomic.patch
Normal file
@ -0,0 +1,40 @@
|
||||
--- a/dist/configure 2010-04-12 13:25:23.000000000 -0700
|
||||
+++ b/dist/configure 2021-04-11 11:27:32.000000000 -0700
|
||||
@@ -19158,7 +19158,7 @@
|
||||
# x86_64/gcc: FreeBSD, NetBSD, BSD/OS, Linux
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
-
|
||||
+#include <stdlib.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
@@ -20197,7 +20197,7 @@
|
||||
if test "$db_cv_atomic" = no; then
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
-
|
||||
+#include <stdlib.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
--- a/dbinc/atomic.h 2013-03-12 14:07:22.000000000 -0400
|
||||
+++ b/dbinc/atomic.h 2013-03-12 14:06:35.000000000 -0400
|
||||
@@ -144,7 +144,7 @@
|
||||
#define atomic_inc(env, p) __atomic_inc(p)
|
||||
#define atomic_dec(env, p) __atomic_dec(p)
|
||||
#define atomic_compare_exchange(env, p, o, n) \
|
||||
- __atomic_compare_exchange((p), (o), (n))
|
||||
+ __atomic_compare_exchange_db((p), (o), (n))
|
||||
static inline int __atomic_inc(db_atomic_t *p)
|
||||
{
|
||||
int temp;
|
||||
@@ -176,7 +176,7 @@
|
||||
* http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
|
||||
* which configure could be changed to use.
|
||||
*/
|
||||
-static inline int __atomic_compare_exchange(
|
||||
+static inline int __atomic_compare_exchange_db(
|
||||
db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval)
|
||||
{
|
||||
atomic_value_t was;
|
56
mac/patches/pyfontconfig-curexc.patch
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
--- a/fontconfig.c 2011-11-02 07:59:41.000000000 -0700
|
||||
+++ b/fontconfig.c 2021-08-09 18:07:50.000000000 -0700
|
||||
@@ -4525,12 +4525,12 @@
|
||||
Py_INCREF(local_type);
|
||||
Py_INCREF(local_value);
|
||||
Py_INCREF(local_tb);
|
||||
- tmp_type = tstate->exc_type;
|
||||
- tmp_value = tstate->exc_value;
|
||||
- tmp_tb = tstate->exc_traceback;
|
||||
- tstate->exc_type = local_type;
|
||||
- tstate->exc_value = local_value;
|
||||
- tstate->exc_traceback = local_tb;
|
||||
+ tmp_type = tstate->curexc_type;
|
||||
+ tmp_value = tstate->curexc_value;
|
||||
+ tmp_tb = tstate->curexc_traceback;
|
||||
+ tstate->curexc_type = local_type;
|
||||
+ tstate->curexc_value = local_value;
|
||||
+ tstate->curexc_traceback = local_tb;
|
||||
/* Make sure tstate is in a consistent state when we XDECREF
|
||||
these objects (XDECREF may run arbitrary code). */
|
||||
Py_XDECREF(tmp_type);
|
||||
@@ -4735,9 +4735,9 @@
|
||||
|
||||
static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
- *type = tstate->exc_type;
|
||||
- *value = tstate->exc_value;
|
||||
- *tb = tstate->exc_traceback;
|
||||
+ *type = tstate->curexc_type;
|
||||
+ *value = tstate->curexc_value;
|
||||
+ *tb = tstate->curexc_traceback;
|
||||
Py_XINCREF(*type);
|
||||
Py_XINCREF(*value);
|
||||
Py_XINCREF(*tb);
|
||||
@@ -4746,12 +4746,12 @@
|
||||
static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
|
||||
PyObject *tmp_type, *tmp_value, *tmp_tb;
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
- tmp_type = tstate->exc_type;
|
||||
- tmp_value = tstate->exc_value;
|
||||
- tmp_tb = tstate->exc_traceback;
|
||||
- tstate->exc_type = type;
|
||||
- tstate->exc_value = value;
|
||||
- tstate->exc_traceback = tb;
|
||||
+ tmp_type = tstate->curexc_type;
|
||||
+ tmp_value = tstate->curexc_value;
|
||||
+ tmp_tb = tstate->curexc_traceback;
|
||||
+ tstate->curexc_type = type;
|
||||
+ tstate->curexc_value = value;
|
||||
+ tstate->curexc_traceback = tb;
|
||||
Py_XDECREF(tmp_type);
|
||||
Py_XDECREF(tmp_value);
|
||||
Py_XDECREF(tmp_tb);
|
||||
|
||||
Diff finished. Mon Aug 9 18:09:16 2021
|
8
setup.py
@ -353,8 +353,8 @@ data_files_core.append(('share/gramps/css/swanky-purse/images', SWANKY_IMG))
|
||||
|
||||
PNG_FILES = glob.glob(os.path.join('data', '*.png'))
|
||||
SVG_FILES = glob.glob(os.path.join('data', '*.svg'))
|
||||
data_files_core.append(('share/icons/gnome/48x48/mimetypes', PNG_FILES))
|
||||
data_files_core.append(('share/icons/gnome/scalable/mimetypes', SVG_FILES))
|
||||
data_files_core.append(('share/icons/hicolor/48x48/mimetypes', PNG_FILES))
|
||||
data_files_core.append(('share/icons/hicolor/scalable/mimetypes', SVG_FILES))
|
||||
|
||||
DTD_FILES = glob.glob(os.path.join('data', '*.dtd'))
|
||||
RNG_FILES = glob.glob(os.path.join('data', '*.rng'))
|
||||
@ -381,11 +381,15 @@ APP_16 = os.path.join(THEME, '16x16', 'apps', 'gramps.png')
|
||||
APP_22 = os.path.join(THEME, '22x22', 'apps', 'gramps.png')
|
||||
APP_24 = os.path.join(THEME, '24x24', 'apps', 'gramps.png')
|
||||
APP_48 = os.path.join(THEME, '48x48', 'apps', 'gramps.png')
|
||||
APP_128 = os.path.join(THEME, '128x128', 'apps', 'gramps.png')
|
||||
APP_256 = os.path.join(THEME, '256x256', 'apps', 'gramps.png')
|
||||
APP_SC = os.path.join(THEME, 'scalable', 'apps', 'gramps.svg')
|
||||
data_files_gui.append(('share/icons/hicolor/16x16/apps', [APP_16]))
|
||||
data_files_gui.append(('share/icons/hicolor/22x22/apps', [APP_22]))
|
||||
data_files_gui.append(('share/icons/hicolor/24x24/apps', [APP_24]))
|
||||
data_files_gui.append(('share/icons/hicolor/48x48/apps', [APP_48]))
|
||||
data_files_gui.append(('share/icons/hicolor/128x128/apps', [APP_128]))
|
||||
data_files_gui.append(('share/icons/hicolor/256x256/apps', [APP_256]))
|
||||
data_files_gui.append(('share/icons/hicolor/scalable/apps', [APP_SC]))
|
||||
|
||||
data_files = data_files_core + data_files_gui
|
||||
|