Compare commits
790 Commits
maintenanc
...
maintenanc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17c1dfe950 | ||
|
|
4531cbd049 | ||
|
|
d24fc82031 | ||
|
|
16a9cd4c93 | ||
|
|
94018ed33a | ||
|
|
ffd77dc404 | ||
|
|
7c6e531c26 | ||
|
|
bc4b006dbe | ||
|
|
40da63a0fb | ||
|
|
6fafe8f6c3 | ||
|
|
66a0c619b9 | ||
|
|
6ffc095db0 | ||
|
|
5a5f4970f7 | ||
|
|
ea3d49e50c | ||
|
|
e4b6d9beda | ||
|
|
b6f68c03bb | ||
|
|
f5a66c3958 | ||
|
|
c6ce61b4b9 | ||
|
|
9c050491ef | ||
|
|
54ab2820c3 | ||
|
|
1bf9fef1cb | ||
|
|
dafde8df12 | ||
|
|
ac6eb9661c | ||
|
|
09bc188a1c | ||
|
|
4d68f68742 | ||
|
|
70a634da1e | ||
|
|
ec44396680 | ||
|
|
5490ff0b84 | ||
|
|
a339e68877 | ||
|
|
dd0956d6ce | ||
|
|
7911785ea4 | ||
|
|
9eebeb05da | ||
|
|
a492511533 | ||
|
|
ed907def1f | ||
|
|
22a9cbdcc8 | ||
|
|
84e0d45ab6 | ||
|
|
85f42908f4 | ||
|
|
da1c942509 | ||
|
|
d98db27dcc | ||
|
|
2b74e0734a | ||
|
|
ebae9c3915 | ||
|
|
286289aaf7 | ||
|
|
e8489bf53c | ||
|
|
9946d6f993 | ||
|
|
00f87cc70e | ||
|
|
2fbc0b8aeb | ||
|
|
56122b0a54 | ||
|
|
6648ecb5ff | ||
|
|
1b2d0a1956 | ||
|
|
6bdac08358 | ||
|
|
e74dc2fa8c | ||
|
|
314f7cce65 | ||
|
|
11776db76d | ||
|
|
eecf48e6e5 | ||
|
|
bedebc524b | ||
|
|
c01ee8ed7d | ||
|
|
578f4bdf62 | ||
|
|
baadf6158a | ||
|
|
024204771b | ||
|
|
7ed03d43d5 | ||
|
|
24d97f528e | ||
|
|
d9bb009e6b | ||
|
|
16d7f92b97 | ||
|
|
1a1c82c261 | ||
|
|
b9cd0450dc | ||
|
|
df01461171 | ||
|
|
b573c7d7cf | ||
|
|
60f944adcf | ||
|
|
9e12a5d364 | ||
|
|
c138aeb8c6 | ||
|
|
00a5ea1a39 | ||
|
|
9bb4aaaf49 | ||
|
|
ae6db43fc4 | ||
|
|
5972477550 | ||
|
|
215f6bf88d | ||
|
|
fc3e41d696 | ||
|
|
706d29a480 | ||
|
|
26c50fdbdd | ||
|
|
7a61a0e96f | ||
|
|
efab48d5cc | ||
|
|
647a3b226a | ||
|
|
db3655d156 | ||
|
|
95e0f43bf5 | ||
|
|
77e9d796da | ||
|
|
2af262435d | ||
|
|
4fca41c8c9 | ||
|
|
8c7133ab00 | ||
|
|
425c15e6f5 | ||
|
|
0ab7c316f0 | ||
|
|
a219421e36 | ||
|
|
7bbc976141 | ||
|
|
f1b311c9cd | ||
|
|
3c2231591f | ||
|
|
ac18460059 | ||
|
|
aebe2810f8 | ||
|
|
4ff908bcef | ||
|
|
f8c1a54def | ||
|
|
3d1ec9e658 | ||
|
|
fd83162289 | ||
|
|
f092144a93 | ||
|
|
041d969cce | ||
|
|
c656b38d9e | ||
|
|
2f1df8ac69 | ||
|
|
49416739c1 | ||
|
|
5f2a6df0d0 | ||
|
|
0be00be4d9 | ||
|
|
ab17a5340a | ||
|
|
e578316bd9 | ||
|
|
1c83948b40 | ||
|
|
63ce7383cc | ||
|
|
11f0c0254b | ||
|
|
d691cfdb1c | ||
|
|
58b12e702a | ||
|
|
2bd1a4b757 | ||
|
|
54b6563e63 | ||
|
|
0964bfd683 | ||
|
|
35ceba1e4d | ||
|
|
dc82105fa4 | ||
|
|
c5d40f70d0 | ||
|
|
77ccb1770b | ||
|
|
68f54f9b08 | ||
|
|
78c807814d | ||
|
|
a515501552 | ||
|
|
0e05b2f535 | ||
|
|
b999e2df78 | ||
|
|
906035b022 | ||
|
|
9be31757e0 | ||
|
|
cc50e4e972 | ||
|
|
4a583e187c | ||
|
|
bc51334178 | ||
|
|
d1d08a1552 | ||
|
|
3a58492424 | ||
|
|
9860fdb941 | ||
|
|
aedf26b871 | ||
|
|
47ba95d005 | ||
|
|
6b5253abce | ||
|
|
ca5953f1bc | ||
|
|
44e89c0a67 | ||
|
|
1acbd3e3f7 | ||
|
|
b568c1bb97 | ||
|
|
1b05edf7b4 | ||
|
|
5cd646d22b | ||
|
|
aca78ad3d5 | ||
|
|
d85ab22db6 | ||
|
|
70998b2a6b | ||
|
|
f4a82ce6e0 | ||
|
|
477efa8a5a | ||
|
|
8f05973b29 | ||
|
|
cb251ccccf | ||
|
|
95afffef79 | ||
|
|
e52e0d3734 | ||
|
|
bb58b6fc1b | ||
|
|
de7342d3e8 | ||
|
|
46d8839880 | ||
|
|
10781bde6b | ||
|
|
7a4b7aa77b | ||
|
|
c03ccaa740 | ||
|
|
d682302612 | ||
|
|
6bbe44f6aa | ||
|
|
703703cc75 | ||
|
|
17c51b3e76 | ||
|
|
3e53d086ea | ||
|
|
b0fd9bcceb | ||
|
|
7e2585d27e | ||
|
|
cd4afcdb32 | ||
|
|
4e5112d3fd | ||
|
|
87e38afdde | ||
|
|
2a55fd268c | ||
|
|
dec4380c82 | ||
|
|
05d4cc39e3 | ||
|
|
e5a7fdc512 | ||
|
|
3f83395603 | ||
|
|
850685c3ef | ||
|
|
ac00bd1843 | ||
|
|
b2775b3892 | ||
|
|
f2d822b8b7 | ||
|
|
3d1ec482e4 | ||
|
|
9f6e1ebe7d | ||
|
|
b7b8daef40 | ||
|
|
7f6757bcad | ||
|
|
57794a7ed2 | ||
|
|
517f794af6 | ||
|
|
ce59ea6c4a | ||
|
|
00dc403ec3 | ||
|
|
68f7238048 | ||
|
|
3c8cd9f7ab | ||
|
|
4a12c344c6 | ||
|
|
fd0d9cf297 | ||
|
|
ce9f77ac77 | ||
|
|
eac82f538e | ||
|
|
6511379220 | ||
|
|
84c8fada7a | ||
|
|
fd96331b6d | ||
|
|
5a5868d183 | ||
|
|
e53587783e | ||
|
|
072048bdf1 | ||
|
|
eec2f8477b | ||
|
|
402cf35f88 | ||
|
|
cd478d0e0d | ||
|
|
8b41cab3fc | ||
|
|
19447be47c | ||
|
|
dd179ad790 | ||
|
|
9ca553bf7f | ||
|
|
d3768f384f | ||
|
|
3b557ead10 | ||
|
|
87cb2654ab | ||
|
|
a0c96e576f | ||
|
|
92f444eb7e | ||
|
|
9c533916f1 | ||
|
|
1f45e8996b | ||
|
|
f95c8a2036 | ||
|
|
9c10b59c8b | ||
|
|
53dedde014 | ||
|
|
47e4b3de25 | ||
|
|
3af32ec258 | ||
|
|
04e123a5ce | ||
|
|
70daa4029a | ||
|
|
22fb6f2841 | ||
|
|
eb5c8da8b0 | ||
|
|
586573d289 | ||
|
|
43c1f24c2d | ||
|
|
998c3c37fc | ||
|
|
a8c32dcb16 | ||
|
|
632aada923 | ||
|
|
883f29901f | ||
|
|
32d7c236e8 | ||
|
|
13b3de4955 | ||
|
|
c83326a4d6 | ||
|
|
1cada500de | ||
|
|
a6126dbd03 | ||
|
|
92d2181621 | ||
|
|
018f60c826 | ||
|
|
194bafd484 | ||
|
|
93422189fe | ||
|
|
6ade6ba419 | ||
|
|
802bab7bbe | ||
|
|
191bda5418 | ||
|
|
cfdbbf7260 | ||
|
|
718410e28f | ||
|
|
c46a4c4351 | ||
|
|
42f9f4701c | ||
|
|
016db63648 | ||
|
|
57902a4333 | ||
|
|
e3e61191ba | ||
|
|
d985980ad7 | ||
|
|
3cdc1bd988 | ||
|
|
e311de1964 | ||
|
|
c5a14c94ae | ||
|
|
7e234beff7 | ||
|
|
3e21084f02 | ||
|
|
e53df38c8a | ||
|
|
b999680f83 | ||
|
|
a19790c5ea | ||
|
|
a49b0792d0 | ||
|
|
5e7b84bdde | ||
|
|
2eed3c4ab6 | ||
|
|
b5260704df | ||
|
|
28cc175fb5 | ||
|
|
73eaf011a0 | ||
|
|
f1156c9627 | ||
|
|
a72e6f158c | ||
|
|
2ac3935092 | ||
|
|
62f47ffd6d | ||
|
|
87bd65c855 | ||
|
|
fd1f290752 | ||
|
|
71a25a9e28 | ||
|
|
ef28c52f4c | ||
|
|
ef75fc8c15 | ||
|
|
72a9897283 | ||
|
|
96f2091ee9 | ||
|
|
f24ef15518 | ||
|
|
be6715cd99 | ||
|
|
16e2ed4f54 | ||
|
|
31ad46d73e | ||
|
|
73ee71eb2a | ||
|
|
4619dbe1a5 | ||
|
|
be1bf15964 | ||
|
|
a9fe12c394 | ||
|
|
d460e9a6eb | ||
|
|
d4373249f7 | ||
|
|
75f383f90f | ||
|
|
f776dc480e | ||
|
|
7d4da1d9ef | ||
|
|
7786cdcf4c | ||
|
|
2ea2cb135e | ||
|
|
22ad26b7ef | ||
|
|
dc77d95274 | ||
|
|
8b6bd226af | ||
|
|
6e0a6c4c87 | ||
|
|
c8d5a40efc | ||
|
|
54d9d45486 | ||
|
|
92659145d0 | ||
|
|
8acb425674 | ||
|
|
c8d097269c | ||
|
|
fd4737bfc9 | ||
|
|
4a27671337 | ||
|
|
5cec72ed04 | ||
|
|
9ad824d56e | ||
|
|
b77089e97f | ||
|
|
57a963d0b2 | ||
|
|
df55780880 | ||
|
|
170d63f378 | ||
|
|
31bdd8f5f1 | ||
|
|
8f396cb6e9 | ||
|
|
f3dcc68a44 | ||
|
|
ed936f9975 | ||
|
|
6f94ec8ef3 | ||
|
|
653e18db5a | ||
|
|
1e9de5517f | ||
|
|
9caa89fe3b | ||
|
|
56e640731f | ||
|
|
826c9a4122 | ||
|
|
d9c095a8d3 | ||
|
|
89e0297881 | ||
|
|
848fe67ada | ||
|
|
47f798077e | ||
|
|
358428181b | ||
|
|
c48034eca8 | ||
|
|
f8486d4954 | ||
|
|
9ce3a52d33 | ||
|
|
d2de684c5e | ||
|
|
c405b58a75 | ||
|
|
e3e787c038 | ||
|
|
987f9d0729 | ||
|
|
9a207499c3 | ||
|
|
c7d8f6ba6e | ||
|
|
30fb4916f3 | ||
|
|
c3e0d8c7c0 | ||
|
|
a7a8b72df4 | ||
|
|
e9c076520a | ||
|
|
8103bb7b4a | ||
|
|
93882fa9cb | ||
|
|
2534368419 | ||
|
|
aa71dd095d | ||
|
|
880a583a0f | ||
|
|
88bdc33051 | ||
|
|
155a03a92f | ||
|
|
f322ab43a6 | ||
|
|
29b94e5de8 | ||
|
|
e4573b9b7a | ||
|
|
73d13ba826 | ||
|
|
0414893c34 | ||
|
|
27c1c15a20 | ||
|
|
e03ac241e1 | ||
|
|
5eb841b8d3 | ||
|
|
92612cebf2 | ||
|
|
03178fb1df | ||
|
|
93cb85be3d | ||
|
|
f9f98c79a7 | ||
|
|
8a283ff376 | ||
|
|
cfeb97a524 | ||
|
|
9887e6376d | ||
|
|
7fe02eb49a | ||
|
|
f5e6d30d9b | ||
|
|
61ee32cb7b | ||
|
|
f6df78bf33 | ||
|
|
fc687e3bfa | ||
|
|
1c1d05b2ac | ||
|
|
0c3b2d44a8 | ||
|
|
dba68c5876 | ||
|
|
1a35de0446 | ||
|
|
fd9b38dbed | ||
|
|
2965533e2c | ||
|
|
25018d68e3 | ||
|
|
d8c9ace62e | ||
|
|
3aa2b6688e | ||
|
|
2bbe278f41 | ||
|
|
037f8607e0 | ||
|
|
97fbbfa31c | ||
|
|
5fe4ab64a9 | ||
|
|
4bbee3539b | ||
|
|
8744da91c3 | ||
|
|
68b35f73fb | ||
|
|
af58730c15 | ||
|
|
9784e43b79 | ||
|
|
cc1726f799 | ||
|
|
7a114ac493 | ||
|
|
179f793685 | ||
|
|
8a2161fa47 | ||
|
|
cd45753c07 | ||
|
|
d335a6dd80 | ||
|
|
382635796b | ||
|
|
c163bfc18e | ||
|
|
37a4d19a92 | ||
|
|
a7306150a2 | ||
|
|
e7db5c9db5 | ||
|
|
54e8ea0e39 | ||
|
|
36da63b33e | ||
|
|
a112f8f3fa | ||
|
|
91d23b3594 | ||
|
|
425fe632f3 | ||
|
|
b7b61e3cf0 | ||
|
|
e79e325b28 | ||
|
|
638cd571d4 | ||
|
|
f031abd7c9 | ||
|
|
07d3bb80ac | ||
|
|
d90b34a883 | ||
|
|
ea9b4eba01 | ||
|
|
675633f055 | ||
|
|
9ec04d86a5 | ||
|
|
a09a014285 | ||
|
|
299cf15f1e | ||
|
|
4d30398948 | ||
|
|
5072cdb844 | ||
|
|
c21687134c | ||
|
|
56ff535968 | ||
|
|
5711548e60 | ||
|
|
ee00bc8881 | ||
|
|
6f8e7b4694 | ||
|
|
569f751b79 | ||
|
|
c7bfce5066 | ||
|
|
a9b42e8a3d | ||
|
|
61e08dd723 | ||
|
|
54e4ee8856 | ||
|
|
fed79f99d6 | ||
|
|
38f66a2f58 | ||
|
|
cf7edc6844 | ||
|
|
a01fc6d442 | ||
|
|
266f67f12b | ||
|
|
62ce43aa5d | ||
|
|
e543bfd310 | ||
|
|
4c0c769bcd | ||
|
|
51f3e4928d | ||
|
|
fda0c4a91c | ||
|
|
9c8389f4ef | ||
|
|
657068663e | ||
|
|
fed57a939d | ||
|
|
0e044392b8 | ||
|
|
c802eedd08 | ||
|
|
22c160f2bd | ||
|
|
be70956e90 | ||
|
|
0106661523 | ||
|
|
a1b30a5f7e | ||
|
|
cf5d9e183a | ||
|
|
1fd06c506e | ||
|
|
047ff3673c | ||
|
|
bef7e7249c | ||
|
|
63b766245c | ||
|
|
d207408717 | ||
|
|
ef762645e3 | ||
|
|
257ea9117f | ||
|
|
611c3bd13d | ||
|
|
b4d7e4b8b3 | ||
|
|
474ee487dd | ||
|
|
44ae41107d | ||
|
|
d5f871e8e7 | ||
|
|
6bca978207 | ||
|
|
0e51573af9 | ||
|
|
9232e78c0a | ||
|
|
15c3837968 | ||
|
|
dba52f4d2f | ||
|
|
e0502e1ba8 | ||
|
|
f73d719b9e | ||
|
|
b91eb1540a | ||
|
|
cfa0e0c4f7 | ||
|
|
0937286eba | ||
|
|
a57257415c | ||
|
|
f7a09fc558 | ||
|
|
bb33cdadb6 | ||
|
|
b9d3378020 | ||
|
|
ca2607de0e | ||
|
|
75a4a380a9 | ||
|
|
72d54a319f | ||
|
|
e50f0c145e | ||
|
|
df90ef58fd | ||
|
|
4640ad39a1 | ||
|
|
2bc4dd3418 | ||
|
|
2c774355ac | ||
|
|
b5871d1ae5 | ||
|
|
908ace174b | ||
|
|
1b07d9a621 | ||
|
|
24377c66c8 | ||
|
|
f11c7b9de0 | ||
|
|
e2c76dfb12 | ||
|
|
0f72a796c2 | ||
|
|
7d3b7c9277 | ||
|
|
6f8dd6f287 | ||
|
|
d4e1d60f97 | ||
|
|
efe0767012 | ||
|
|
2dc332a78c | ||
|
|
f15f6a14b0 | ||
|
|
a766ec583a | ||
|
|
c860db13a9 | ||
|
|
34afcb6504 | ||
|
|
3ca0db552a | ||
|
|
efaa713f68 | ||
|
|
888bdc77b5 | ||
|
|
ad84bed2d5 | ||
|
|
468db43aef | ||
|
|
1447d244d8 | ||
|
|
aedb8f83ed | ||
|
|
365df85971 | ||
|
|
f15649a0f1 | ||
|
|
407588d338 | ||
|
|
3b1687143d | ||
|
|
c1f4ccf46c | ||
|
|
abf4511f87 | ||
|
|
6016acafdb | ||
|
|
f51aaccc78 | ||
|
|
d532ecabc7 | ||
|
|
c42d4cf3f8 | ||
|
|
c82b75fef8 | ||
|
|
f30fa909c1 | ||
|
|
a98daed758 | ||
|
|
4046c8af0f | ||
|
|
0baf7dc3ad | ||
|
|
4f14f8e4a0 | ||
|
|
b5229c46f5 | ||
|
|
229602577f | ||
|
|
908aa90b61 | ||
|
|
32426459db | ||
|
|
66114432df | ||
|
|
5baf8d322c | ||
|
|
1302743541 | ||
|
|
da417a5ee7 | ||
|
|
08338db8ab | ||
|
|
9fecb67bd8 | ||
|
|
d89e9d2c67 | ||
|
|
67e0f75107 | ||
|
|
3e4569bd49 | ||
|
|
dddd5b5db2 | ||
|
|
2fc9459aad | ||
|
|
ba98dc0412 | ||
|
|
586bd2fcf5 | ||
|
|
f7e8b90d60 | ||
|
|
e6b8dacfc3 | ||
|
|
a6de1c81bc | ||
|
|
03773fe9a2 | ||
|
|
6f849befe0 | ||
|
|
6ec12af6d7 | ||
|
|
5fa70824a3 | ||
|
|
05a53a40c9 | ||
|
|
1b09074fc4 | ||
|
|
b0d040ee99 | ||
|
|
b56b63a9fa | ||
|
|
e6cc62ff9c | ||
|
|
d81e851fd5 | ||
|
|
c96a8b85b9 | ||
|
|
0d07292d23 | ||
|
|
a8198c3ef1 | ||
|
|
b4827dc9c1 | ||
|
|
6d99a47b5e | ||
|
|
db2037fe08 | ||
|
|
2309747413 | ||
|
|
a3bf2e4d6e | ||
|
|
bd694b0baa | ||
|
|
8bf081ccc3 | ||
|
|
6f66a021bb | ||
|
|
55733cb264 | ||
|
|
17f8b4818c | ||
|
|
3755337db9 | ||
|
|
afbfaa815d | ||
|
|
7beb66dd66 | ||
|
|
e3374b8cb5 | ||
|
|
d3f90860c1 | ||
|
|
227da7671f | ||
|
|
7c3eaa9684 | ||
|
|
4cfa03ab16 | ||
|
|
ae89bc4d83 | ||
|
|
75ac634fa9 | ||
|
|
2e6e13e166 | ||
|
|
dec1130c81 | ||
|
|
dcb0aa8c35 | ||
|
|
1b4143f83c | ||
|
|
f5adb32bb6 | ||
|
|
c36e3f4747 | ||
|
|
688ee0f918 | ||
|
|
f548570af1 | ||
|
|
09e3ff2a62 | ||
|
|
73f75f7317 | ||
|
|
1e3ad0d325 | ||
|
|
09dd6deea3 | ||
|
|
460049809d | ||
|
|
80a9597e5a | ||
|
|
428c341005 | ||
|
|
a8d2f21b23 | ||
|
|
93962adaef | ||
|
|
d893ec5de5 | ||
|
|
9ff1f7781c | ||
|
|
b2fa1350f0 | ||
|
|
67e6a53951 | ||
|
|
01a68f5692 | ||
|
|
0f8bdbca00 | ||
|
|
f582592cf1 | ||
|
|
96173da947 | ||
|
|
e9ddd513a4 | ||
|
|
39cc00963d | ||
|
|
cc25a21ad7 | ||
|
|
f7084a775b | ||
|
|
2ac9f5bbd6 | ||
|
|
7a7ac5376d | ||
|
|
ad01a680aa | ||
|
|
318f2e93ce | ||
|
|
d210ea64f6 | ||
|
|
0f11ac01c8 | ||
|
|
25b999a140 | ||
|
|
be59619444 | ||
|
|
a1c0db37ad | ||
|
|
a2dbc495df | ||
|
|
3104900c21 | ||
|
|
50911b7cf1 | ||
|
|
dd33a4b172 | ||
|
|
d03f13c503 | ||
|
|
65f0df74c7 | ||
|
|
dce07dcb1d | ||
|
|
2dae5c3a08 | ||
|
|
3ed5e74657 | ||
|
|
67e6c66555 | ||
|
|
a121922310 | ||
|
|
6fc4d1f536 | ||
|
|
98409ca194 | ||
|
|
085409bcc0 | ||
|
|
bd06550331 | ||
|
|
1dc8746810 | ||
|
|
e53f15e8a9 | ||
|
|
8209096b73 | ||
|
|
7fa9e647e5 | ||
|
|
dcb8efd8e6 | ||
|
|
c0bdfafbda | ||
|
|
e5d564dbf0 | ||
|
|
aabb06ab11 | ||
|
|
a14894fce7 | ||
|
|
3df700b22a | ||
|
|
58d7cbe99d | ||
|
|
b5f419cbf3 | ||
|
|
9aaaaa3816 | ||
|
|
f2b1a5bdbc | ||
|
|
58fc415e28 | ||
|
|
f3898c5d43 | ||
|
|
de6847db7b | ||
|
|
e7ce80a06e | ||
|
|
789a94b59b | ||
|
|
10029e3a67 | ||
|
|
31aa503934 | ||
|
|
5cf54d4300 | ||
|
|
7b5c692787 | ||
|
|
1b91f53622 | ||
|
|
f3a3da5e5c | ||
|
|
e525aab0c8 | ||
|
|
8346836cf9 | ||
|
|
ce6edaf901 | ||
|
|
83e671afd5 | ||
|
|
5d5ca47863 | ||
|
|
2a8d75c493 | ||
|
|
63f09baab0 | ||
|
|
f96df5658c | ||
|
|
5d86e44264 | ||
|
|
b5eaeff3a4 | ||
|
|
d2da00989a | ||
|
|
36687cd703 | ||
|
|
25a9f17d66 | ||
|
|
f8380e1b0c | ||
|
|
3c2b7406c5 | ||
|
|
595828ba99 | ||
|
|
8b09bcdb98 | ||
|
|
d19bed4b42 | ||
|
|
8e0e07240f | ||
|
|
e7ba2423aa | ||
|
|
c19402f731 | ||
|
|
faba7ddc2c | ||
|
|
4379f42999 | ||
|
|
f30a353e15 | ||
|
|
029241bae9 | ||
|
|
86cab99e7a | ||
|
|
85a97c1c7f | ||
|
|
538b00b3c8 | ||
|
|
2637e2dcc1 | ||
|
|
cc1d15fc3f | ||
|
|
ad8259814d | ||
|
|
0cd63965a7 | ||
|
|
7b987cfa88 | ||
|
|
3e6fd00286 | ||
|
|
27e6d9b2a9 | ||
|
|
8b65c60a04 | ||
|
|
6e69cbcb04 | ||
|
|
6b929e9c7e | ||
|
|
f9ccea0149 | ||
|
|
feee26f74a | ||
|
|
6e68cc3f73 | ||
|
|
bce1462567 | ||
|
|
61443ad9ce | ||
|
|
2e93109d75 | ||
|
|
bbab0cdbba | ||
|
|
ae73a30a6d | ||
|
|
eed9e6505e | ||
|
|
34bb729c7a | ||
|
|
3060d7504a | ||
|
|
2e32fc7141 | ||
|
|
ee060b85a2 | ||
|
|
289436ee33 | ||
|
|
905ac154d3 | ||
|
|
ac29b091a7 | ||
|
|
1a618c3a2e | ||
|
|
c731c68ec5 | ||
|
|
ab80af602c | ||
|
|
4caa412a06 | ||
|
|
49ec2e1244 | ||
|
|
63dc1ddff8 | ||
|
|
b9c3b077e8 | ||
|
|
8c9333b58d | ||
|
|
fd22effab3 | ||
|
|
5e5e92ac9a | ||
|
|
7fac5c6607 | ||
|
|
fa26216839 | ||
|
|
9032c0a37d | ||
|
|
fb6a2cecf2 | ||
|
|
90de5dffec | ||
|
|
8ec10c067f | ||
|
|
84be6de6ab | ||
|
|
0b88c61421 | ||
|
|
d943e122a8 | ||
|
|
fc08e7de4e | ||
|
|
a04c8dc497 | ||
|
|
66c943f69d | ||
|
|
0ad17ac27f | ||
|
|
01536e4b50 | ||
|
|
811261609f | ||
|
|
cba763611d | ||
|
|
56de5ff4af | ||
|
|
928a0af713 | ||
|
|
913fdd071c | ||
|
|
22a27e9707 | ||
|
|
2142118832 | ||
|
|
fabd5742fc | ||
|
|
7a3da35543 | ||
|
|
c0c165d155 | ||
|
|
030ffd8226 | ||
|
|
4964461fa4 | ||
|
|
42c4662329 | ||
|
|
d3eafc00db | ||
|
|
a2030431c0 | ||
|
|
56f867d783 | ||
|
|
5a752205b3 | ||
|
|
6e87ee433c | ||
|
|
70806f2388 | ||
|
|
b8b186dde2 | ||
|
|
d10c4faffe | ||
|
|
8bff04729f | ||
|
|
9cddf3ebdb | ||
|
|
c089eba1c3 | ||
|
|
a94f3100df | ||
|
|
5d341a684e | ||
|
|
26723c1b60 | ||
|
|
de7430eeb8 | ||
|
|
89ffc6b4cc | ||
|
|
a18120f17d | ||
|
|
2846fc7dc5 | ||
|
|
e6c5232ae8 | ||
|
|
e7ab8b322b | ||
|
|
fde34bb53b | ||
|
|
60c0843861 | ||
|
|
2ae2ca5c7d | ||
|
|
9747d1deea | ||
|
|
e52d0a7a90 | ||
|
|
eefd3e13e4 | ||
|
|
918317434f | ||
|
|
8dfc5381cd | ||
|
|
6511a80b47 | ||
|
|
a5074e9478 | ||
|
|
b90808525c | ||
|
|
fedfabc87e | ||
|
|
891b9d2e34 | ||
|
|
3b0579afc3 | ||
|
|
5e763026a4 | ||
|
|
de706de317 | ||
|
|
b884dc0e4c | ||
|
|
aaba2ec347 | ||
|
|
bdd44b57fd | ||
|
|
8deb444a6c | ||
|
|
ca3158a6ff | ||
|
|
53a9cfc83f | ||
|
|
92fc8f8dcb | ||
|
|
7a488c2fd4 | ||
|
|
98ff7693f3 | ||
|
|
6b7258dfe0 | ||
|
|
aceee07544 | ||
|
|
9e670d51bd | ||
|
|
8e97b25f38 | ||
|
|
6aeeafe74d | ||
|
|
4189799d45 | ||
|
|
5bfe514f45 | ||
|
|
aa35dbfb82 | ||
|
|
784ab0c3c7 | ||
|
|
5847bb0e17 | ||
|
|
08ac0b0996 | ||
|
|
c38ccf22ed | ||
|
|
1866b7ace1 | ||
|
|
27b7676caa | ||
|
|
c273926941 | ||
|
|
ba8392923a |
9
.gitattributes
vendored
Normal file
9
.gitattributes
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Make Github recognise Gramps as a Python project,
|
||||
# by marking .sql files as text files!
|
||||
# See: https://github.com/github/linguist/issues/2462
|
||||
# https://github.com/github/linguist/blob/master/README.md
|
||||
*.sql linguist-language=txt
|
||||
|
||||
# Have Github ignore js vendored files.
|
||||
# https://github.com/gramps-project/gramps/tree/master/data/javascript
|
||||
#data/javascript/*.js linguist-vendored
|
||||
21
.travis.yml
21
.travis.yml
@@ -2,22 +2,25 @@
|
||||
# http://lint.travis-ci.org/
|
||||
|
||||
|
||||
language: c
|
||||
language: python
|
||||
#python:
|
||||
# - 3.3
|
||||
# - 3.4
|
||||
|
||||
install:
|
||||
- git clone --depth=50 --branch=master git://github.com/gramps-project/gramps.git gramps-project/gramps
|
||||
- cd gramps-project/gramps
|
||||
- git clone --depth=50 --branch=maintenance/gramps42 git://github.com/gramps-project/gramps.git gramps-project/gramps
|
||||
- cd gramps-project/gramps
|
||||
- time sudo apt-get update
|
||||
- travis_retry sudo apt-get install gir1.2-pango gir1.2-gtk xdg-utils librsvg2-common libglib2.0-dev intltool
|
||||
- travis_retry sudo apt-get install gir1.2-pango gir1.2-gtk xdg-utils librsvg2-common libglib2.0-dev intltool
|
||||
- travis_retry sudo apt-get install python3-gobject python3-gi python3-cairo python3-gi-cairo python3-bsddb3 python3-dev python3-nose
|
||||
|
||||
- travis_retry sudo apt-get install python3-mock
|
||||
|
||||
# - travis_retry curl https://bootstrap.pypa.io/get-pip.py | sudo python3
|
||||
# - travis_retry sudo pip3 install Django==1.7
|
||||
# - travis_retry sudo pip3 install pyicu==1.8
|
||||
# - travis_retry sudo pip3 install mock
|
||||
|
||||
- travis_retry curl https://bootstrap.pypa.io/get-pip.py | sudo python3
|
||||
- travis_retry sudo pip3 install Django==1.7
|
||||
- travis_retry sudo pip3 install pyicu==1.8
|
||||
- travis_retry sudo pip3 install mock
|
||||
- python3 setup.py build
|
||||
|
||||
#before_script:
|
||||
@@ -26,4 +29,4 @@ install:
|
||||
|
||||
script:
|
||||
- mkdir -p /home/travis/.gramps/grampsdb/
|
||||
- DJANGO_SETTINGS_MODULE=gramps.webapp.settings nosetests3 --exclude=TestcaseGenerator --exclude=vcard --exclude=merge_ref_test gramps
|
||||
- nosetests3 --exclude=TestcaseGenerator --exclude=vcard --exclude=merge_ref_test --exclude=user_test --exclude=webapp gramps
|
||||
|
||||
13
ChangeLog
Normal file
13
ChangeLog
Normal file
@@ -0,0 +1,13 @@
|
||||
2018-02-09 prculley <paulr2787@gmail.com>
|
||||
|
||||
* gramps/plugins/view/geoclose.py,
|
||||
gramps/plugins/view/geoevents.py,
|
||||
gramps/plugins/view/geofamclose.py,
|
||||
gramps/plugins/view/geofamily.py, gramps/plugins/view/geoperson.py,
|
||||
gramps/plugins/view/geoplaces.py: Fix Geography views for bad
|
||||
'dbstate.is_open()' test Fixes #10417
|
||||
|
||||
2018-02-08 Nick Hall <nick-h@gramps-project.org>
|
||||
|
||||
* Bump to 4.2.8
|
||||
|
||||
2
FAQ
2
FAQ
@@ -212,7 +212,7 @@ their own plugins which could be new reports, charts, or research tools.
|
||||
|
||||
18. In what formats can Gramps output its reports?
|
||||
|
||||
Text reports are available in HTML, PDF, ODT, LaTeX, and RTF formats. Graphical reports (charts and diagrams) are available in PostScript, PDF, SVG, ODS, and GraphViz formats.
|
||||
Text reports are available in HTML, PDF, ODT, LaTeX, and RTF formats. Graphical reports (charts and diagrams) are available in PostScript, PDF, SVG, ODS, and Graphviz formats.
|
||||
|
||||
|
||||
19. How can I change the default language in reports?
|
||||
|
||||
26
INSTALL
26
INSTALL
@@ -33,11 +33,11 @@ all required and optional dependencies. Missing dependencies will
|
||||
result in runtime errors.
|
||||
|
||||
To build and install, whether from a tarball or git repo:
|
||||
python setup.py build
|
||||
sudo python setup.py install
|
||||
python3 setup.py build
|
||||
sudo python3 setup.py install
|
||||
|
||||
You can avoid using sudo for the install step by specifying a prefix to which you have write priviledge. The default is /usr/local, which is usually owned by root. You can learn of more options with
|
||||
python setup.py --help
|
||||
python3 setup.py --help
|
||||
|
||||
One can use gramps from the command line without installing it by
|
||||
setting the following environment variables, but that won't provide
|
||||
@@ -71,7 +71,7 @@ from the source directory.
|
||||
b) You installed Gramps, and want to start it from the PYTHONPATH. In this
|
||||
case use the command:
|
||||
|
||||
python -c 'from gramps.grampsapp import main; main()'
|
||||
python3 -c 'from gramps.grampsapp import main; main()'
|
||||
|
||||
The executable 'gramps' in /usr/local/bin or /usr/bin from a) does
|
||||
this for you.
|
||||
@@ -79,7 +79,7 @@ from the source directory.
|
||||
b) You downloaded the Gramps source code to a directory, and want to run it.
|
||||
You can start Gramps from the source code directory with
|
||||
|
||||
python Gramps.py
|
||||
python3 Gramps.py
|
||||
|
||||
See gramps/gen/const.py how Gramps finds its resource directories in case
|
||||
you encounter problems.
|
||||
@@ -90,17 +90,17 @@ If you would like to install Gramps without being root, or in an
|
||||
alternative location on windows, supply the --root argument to setup.py
|
||||
|
||||
For example:
|
||||
python setup.py install --root ~/test
|
||||
or
|
||||
python setup.py install --root ~/test --enable-packager-mode
|
||||
|
||||
The last option, --enable-packager-mode, is needed if you want to disable
|
||||
execution of post-install mime processing. If you don't have root/admin
|
||||
access, this will be needed
|
||||
python3 setup.py install --root ~/test
|
||||
|
||||
Packager's issues
|
||||
------------------
|
||||
There is a MANIFEST.in file to indicate the work needed.
|
||||
To create a source distribution run:
|
||||
|
||||
python setup.py sdist
|
||||
python3 setup.py sdist
|
||||
|
||||
If Gramps is built outside of the source tree in a temporary location (e.g. when
|
||||
packaging for a distribution), the --resourcepath option can be used to specify
|
||||
the path to the installed location of the Gramps resources (e.g. /usr/share):
|
||||
|
||||
python3 setup.py install --resourcepath=/usr/share
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
include AUTHORS
|
||||
include ChangeLog
|
||||
include COPYING
|
||||
include FAQ
|
||||
include Gramps.py
|
||||
|
||||
588
NEWS
588
NEWS
@@ -1,3 +1,571 @@
|
||||
2018-02-09
|
||||
Version 4.2.8
|
||||
* Fix Geography views for bad 'dbstate.is_open()' test
|
||||
|
||||
2018-02-08
|
||||
Version 4.2.7
|
||||
* Fix Export View to CSV when Unicode characters are present
|
||||
* Fix several intl date displayers for missing parameter
|
||||
* DescendantTree report; fix crashes and Title spacing
|
||||
* Fix Book XML handler to deal with unusual characters in Book name
|
||||
* Add support for new genealogy tree report category
|
||||
* Fix Media Preview Gramplet for closed db
|
||||
* Suport FTM 2017 Gedcom tags on import
|
||||
* Fix Person, Family Sidebar Filters to add custom Event types
|
||||
* Fix QuestionDialog display for html like characters in title
|
||||
* Fix FamilyRelationshpType _DATAMAP order to correspond with values
|
||||
* Fix Gedcom import for illegal Gedcom Family Attributes
|
||||
* Fix Gedcom export for bad Hebrew Months
|
||||
* Change INSTALL to replace 'python' with 'python3 for script invokes
|
||||
* Fix CSV importer for place event name using gramps_id
|
||||
* Fix Geography view 'Find' when db is closed
|
||||
* Fix interactive search for exception on click then down arrow
|
||||
* Create where_is utility to locate a binary in the standard places
|
||||
* Fix relationship Graph so Unicode chars on Multiple pages works
|
||||
* Update authors file
|
||||
* Fix Gedcom import for "1 MARR Y" issue
|
||||
* Fix Export Web Family Tree for errors on file write
|
||||
* Fix Citation Editor to Tab out of Confidence ComboBox
|
||||
* Reset the dependencies on the new meta-module
|
||||
* Use online modules
|
||||
* Consolidate Python2 and Python3 meta-modules
|
||||
* Use None as the foreground colour for untagged rows in list views
|
||||
* Fix shading colour in relationship view for dark themes
|
||||
* Fix link colour for dark themes
|
||||
* Fix default foreground colour in list views for dark themes
|
||||
* Fix Undo; crashes due to race in Gtk
|
||||
* Gedcom import with OBJE/FORM URL on event
|
||||
* EOFError [Ran out of input] in Clipboard
|
||||
* Cannot drag & drop textual value via clipboard
|
||||
* Fix 'DbBsddbRead' object has no attribute '_Callback__callback_map'
|
||||
* Reports - Narrated Web Site Failure
|
||||
* Fix link path in gramps-launcher compile instructions
|
||||
* Update translations: fi, de
|
||||
|
||||
2017-08-01
|
||||
Version 4.2.6
|
||||
* Fix HasCitation rule in citation filter sidebar
|
||||
* Fix use of regular expressions
|
||||
* Date Editor had 'Type' and 'Quality' labels swapped
|
||||
* Fix FamilyGroup Report
|
||||
* Fix names not displayed in relationship graph
|
||||
* Fix outdated Bugtracker link in reporting wizard
|
||||
* Fix replacements in Ancestor tree
|
||||
* Fix Default Browser Setting
|
||||
* Fix linking place on OpenStreetMap view
|
||||
* Fix Family Lines Report having unescaped characters
|
||||
* Fix non-local character in DB name (Windows OS)
|
||||
* Fix checking for "event.string" in "treeview_keypress"
|
||||
* Fix invalid February 29th date in Julian dual-dated
|
||||
* Fix Note on CIR when it is attached to a (preferred or alternative) name through the names dialog.
|
||||
* Improve time loading for person selector in census forms
|
||||
* Fix incorrect SoundEx result
|
||||
* Fix Error printing on ancestor tree graphical report
|
||||
* Fix custom filter creation with 'Events occurring on a particular day of the week'
|
||||
* Bug in the Name Editor / Group As
|
||||
* Gramps CSV export of Places did not generate correct Title.
|
||||
* Add custom Family Relations not shown in the filter siderbar
|
||||
* Fix non-textual value on Tag report
|
||||
* Fix 'interface.dont-ask' config key ignored on Note edition
|
||||
* Fix Reorder Relationships dialog
|
||||
* Shrink size of Break Lock (and other QuestionDialogs)
|
||||
* Only selection of Active or Home person if commited
|
||||
* Fix quick search exception when nothing in searched list
|
||||
* Fix problem adding parents
|
||||
* Fix bookmarks keybinding on Mac
|
||||
* Fix failure to load default gramplets if GExiv2 is missing or too old.
|
||||
* Update API doc for place displayer
|
||||
* Add datestrings to Turkish translation
|
||||
* Update translations: cs, de, fr, fi, hu, it, ru, sl, sv, tr
|
||||
|
||||
2016-12-15
|
||||
Version 4.2.5
|
||||
* The configparser is assuming the wrong encoding
|
||||
* Sorting in family tab of narrated web report
|
||||
* Silence remaining PyGIWarning
|
||||
* Sorting of relationships in family tab of narrated web report
|
||||
* Use latest valid date rather than today
|
||||
* Modify endonym handling in place displayer
|
||||
* Fix house number concatenation
|
||||
* Allow merging of families with one or more parents in common
|
||||
* Jump to Gramps ID functionality doesn't work
|
||||
* Ability to search alternate place names when selecting place
|
||||
* Fix clear map action on Geography
|
||||
* Database repair tool always edit all source objects
|
||||
* Database repair tool ignored some objects with tag
|
||||
* "Enclosing" gramplet includes places outside valid date ranges
|
||||
* Fix icon and tooltip in LDS editor
|
||||
* CSV import fails
|
||||
* Fix duplicated Gramps IDs on Gedcom import
|
||||
* Unexpected error Preferences > Dates > Markup for invalid date format
|
||||
* Fix Import Vcard, can create multiple surnames with all selected as 'Primary'
|
||||
* Fix Gedcom import in some alternate languages; improper date parsing
|
||||
* Export options 'Preview' buttons create hidden quickreport
|
||||
* Alignment radio buttons in the style editor do not work
|
||||
* Select Place search & Source/Citation hierarchy should NOT be expanded
|
||||
* Tweak improvement on Tag editor
|
||||
* Support for Windows Python3 pythonw.exe
|
||||
* Wrong parsing Numeric date format for cs_CZ locale
|
||||
* Fix Norwegian relationship calculator
|
||||
* Fix Icelandic and German translations
|
||||
* Update translations: cs, de, fi, fr, hu, is, nb, ru
|
||||
|
||||
2016-09-04
|
||||
Version 4.2.4
|
||||
* fixes for the PHON, FAX, EMAIL and WWW Gedcom tags to support Gedcom v5.5.1
|
||||
* use more relative import
|
||||
* Support for FTM and others Custom Gedcom Event Tags on import
|
||||
* fix '_deeprelationshippath' filter rule
|
||||
* Narrativeweb: some dates are incorrect in tar archive.
|
||||
* MacOS: Update graphviz to 2.38 and change to a binary launcher in app bundles.
|
||||
* Gramps crashes when closed while exporting
|
||||
* Some events are not shown in familymaps page.
|
||||
* Remove old debug bloc on place selection.
|
||||
* Add GUI and CLI config option to allow easy setting
|
||||
* Chinese characters are not rendered properly in pdf reports
|
||||
* Support v5.5.1 OBJE/FORM/MEDI tag on embedded OBJE
|
||||
* Sorting of Sources on gedcom
|
||||
* Change "class xxx(object)" to "class xxx"
|
||||
* Use "with open" instead of "try: except:"
|
||||
* Change "raise NotImplemented" to "raise NotImplementedError()"
|
||||
* Add new argument to IsEnclosedByRule
|
||||
* Narrativeweb: place title must agree the references.place-auto configuration
|
||||
* Improvements on CSV file format support
|
||||
* update Finnish holidays
|
||||
* Some strings in tools and report dialogs will not translate
|
||||
* Gedcom import improvements in media area to support v5.5.1 and FTM
|
||||
* Trailing whitespace
|
||||
* Gedcom import of FTM .ged file containing _LINK tags not supported
|
||||
* Change pycairo-python3 to pycairo.
|
||||
* pycairo for python2 is now py2cairo.
|
||||
* Remove pango modules from bundle, pango no longer uses them.
|
||||
* Gedcom import loses spaces in text fields from FTM
|
||||
* Gedcom import of FTM file containing _PHOTO tags
|
||||
* Missed self.photo initializer
|
||||
* Attempting to select an "Available item" for the Book Report gives an error
|
||||
* Fix for either valid or invalid FTM Gedcom
|
||||
* Gedcom import of FTM file with OCCU record crashes import
|
||||
* crash - 'NoneType' object has no attribute 'get_child_ref_list'
|
||||
* Family Page maps are non-functional in Narrative Web report
|
||||
* Gedcom import loses spaces in text fields from FTM
|
||||
* String not translated in geoplaces
|
||||
* Descendant Report does not recognise auto. place title generation
|
||||
* Translated text will not be printed in the program
|
||||
* Geography: Attempting to print crashes (add parent to dialog)
|
||||
* GEDCOM doesn't accept CR as a line terminator
|
||||
* Wrong Numeric date format for cs_CZ locale
|
||||
* Narrativeweb: inconsistent & incomplete display of place hierarchy labels
|
||||
* Narratedweb: surname listing errors for people with multiple partners
|
||||
* In "Verify" people w/ death event w/o date are not thought dead
|
||||
* While starting gramps, it fails to pop up "tips of the day"
|
||||
* GEDCOM import in CLI mode with .ged file containing ANSEL encoding tries to pop up gui
|
||||
* fix merge conflict
|
||||
* Use first matching name when generating place titles
|
||||
* GEDCOM import with media files that have no path fails
|
||||
* [Geography] Geoclose and mother handle
|
||||
* place names empty if Gedcom ADDR record contains no street
|
||||
* Tidy up place configuration options
|
||||
* Use CSS to fade background colour in ValidatableMaskedEntry
|
||||
* crash on GEDCOM import with empty _AKA lines
|
||||
* Add inclusive option to IsEnclosedBy rule
|
||||
* Saving/closing new person window with Alt-o does not find gender
|
||||
* Fix to allow deferred translation of place type
|
||||
* Include all place types in place report
|
||||
* Allow place selection both individually and by filter on textual report
|
||||
* Expand tree in selectors automatically
|
||||
* Fix Encloses gramplet to display correct place references
|
||||
* Update for appdata stuff
|
||||
* UnboundLocalError on ODF doc backend
|
||||
* Media Preview: wrong frame
|
||||
* fix signals
|
||||
* GEDCOM import PLAC:FORM in local mode doesn't work
|
||||
* fix empty Place Alternate Names on import
|
||||
* Merge unit test for PlaceCheck not working correctly
|
||||
* GEDCOM import some Place Names & Titles are blank
|
||||
* GEDCOM import PLAC or ADDR attached Notes etc. are lost
|
||||
* Gramps not appearing in Gnome Software
|
||||
* fix broken GEDCOM import PLAC:FORM handling
|
||||
* Place Alt Names gets duplicated entries
|
||||
* Multiple GEDCOM imports creates duplicate event IDs
|
||||
* The place page in webreport is complete mess
|
||||
* Gallery tab of Source view does not display .ods files
|
||||
* Narrated Web report - Individual sort order not correct on the Surnames tab
|
||||
* Specify required GtkSpell and GExiv2 version
|
||||
* Narrated web report link to thumbnails is broken on certain pages
|
||||
* Narrated Web report - Individual page sort order has changed
|
||||
* Gramps reports that it can't find dictionaries.
|
||||
* Turns out it was really that enchant couldn't find its backend because an environment variable wasn't set.
|
||||
* Update translations: cs, da, de, fi, fr, hu, pt_BR, ru, sl
|
||||
|
||||
2016-04-10
|
||||
Version 4.2.3
|
||||
* Creation of the "graphic calendar report" failed
|
||||
* Fix "TypeError: 'tuple' object does not support item assignment
|
||||
* Fix experienced an unexpected error
|
||||
* Unable to build narrated web site
|
||||
* [NarrativeWeb report] Places index and Media index are incorrectly sorted
|
||||
* Error when trying to create narrative report (residence event)
|
||||
* Fix filter set by default on selector, 'Show all' button
|
||||
* Detailed Ancestors Report has ? for locations when [private data is excluded]
|
||||
* Age in the event family view column is wrong.
|
||||
* Crash when dragging multiple media items to clipboard
|
||||
* vCal Export File format invalid
|
||||
* Error occurs for Complete Individual Report -- complete database
|
||||
* Narrated Web Site Report: places page is no longer sorted alphabetically
|
||||
* Narrative web: html elements emitted in different order
|
||||
* Narrative web: "errno: 1, operation is not permitted" when creating archive.
|
||||
* Narrative Web report further stops in error.
|
||||
* Fix multiple lines for firstname on gramps XML file via import or export
|
||||
* fix scrolling in persons view after typing some letters
|
||||
* Location on geography view could not convert string to float
|
||||
* setup.py: make typeout more accurate
|
||||
* Searching in people view when surnames are collapsed
|
||||
* Fix error when changing database in new locations gramplets
|
||||
* Error loading Participants add-on in French locale
|
||||
* Restores setting the stdout encoding to sys.getdefaultencoding() for Python3
|
||||
* Fix comment about getting the right encoding for stdout.
|
||||
* Date format does not match system.
|
||||
* Make US English a special-case locale, where en_GB is the default for english based locales
|
||||
* Enhance the Locations gramplet
|
||||
* New "Encloses" gramplet to the display places that the active place encloses
|
||||
* Individuals with incomplete names, not updated when name completed
|
||||
* Children gramplet in Family view does not get updated when a birth/death events are added to a child
|
||||
* Non-image media objects don't appear in the main window gallery.
|
||||
* Pressing tab stops at element in gui places
|
||||
* Double-clicking on a source in the citation gramplet causes exception
|
||||
* "Find text in record" filter crash
|
||||
* Fix vCard Export
|
||||
* Notes used in the "To Do" gramplet are found by the Remove Unused Objects tool
|
||||
* Unable to select Unicode
|
||||
* Cannot import gedcom generated by RootsMagic custom place details ignoring PlaceName()
|
||||
* Fix people sorted by surname view
|
||||
* Complete Report about person (whole database) - PDF - crash
|
||||
* Update for travis
|
||||
* Only consider the values of LC_ALL, LANG, and LANGUAGE, in that order, when choosing the default locale.
|
||||
* New Icelandic date and relationships handlers
|
||||
* Fix Finnish translation in keywords of desktop entry
|
||||
* Update translations: cs, de, el, fi, fr, hu, is, it, ru, sl, sv, uk
|
||||
|
||||
2016-01-06
|
||||
Version 4.2.2
|
||||
* "Show all" checkbox of "Select Family" window not unchecked when the filter is cleared
|
||||
* Name of user defined filter is not shown
|
||||
* ErrorDialog and GtkDialog mapped without a transient parent
|
||||
* 'Find' is broken when used in the Family selector
|
||||
* Fix default selection in selectors
|
||||
* Comment currently-unused bogus wiki URL pointers
|
||||
* Fix counter for filtered entries and indentation on TreeBaseModel
|
||||
* Faulty headline in start up screen
|
||||
* Check that gramplet is in notebook before setting tab label
|
||||
* Fix creation of focus change events
|
||||
* Interactivesearch gives "TypeError: unorderable types: str() < NoneType()"
|
||||
* Put tag selection list in alphabetical order
|
||||
* Remove redundant code
|
||||
* Fix delete error in undoable entry widget
|
||||
* Fix deprecation warning
|
||||
* Re-enable selection in MultiTreeView on a grab_broken event
|
||||
* Add validation to gender field
|
||||
* Unhandled AttributeError when db.get_tag_from_handle returns None
|
||||
* ReferencedBySelectionProxy can forget some referenced tags
|
||||
* Remove encoding on stdout and stderr
|
||||
* Handle citation objects in glocale.trans_objclass
|
||||
* Locality data in address was not imported
|
||||
* Don't check SSL certs when fetching addons
|
||||
* Catch urlopen TypeError when context arg isn't supported
|
||||
* Fix undefined variable error
|
||||
* Can not download new or updated add-ons
|
||||
* ValueError: underlying buffer has been detached
|
||||
* LaTeX backend crashes
|
||||
* Geography: performance issue due to bad initialization and performance issue when selecting the events or places views.
|
||||
* Narrated Web Site Report: html elements emitted in different order
|
||||
* Unused *_init.jpg are created in the narrated website
|
||||
* Some media files are not exported to the NAVWEB report
|
||||
* Narrative web report: add author to citations
|
||||
* TypeError: unorderable types: EventRef() < EventRef(), events list and family list are differents between two reports
|
||||
* Permission denied: change mtime to origin instead of destination
|
||||
* Thumbnails html file missing in the narrative web
|
||||
* Narrativeweb: Place title based on current date not that of the event
|
||||
* Webcal: make the month name clickable in the year overview page
|
||||
* 'Narrative' word not translatable
|
||||
* 'Unknown' spouse uses an harcoded string name on Simple Descendants textual report
|
||||
* Father/mother's age attributes are not translated on reports
|
||||
* Improve Russian date handler and unittests
|
||||
* Mars month instead of Marzec on Polish locale (Date Editor)
|
||||
* Translations update: cs, de, fr, fi, nl, pl, ru, sv
|
||||
|
||||
2015-10-12
|
||||
Version 4.2.1,
|
||||
* Support for Retina and HiDPI Display, added 24px icons
|
||||
* Fix verification tool with "Estimate missing or inexact dates"
|
||||
* Fix missing link in hourglass graph report
|
||||
* Sort custom place types in editors
|
||||
* Allow Easter calculation with python3
|
||||
* Fix crash on Descendants-detailed report
|
||||
* FanChartDescendants View should at least have 2 generations
|
||||
* Allow hyphenated gramps-id in Graphviz reports
|
||||
* Complete Individual Report fails to run
|
||||
* Fix broken wiki help links
|
||||
* Set TextOption widget to expand vertically
|
||||
* Unused Object Dialog box too small
|
||||
* Short cut keys does not work in 'Change Event Types' dialog
|
||||
* Update some Tips of the day
|
||||
* Error when extracting place names
|
||||
* Custom filters for note text repaired
|
||||
* Fix Pedigreeview crash when selecting Compact view
|
||||
* Set "visable_window" in GtkEventBox to fix transparency
|
||||
* Faster scrolling
|
||||
** cache database access for column values
|
||||
** cache do_get_path lookups
|
||||
** speed up load access on treeviews with no filters
|
||||
** new LRU size of 1k (was 250)
|
||||
** use cache in do_get_path from siblings
|
||||
* Avoid using person-centric date matching for places
|
||||
* Use place title as default name in GEDCOM import
|
||||
* Ensure place names are not empty after upgrade
|
||||
* Fix proxy to include all referenced place objects
|
||||
* Fix bug that prevented any addons being loaded onto the Mac version
|
||||
* Remove copy button from family tree manager
|
||||
* Consistency for name fields on Person Editor
|
||||
* [Geography] Place.set_name(name) requires a PlaceName()
|
||||
* [Geography] Fix and improvements on place selection
|
||||
* Limit problems with existing selection in media reference editor
|
||||
* Stability fixes on Mac port
|
||||
* Mac port localization crash with non-standard locale (e.g. en_IT).
|
||||
* Fix color on history
|
||||
* Fix countries selector for holidays
|
||||
* Fix missing markups into textual reports
|
||||
* All sidebars with Types now show custom types in combo list
|
||||
* [New] Added Places to CSV import/export
|
||||
* Some fixes on installer (setup.py)
|
||||
* Various improvements on gen.plug.utils
|
||||
* Fix graph reports [in Greek locale]
|
||||
* New date handler for Hungarian locale
|
||||
* Updated translations : cs, de, el, en_GB, fi, fr, hu, is, sv
|
||||
|
||||
2015-08-02
|
||||
Version 4.2.0,
|
||||
* New date and language fields on place name
|
||||
* Review on GtkBuilder, fix some Gtk3 warnings and move from deprecated methods
|
||||
* Change icons and buttons handling methods
|
||||
* Enhanced Place Editor and new Place Name editor
|
||||
* New widget: use own interactive-search
|
||||
* Ability to import kml data into Geography views
|
||||
* Enhancement for removing multiple selected items from Views (action group)
|
||||
* Add drag support on more Views, Selectors and Editors
|
||||
* Add right-click "Copy all" to ListModel and all QuickTables
|
||||
* Review Alternate Place handling and edition
|
||||
* New 'Place' configuration keys set by user (settings)
|
||||
* New filter rule: is enclosed by
|
||||
* Consistency on Privacy option for reports
|
||||
* Consistency on "Name-format" options for reports
|
||||
* Add DeferredFilter class (a subclass of GenericFilter)
|
||||
* New textual Report: Links on Notes
|
||||
* Fix alphabetic index and toc bug in books
|
||||
* Enhancements on Style Editor
|
||||
* Enhancements on End Notes into textual reports
|
||||
* Changes on Individuals complete textual report
|
||||
* Changes on Ancestors Tree draw report: Include Siblings
|
||||
* Add name-format option, and deferred translation on Records report
|
||||
* Add deferred translation on Timeline draw report
|
||||
* Enable attributes gramplet on Source and Citation Views
|
||||
* New place locations gramplet
|
||||
* Optimizations around index, Flat and TreeView models
|
||||
* Enhanced samples files
|
||||
* All importers return now an ImportInfo object
|
||||
* Experimental gwplus (geneweb) import file format support
|
||||
* Remove experimental HTML renderer view
|
||||
* New test scripts
|
||||
* New Date handler for Japanese
|
||||
* Review on Slovenian and Czech Date Handlers
|
||||
* Implement both "traditional" and "simplfied" Chinese (translations and dates)
|
||||
* Serbian review
|
||||
|
||||
2015-05-01
|
||||
Version 4.1.3, "Thou shalt not count to five", a maintenance release.
|
||||
* Fix db upgrade failure
|
||||
* GtkDialog mapped without a transient parent
|
||||
* [Gedcom} SUBN and SUBM record handling
|
||||
* [Gedcom] Import/export round trip causes lost information
|
||||
* [Gedcom] Entering a witness to an event such as marriage might be ignored
|
||||
* [Gedcom] Gramps can't import estim. date period exported by itself
|
||||
* [Gedcom] 1/4 and 1/2 ANSEL characters not supported on importing ANSEL
|
||||
* [Gedcom] Importing file containing multibyte UTF-8 characters fails
|
||||
* [Gedcom] Import fails for ANSI file under python 3
|
||||
* [Gedcom] Failure importing ANSEL encoded gedcom file.
|
||||
* [Gedcom] Characters ignored on a Gedcom encoded ANSI (cp1252 West Europe, USA)
|
||||
* [Gedcom] NameError in importer
|
||||
* [Gedcom] Event address is lost on import, i.e. disconnected from event
|
||||
* Crash on geneweb export with python3
|
||||
* GuiColorOption missing avail-changed event handler
|
||||
* Bad generation of [timeline report] ODT files since 4.0.0
|
||||
* Fix bad handle in explanation note for unknown event
|
||||
* Fix spurious generation of empty 'Alternative Name' in place.merge()
|
||||
* Support creating directories in various scenarios
|
||||
* Attempting to add a bookmark causes an error
|
||||
* Long series of "unhandled exception" popup boxes while doing a check & repair
|
||||
* Crash when trying to link existing place as an enclosing place using P0001 number
|
||||
* HTML view fails to load
|
||||
* Relationship Graph crashes
|
||||
* Python3 needs new_subpixbuf not subpixbuf
|
||||
* Regression: running gramps from crontab fails
|
||||
* tag_map is not initialized
|
||||
* Some labels now fit better on citations sidebar filter
|
||||
* Event columns in web narrative are too narrow
|
||||
* Problem by start program (launcher)
|
||||
* Translation string missing in Not Related tool for help and close button
|
||||
* Date format month/year is not well reported at editing time [in Italian]
|
||||
* Fix unknown gender relationships handler for the french locale
|
||||
* Fix a handle type bug on sidebar filter
|
||||
* Tidy up About dialog
|
||||
* Cleanup on some man files
|
||||
* Convert some remaining unicode literals
|
||||
* Fix mac menubar setting
|
||||
* Enable python3 to run po/update_po.py
|
||||
* Updated translations: cs, de, fr, is, nl
|
||||
|
||||
2015-02-28
|
||||
Version 4.1.2, "That's no ordinary rabbit", a maintenance release.
|
||||
* Error converting python2 utf-8 strings to python3 str when loading data from database
|
||||
* Removing a parent place from a place leaves a dangling reference
|
||||
* Error during checking the database
|
||||
* Stubborn blank space in database won't be removed, fix removing rows in flat list views
|
||||
* Database upgrade fails if default media path is not set
|
||||
* Error converting database after upgrade to Gramps 4.1.1
|
||||
* Error in a single place within the places section
|
||||
* Entries from the add-or-choose selector of Place/Source/Media/Note cannot be dragged
|
||||
* Enclosing places tab should work like other similar tabs, new place reference editor
|
||||
* Association editor refuses dropped persons
|
||||
* Error on opening twice an object from clipboard
|
||||
* Incorrect spacing in export assistant file chooser
|
||||
* New Event types are saved as a disordered list
|
||||
* Always display main participants
|
||||
* Place titles can now be generated on-the-fly by a place displayer, default is still to use the place title field
|
||||
* GEDCOM import of embedded notes attached to media does not work
|
||||
* Crash on Ancestry.com .ged import; consistent.
|
||||
* Errors handling owner/submitter information in GEDCOM files.
|
||||
Only import researcher from GEDCOM or XML if the family tree was originally empty.
|
||||
* GEDCOM export does not export media attached to citations.
|
||||
* The fanchart view crashes if max generation is set to 1 away.
|
||||
* Sidebar Filters do not match placetypes in new placeview, two new filter rules (HasTitle, HasData)
|
||||
* Fix bug when family has no parents
|
||||
* Fix bad handle in explanation note for unknown event
|
||||
* Some labels now fit better on citations sidebar filter
|
||||
* Views in Geography should not always use the last option set by the user
|
||||
* Request for keyboard-controlled zoom on Geography view
|
||||
* Error geography view - Displaying main menu
|
||||
* Configure screen needs a file selector to select directory for "offline mode" files
|
||||
* Filter panel on geography view displays improperly
|
||||
* Detailed descendant report crashes, bibliography (citations)
|
||||
* Can't disable box shadow in SVG descendant tree
|
||||
* Descendant tree graphical report, syntax error in svg output
|
||||
* Regression: Complete Individual report has partially-untranslated output
|
||||
* Events Page in Narrative Report not working
|
||||
* Gramps freeze after defining a report style with German cm values
|
||||
* Various problems with docgen.TextDoc.add_media_object
|
||||
* Report event attribute name is not translated
|
||||
* Records Gramplet uses wrong text
|
||||
* Closing detached gramplet causes python to crash
|
||||
* Cannot reduce size of gramplets detached from a gramplet bar
|
||||
* Gramplets don't fill window when detached from dashboard
|
||||
* ImageMetadata doesn't show metadata
|
||||
* typo on GLib call, used by an addon only
|
||||
* Fix error setting gramplet tab label
|
||||
* Check for active person in session log gramplet
|
||||
* Spurious spaces in CLI List Family Trees, tab delimited output.
|
||||
Print statements changed to assemble the whole line before output.
|
||||
* Gtk3 warning and custom undoableentry widget, see bugzilla_id 644927
|
||||
* Warnings: deprecated Gtk properties and errors loading theme icon.
|
||||
Fix: database manager dialog is inconsistent for older gtk+3 versions.
|
||||
Warnings: deprecated Gtk properties and errors loading theme icon.
|
||||
Fix: Error loading theme icon 'gtk-apply'
|
||||
* gramps fails to start with gtk+-3.13.3
|
||||
* Places in data.gramps are not in the new Place hierarchy
|
||||
* Upgrade the version of some dependencies for Mac OS and Windows OS.
|
||||
* Keywords entry in gramps.desktop does not work
|
||||
* 'Available Gramps Updates for Addons' window not on top
|
||||
* Some text not translatable in context menu fancharts
|
||||
* Fix for Unit test
|
||||
* date inflections in _datehandler.py, update for Ukrainian, Russian, Croatian
|
||||
* Better support for Serbian and Turkish locales
|
||||
* New translation: Icelandic
|
||||
* Re-enable Turkish support after a major review. Thank you Uğur.
|
||||
* Updated translations: cs, de, eo, fi, fr, hr, hu, it, nb, nn, ru, sk, sr, sv, uk, zh_CN
|
||||
|
||||
2014-10-24
|
||||
Version 4.1.1, "MachineThatGoes...Ping!", a maintenance release.
|
||||
* Fix custom place types in the place editor
|
||||
* Allow place type combobox to receive focus.
|
||||
* Store custom place types in the metadata table
|
||||
* Fix place type for places without a main location
|
||||
* Fix bug adding parent places to a new place
|
||||
* Prevent user creating a cycle in the place hierarchy
|
||||
* Avoid infinite loop when place cycle encountered
|
||||
* Prevent creation of a place cycle when merging
|
||||
* Fix error when no place is selected
|
||||
* Check that a place has been selected when saving.
|
||||
* Use the standard place selection widget to be consistent.
|
||||
* Add a new Top Level place through the Place Reference Editor
|
||||
* Fix backlinks code in place report
|
||||
* Backlinks for places can now also be places as well as events.
|
||||
* Fix check and repair tool for empty placerefs
|
||||
* Update location utilities to work with proxies
|
||||
* Place report does not run
|
||||
* Update place details gramplet
|
||||
* Locations are now displayed in a new separate gramplet.
|
||||
* Add check for empty handle in gramplets
|
||||
* Check DB lock on the recent opened trees list
|
||||
* Sidebarfilter gramplet does not fit well into People, Events or Media views
|
||||
* Fix new event default type considering existing events with *default* role
|
||||
* Rebuild secondary indexes after database upgrade
|
||||
* Importing gedcom files containing multibyte UTF-8 characters fails
|
||||
* Ahnentafel Report did not use Christening Date if no Birth Date
|
||||
* [Narweb:] Missing webpage for media under some circumstances
|
||||
* Fix narrated web report with gendex option enabled
|
||||
* Tweak to "default" CSS choice for the narrated web report
|
||||
* Invalid link for Merge citation Help button
|
||||
* Fix 'todo' gramplet
|
||||
* Fix path when using drag & drop to add media
|
||||
* Limit the number of generations displayed in the ancestor gramplet
|
||||
* Export of a subset of the tree failed
|
||||
* Fix issues in python3, and bytes-string mismatch with ICU
|
||||
* Fix url/uri handling with non-ascii characters under linux and mac
|
||||
* Fix name format on graphical reports
|
||||
* Fix name format on textual reports
|
||||
* Better GUI support for embeded custom attributes list on media object
|
||||
* Better keys for search under linux shells (.desktop file)
|
||||
* 'Unknown' person in detailed ancestor report can not be translated
|
||||
* Translations don't show in many labels
|
||||
* Ensure python text domain gets the right encoding.
|
||||
* Translate some punctuation marks
|
||||
* Various fixes around Geography and osmgpsmap
|
||||
* Allow gramplets to be displayed in the dashboard only
|
||||
* Update FSF address
|
||||
* Add Arabic-script, Islamic-date, Thai script, Married Name and more dates examples
|
||||
* Fix on czech date handler for calculated and estimated dates
|
||||
* Enhance Serbian date handler to handle Cyrillic dates
|
||||
* Simplify Canadian Ash Wednesday holiday
|
||||
* Re-enable Esperanto support (for non-Windows OS only) after a large review
|
||||
* New translation: Serbian
|
||||
* Various fixes in German and Czech
|
||||
* Updated translations: ar, cs, de, fi, fr, it, sv
|
||||
|
||||
2014-06-15
|
||||
Version 4.1.0, the "Name go in book", new major release.
|
||||
* GEP 006: Better Place handling
|
||||
* New Tags support on Event, Place, Repository, Source, and Citation
|
||||
* Source/Citation Data becomes Attributes
|
||||
* Add optional support for checksum on Media object
|
||||
* New place hierarchies model
|
||||
* By default, you can choose navigator modes with a drop down.
|
||||
* New Place editor
|
||||
* Enhanced MediaReference Editor
|
||||
* Some debug tools move to new gramplets
|
||||
* Full Python 3 support
|
||||
* New functions and widgets related to Place and Media selections
|
||||
* Enhancements on to_struct()
|
||||
* New methods on Date handlers
|
||||
* Better support on translation for inflection rules
|
||||
|
||||
2014-05-22
|
||||
Version 4.0.4, "Not the comfy chair", a maintenance release.
|
||||
* Upgrade to db version 17 fails in Python 3 due to use of iteritems
|
||||
@@ -151,8 +719,8 @@ Version 3.4.4 of Gramps! "The Ministry of Silly Names", a maintenance release.
|
||||
* fix annoying errors on navigation related to citations gramplet and tag object.
|
||||
* listing the Family Trees can corrupt them.
|
||||
* various fix around handling Gedcom file format
|
||||
* fix citations and sources import on ProGen format
|
||||
* better date handling and better alternate translation support on some textual reports according to locale under windows
|
||||
* fix citations and sources import on ProGen format
|
||||
* better date handling and better alternate translation support on some textual reports according to locale under windows
|
||||
* avoid Errors when setting wrong value as markup for invalid dates (Preferences)
|
||||
* fix paragraph layout on PDF format or print output
|
||||
* New: New-Zealand holidays
|
||||
@@ -170,16 +738,16 @@ Version 3.4.3 of Gramps! "Whenever life gets you down, Mrs. Brown", a maintenanc
|
||||
* Sorting (both in the main display window, and particularly in Narrative Web output) now uses PyICU (if that module is available). Inclusion of PyICU is 'strongly recommended'. This resolves a number of bugs particularly related to sorting of non-Latin characters, and sorting on MS Windows and Mac OS X. Some changes have been made in Narrative Web to support contractions for alphabetic indices.
|
||||
* The automatic Addon checking and download now works once again (the location used in Gramps 3.4.2 and before had been changed, so the the automatic process was no longer working).
|
||||
* Import from Pro-Gen has been updated (at last) to take account of the change to Citations (in 3.4.0)
|
||||
* Import and Export of address fields in GEDCOM has been improved so that the round-trip works properly.
|
||||
* Import and Export of address fields in GEDCOM has been improved so that the round-trip works properly.
|
||||
* GEDCOM Repositories not imported correctly from FTM for Windows and Heredis.
|
||||
* Fixes to a number of errors in filtering notes.
|
||||
* Fix some errors in determining whether someone is alive (e.g. for filtering out alive people).
|
||||
* Make availability of GraphViz settings depend on output format
|
||||
* Improve the descriptions and tooltip for GraphViz aspect ratio option
|
||||
* Make availability of Graphviz settings depend on output format
|
||||
* Improve the descriptions and tooltip for Graphviz aspect ratio option
|
||||
* Fixed update problems with citation bottombar gramplet (bug #6336)
|
||||
* Fixed Open Document Text output in Book report (bug #6457)
|
||||
* A number of changes to Narrative Web:
|
||||
** Media objects attached to Marriage events and Sources are not included in Narrative Web Site
|
||||
** Media objects attached to Marriage events and Sources are not included in Narrative Web Site
|
||||
** restructure the families index so families are indexed under both spouses, and the family name is normalised
|
||||
** separate out Families section in individual and families pages so individual page links to the family page and family page links to both people
|
||||
** normalise links to families so the link is only displayed if the family page is present, and the gid is included when appropriate
|
||||
@@ -197,7 +765,7 @@ Version 3.4.3 of Gramps! "Whenever life gets you down, Mrs. Brown", a maintenanc
|
||||
** Implemented a generalised back reference function to display the 'References' section of all pages. This recursively displays references till one is found for which a page exists.
|
||||
** Removed list of people and families from heading of the event pages as these are now in the 'References' section.
|
||||
** Fixed bug "0005968: Narrated Web Site not copying Source Citations files such as jpg or pdf docs to web site
|
||||
** Fixed bug "0005946 GRAMPS failed to insert jpeg image into proper place for an event" by displaying a thumbnail for citation media in the 'Source References' section (with a link to the media page)
|
||||
** Fixed bug "0005946 GRAMPS failed to insert jpeg image into proper place for an event" by displaying a thumbnail for citation media in the 'Source References' section (with a link to the media page)
|
||||
** Tidy up media pages - remove unused parameters, use list of media items generated in first pass. Should fix bugs 2365, 5905 and 6009.
|
||||
** Tidy up sources pages - fix numbering of repositories, remove unused parameters, fix title of individual source pages
|
||||
** Bug: reset NarrWeb navigation menu layout when style sheet doesn't support it
|
||||
@@ -205,7 +773,7 @@ Version 3.4.3 of Gramps! "Whenever life gets you down, Mrs. Brown", a maintenanc
|
||||
** Fix option to suppress Gramps ID (bug #6237)
|
||||
* a number of technical changes to Narrative Web
|
||||
** Removed a lot of redundant code and parameters (mainly connected with the old way of determining the objects to be included in the report).
|
||||
** Movement of some large chunks of code within the source file and some initial work towards GEPS 022: Narrative Website Refactor. Functionality should be unchanged.
|
||||
** Movement of some large chunks of code within the source file and some initial work towards GEPS 022: Narrative Website Refactor. Functionality should be unchanged.
|
||||
** Moved routines for calculating objects to be output so they can be part of default list building classes.
|
||||
* Various updated translations: da, de, es, fr, it, nb, nl, pt_BR, pt_PT, sv, uk
|
||||
|
||||
@@ -397,7 +965,7 @@ Version 3.1.3 -- the "What name?" release.
|
||||
2009-06-06
|
||||
Version 3.1.2 -- the "Skip the impersonations" release.
|
||||
* Contains translation updates and small bug fixes. No new features.
|
||||
* ca, cs, de, fr, he, it, nb, nl, pl, pt_br, ru, sk, sv,
|
||||
* ca, cs, de, fr, he, it, nb, nl, pl, pt_br, ru, sk, sv,
|
||||
* fixes a failure in 'Check & Repair Database'
|
||||
* fixes to Gramplets
|
||||
* fixes to CLI regressions
|
||||
@@ -510,7 +1078,7 @@ Version 2.2.5 -- the "Now go away or I shall taunt you a second time" release
|
||||
|
||||
Version 2.2.4 -- the "When you're chewing on life's gristle, Don't grumble, give a whistle" release
|
||||
* Improved handling of readonly files
|
||||
* Enhanced parsing of longitute and latitude and mapping
|
||||
* Enhanced parsing of longitute and latitude and mapping
|
||||
(Benny Malengier/Zsolt Foldvari)
|
||||
* Check and repair improvements
|
||||
* Reference map rebuild tool
|
||||
|
||||
11
README
11
README
@@ -7,7 +7,7 @@ Requirements
|
||||
The following packages *MUST* be installed in order for Gramps to work:
|
||||
Python 3.2 or greater
|
||||
GTK 3.10 or greater
|
||||
pygobject 3.3.2 or greater
|
||||
pygobject 3.12 or greater
|
||||
cairo, pango, pangocairo with introspection bindings (the gi packages)
|
||||
librsvg2 (svg icon view)
|
||||
xdg-utils
|
||||
@@ -28,9 +28,9 @@ The following packages are *STRONGLY RECOMMENDED* to be installed:
|
||||
It may be osmgpsmap, osm-gps-map, or python-osmgpsmap,
|
||||
but the Python bindings for this must also be present.
|
||||
Without this the GeoView will not be active, see
|
||||
http://gramps-project.org/wiki/index.php?title=Gramps_4.1_Wiki_Manual_-_Main_Window#Geography_Category
|
||||
https://gramps-project.org/wiki/index.php?title=Gramps_4.2_Wiki_Manual_-_Categories#Geography_Category
|
||||
|
||||
GraphViz Enable creation of graphs using GraphViz engine.
|
||||
Graphviz Enable creation of graphs using Graphviz engine.
|
||||
Without this, three reports cannot be run.
|
||||
Obtain it from: http://www.graphviz.org
|
||||
|
||||
@@ -42,7 +42,8 @@ The following packages are *STRONGLY RECOMMENDED* to be installed:
|
||||
sorting is done through built-in libraries. PyICU is
|
||||
fairly widely available through the package managers of
|
||||
distributions. See http://pyicu.osafoundation.org/
|
||||
(These are Python bindings for the ICU package.)
|
||||
(These are Python bindings for the ICU package.
|
||||
https://pypi.python.org/pypi/PyICU/)
|
||||
|
||||
The following packages are optional
|
||||
|
||||
@@ -52,7 +53,7 @@ The following packages are optional
|
||||
|
||||
rcs The GNU Revision Control System (RCS) can be used to manage
|
||||
multiple revisions of your family trees. See info at
|
||||
http://www.gramps-project.org/wiki/index.php?title=Gramps_4.1_Wiki_Manual_-_Manage_Family_Trees#Archiving_a_Family_Tree
|
||||
https://gramps-project.org/wiki/index.php?title=Gramps_4.2_Wiki_Manual_-_Manage_Family_Trees#Archiving_a_Family_Tree
|
||||
Only rcs is needed, NO python bindings are required
|
||||
|
||||
PIL Python Image Library is needed to crop
|
||||
|
||||
@@ -1,36 +1,13 @@
|
||||
$Id$
|
||||
Major enhancements in Gramps 4.2.0:
|
||||
|
||||
UNSTABLE Gramps 4.0.0 Beta2 release.
|
||||
* GEP 36: GEPS 036: Extended Alternative Place Name Handling:
|
||||
https://gramps-project.org/wiki/index.php?title=GEPS_036:_Extended_Alternative_Place_Name_Handling
|
||||
|
||||
This is a technology preview to allow distribution packagers (and plugin
|
||||
writers) to update their scripts (and plugins). This release is not
|
||||
production ready, so only use it for testing!
|
||||
* GEP interactive search: own interactive-search box.
|
||||
|
||||
It is recommended that Gramps 4.0.0 be used with python 2.7 since many
|
||||
dependent packages do not yet have python 3 versions. A determined person
|
||||
can probably download their sources and build them, however.
|
||||
|
||||
The dependencies for Gramps 4.0.0 are _completely_ different than 3.4 due
|
||||
to the switch to GObject introspection, and the removal of autotools. So
|
||||
only install 4.0.0 if you are certain you can obtain the dependencies,
|
||||
see README and INSTALL.
|
||||
|
||||
For linux, in Ubuntu 12.10 you can install 4.0.0, but you will need to
|
||||
compile and install osmgpsmap manually to have the maps working (see
|
||||
http://www.gramps-project.org/wiki/index.php?title=GEPS_029:_GTK3-GObject_introspection_Conversion#OsmGpsMap_for_Geography )
|
||||
|
||||
|
||||
Major enhancements in Gramps 4.0.0:
|
||||
|
||||
* GEP 8: code reorganization: http://www.gramps-project.org/wiki/index.php?title=GEPS_008:_File_Organization
|
||||
|
||||
* GEP 26: Replace make: http://www.gramps-project.org/wiki/index.php?title=GEPS_026:_Replace_%27make%27_for_Gramps_build
|
||||
|
||||
* GEP 29: Gtk 3 :http://www.gramps-project.org/wiki/index.php?title=GEPS_029:_GTK3-GObject_introspection_Conversion
|
||||
|
||||
* GEP 31: Python 3 support: http://www.gramps-project.org/wiki/index.php?title=GEPS_031:_Python_3_support
|
||||
* Speedup on Tree and Flat Views
|
||||
|
||||
More info in the manual
|
||||
http://www.gramps-project.org/wiki/index.php?title=Gramps_4.0_Wiki_Manual_-_What%27s_new%3F
|
||||
http://www.gramps-project.org/wiki/index.php?title=Gramps_4.2_Wiki_Manual_-_What%27s_new%3F
|
||||
|
||||
Everybody is invited to update the manual to make it current!
|
||||
|
||||
@@ -94,6 +94,9 @@
|
||||
<author title="contributor">
|
||||
Nick Hall <<html:a href="mailto:nick__hall@hotmail.com">nick__hall@hotmail.com</html:a>>
|
||||
</author>
|
||||
<author title="contributor">
|
||||
Paul Culley <<html:a href="mailto:paulr2787@gmail.com">paulr2787@gmail.com</html:a>>
|
||||
</author>
|
||||
<author title="contributor">
|
||||
Peter Landgren <<html:a href="mailto:peter.talken@telia.com">peter.talken@telia.com</html:a>>
|
||||
</author>
|
||||
|
||||
@@ -1,18 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<application>
|
||||
<id type="desktop">gramps.desktop</id>
|
||||
<licence>CC0</licence>
|
||||
<description>
|
||||
<_p>Gramps is a genealogy program that is both intuitive for hobbyists and feature-complete for professional genealogists.</_p>
|
||||
<_p>It gives you the ability to record the many details of the life of an individual as well as the complex relationships between various people, places and events.</_p>
|
||||
<_p>All of your research is kept organized, searchable and as precise as you need it to be.</_p>
|
||||
</description>
|
||||
<url type="homepage">http://gramps-project.org/</url>
|
||||
<screenshots>
|
||||
<screenshot width="1226" height="740">http://www.gramps-project.org/wiki/images/5/5f/AppData1.png</screenshot>
|
||||
<screenshot width="1226" height="740">http://www.gramps-project.org/wiki/images/6/68/AppData2.png</screenshot>
|
||||
<screenshot type="default" width="1226" height="740">http://www.gramps-project.org/wiki/images/e/e9/AppData3.png</screenshot>
|
||||
<screenshot width="1226" height="740">http://www.gramps-project.org/wiki/images/6/68/AppData4.png</screenshot>
|
||||
<screenshot width="1226" height="740">http://www.gramps-project.org/wiki/images/5/50/AppData5.png</screenshot>
|
||||
</screenshots>
|
||||
</application>
|
||||
<component type="desktop">
|
||||
<id>gramps.desktop</id>
|
||||
<metadata_license>CC0</metadata_license>
|
||||
<name>Gramps</name>
|
||||
<summary>Genealogical research program</summary>
|
||||
|
||||
<description>
|
||||
<_p>Gramps is a genealogy program that is both intuitive for hobbyists and feature-complete for professional genealogists.</_p>
|
||||
<_p>It gives you the ability to record the many details of the life of an individual as well as the complex relationships between various people, places and events.</_p>
|
||||
<_p>All of your research is kept organized, searchable and as precise as you need it to be.</_p>
|
||||
</description>
|
||||
|
||||
<url type="homepage">https://gramps-project.org/</url>
|
||||
<url type="bugtracker">https://gramps-project.org/bugs/</url>
|
||||
<url type="help">https://gramps-project.org/wiki/index.php?title=Main_page</url>
|
||||
<project_license>GPL-2.0+</project_license>
|
||||
<developer_name>Gramps Development Team</developer_name>
|
||||
|
||||
<screenshots>
|
||||
<screenshot width="1226" height="740">http://www.gramps-project.org/wiki/images/5/5f/AppData1.png</screenshot>
|
||||
<screenshot width="1226" height="740">http://www.gramps-project.org/wiki/images/6/68/AppData2.png</screenshot>
|
||||
<screenshot type="default" width="1226" height="740">http://www.gramps-project.org/wiki/images/e/e9/AppData3.png</screenshot>
|
||||
<screenshot width="1226" height="740">http://www.gramps-project.org/wiki/images/6/68/AppData4.png</screenshot>
|
||||
<screenshot width="1226" height="740">http://www.gramps-project.org/wiki/images/5/50/AppData5.png</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<provides>
|
||||
<binary>gramps</binary>
|
||||
</provides>
|
||||
|
||||
</component>
|
||||
|
||||
@@ -25,15 +25,15 @@
|
||||
-->
|
||||
|
||||
<!--
|
||||
This is the Document Type Definition file for v1.6.0
|
||||
This is the Document Type Definition file for v1.7.1
|
||||
of the GRAMPS XML genealogy data format.
|
||||
Please use the following formal public identifier to identify it:
|
||||
|
||||
"-//GRAMPS//DTD GRAMPS XML V1.6.0//EN"
|
||||
"-//GRAMPS//DTD GRAMPS XML V1.7.1//EN"
|
||||
|
||||
For example:
|
||||
<!DOCTYPE database PUBLIC "-//GRAMPS//DTD GRAMPS XML V1.6.0//EN"
|
||||
"http://gramps-project.org/xml/1.6.0/grampsxml.dtd"
|
||||
<!DOCTYPE database PUBLIC "-//GRAMPS//DTD GRAMPS XML V1.7.1//EN"
|
||||
"http://gramps-project.org/xml/1.7.1/grampsxml.dtd"
|
||||
[...]>
|
||||
-->
|
||||
|
||||
@@ -62,7 +62,7 @@ DATABASE
|
||||
<!ELEMENT database (header, name-formats?, tags?, events?, people?, families?,
|
||||
citations?, sources?, places?, objects?, repositories?,
|
||||
notes?, bookmarks?, namemaps?)>
|
||||
<!ATTLIST database xmlns CDATA #FIXED "http://gramps-project.org/xml/1.6.0/">
|
||||
<!ATTLIST database xmlns CDATA #FIXED "http://gramps-project.org/xml/1.7.1/">
|
||||
|
||||
|
||||
<!-- ************************************************************
|
||||
@@ -122,6 +122,7 @@ GENDER has values of M, F, or U.
|
||||
|
||||
<!ELEMENT name (first?, call?, surname*, suffix?, title?, nick?, familynick?, group?,
|
||||
(daterange|datespan|dateval|datestr)?, noteref*, citationref*)>
|
||||
<!-- (Unknown|Also Know As|Birth Name|Married Name|Other Name) -->
|
||||
<!ATTLIST name
|
||||
alt (0|1) #IMPLIED
|
||||
type CDATA #IMPLIED
|
||||
@@ -138,6 +139,8 @@ GENDER has values of M, F, or U.
|
||||
<!ELEMENT familynick (#PCDATA)>
|
||||
<!ELEMENT group (#PCDATA)>
|
||||
<!ELEMENT surname (#PCDATA)>
|
||||
<!-- (Unknown|Inherited|Given|Taken|Patronymic|Matronymic|Feudal|
|
||||
Pseudonym|Patrilineal|Matrilineal|Occupation|Location) -->
|
||||
<!ATTLIST surname
|
||||
prefix CDATA #IMPLIED
|
||||
prim (1|0) #IMPLIED
|
||||
@@ -196,12 +199,13 @@ FAMILY
|
||||
<!ELEMENT mother EMPTY>
|
||||
<!ATTLIST mother hlink IDREF #REQUIRED>
|
||||
|
||||
<!-- (None|Birth|Adopted|Stepchild|Sponsored|Foster|Other|Unknown) -->
|
||||
<!ELEMENT childref (citationref*,noteref*)>
|
||||
<!ATTLIST childref
|
||||
hlink IDREF #REQUIRED
|
||||
priv (0|1) #IMPLIED
|
||||
mrel (None|Birth|Adopted|Stepchild|Sponsored|Foster|Other|Unknown) #IMPLIED
|
||||
frel (None|Birth|Adopted|Stepchild|Sponsored|Foster|Other|Unknown) #IMPLIED
|
||||
mrel CDATA #IMPLIED
|
||||
frel CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT type (#PCDATA)>
|
||||
@@ -248,20 +252,25 @@ PLACES
|
||||
|
||||
<!ELEMENT places (placeobj)*>
|
||||
|
||||
<!ELEMENT placeobj (ptitle?, code?, alt_name*, coord?, placeref*, location*,
|
||||
<!ELEMENT placeobj (ptitle?, pname+, code?, coord?, placeref*, location*,
|
||||
objref*, url*, noteref*, citationref*, tagref*)>
|
||||
<!ATTLIST placeobj
|
||||
id CDATA #IMPLIED
|
||||
handle ID #REQUIRED
|
||||
priv (0|1) #IMPLIED
|
||||
change CDATA #REQUIRED
|
||||
name CDATA #REQUIRED
|
||||
type CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT pname (daterange|datespan|dateval|datestr)?>
|
||||
|
||||
<!ATTLIST pname
|
||||
lang CDATA #IMPLIED
|
||||
value CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT ptitle (#PCDATA)>
|
||||
<!ELEMENT code (#PCDATA)>
|
||||
<!ELEMENT alt_name (#PCDATA)>
|
||||
|
||||
<!ELEMENT coord EMPTY>
|
||||
<!ATTLIST coord
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
-->
|
||||
|
||||
<!--
|
||||
This is the RELAX NG schema for the Gramps XML genealogy data format.
|
||||
This is the RELAX NG schema for the GRAMPS XML genealogy data format.
|
||||
-->
|
||||
|
||||
|
||||
<grammar
|
||||
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
|
||||
ns="http://gramps-project.org/xml/1.6.0/"
|
||||
ns="http://gramps-project.org/xml/1.7.1/"
|
||||
xmlns="http://relaxng.org/ns/structure/1.0">
|
||||
|
||||
<start><element name="database">
|
||||
@@ -210,16 +210,7 @@
|
||||
</define>
|
||||
|
||||
<define name="child-rel">
|
||||
<choice>
|
||||
<value>Birth</value>
|
||||
<value>Adopted</value>
|
||||
<value>Stepchild</value>
|
||||
<value>Sponsored</value>
|
||||
<value>Foster</value>
|
||||
<value>None</value>
|
||||
<value>Other</value>
|
||||
<value>Unknown</value>
|
||||
</choice>
|
||||
<text/>
|
||||
</define>
|
||||
|
||||
<define name="name-content">
|
||||
@@ -230,13 +221,7 @@
|
||||
<optional><attribute name="priv">
|
||||
<ref name="priv-content"/>
|
||||
</attribute></optional>
|
||||
<optional><attribute name="type"><choice>
|
||||
<value>Unknown</value>
|
||||
<value>Also Known As</value>
|
||||
<value>Birth Name</value>
|
||||
<value>Married Name</value>
|
||||
<value>Other Name</value>
|
||||
</choice></attribute></optional>
|
||||
<optional><attribute name="type"><text/></attribute></optional>
|
||||
<optional><attribute name="sort"><text/></attribute></optional>
|
||||
<optional><attribute name="display"><text/></attribute></optional>
|
||||
<optional><element name="first"><text/></element></optional>
|
||||
@@ -265,20 +250,7 @@
|
||||
<value>1</value>
|
||||
<value>0</value>
|
||||
</choice></attribute></optional>
|
||||
<optional><attribute name="derivation"><choice>
|
||||
<value>Unknown</value>
|
||||
<value>Inherited</value>
|
||||
<value>Given</value>
|
||||
<value>Taken</value>
|
||||
<value>Patronymic</value>
|
||||
<value>Matronymic</value>
|
||||
<value>Feudal</value>
|
||||
<value>Pseudonym</value>
|
||||
<value>Patrilineal</value>
|
||||
<value>Matrilineal</value>
|
||||
<value>Occupation</value>
|
||||
<value>Location</value>
|
||||
</choice></attribute></optional>
|
||||
<optional><attribute name="derivation"><text/></attribute></optional>
|
||||
<optional><attribute name="connector"><text/></attribute></optional>
|
||||
</define>
|
||||
|
||||
@@ -479,11 +451,12 @@
|
||||
|
||||
<define name="place-content">
|
||||
<ref name="primary-object"/>
|
||||
<attribute name="name"><text/></attribute>
|
||||
<attribute name="type"><text/></attribute>
|
||||
<optional><element name="ptitle"><text/></element></optional>
|
||||
<oneOrMore><element name="pname">
|
||||
<ref name="placename-content"/>
|
||||
</element></oneOrMore>
|
||||
<optional><element name="code"><text/></element></optional>
|
||||
<zeroOrMore><element name="alt_name"><text/></element></zeroOrMore>
|
||||
<optional><element name="coord">
|
||||
<attribute name="long"><text/></attribute>
|
||||
<attribute name="lat"><text/></attribute>
|
||||
@@ -772,6 +745,12 @@
|
||||
<text/>
|
||||
</define>
|
||||
|
||||
<define name="placename-content">
|
||||
<attribute name="value"><text/></attribute>
|
||||
<optional><attribute name="lang"><text/></attribute></optional>
|
||||
<optional><ref name="date-content"/></optional>
|
||||
</define>
|
||||
|
||||
<define name="placeref-content">
|
||||
<attribute name="hlink"><data type="IDREF"/></attribute>
|
||||
<optional><ref name="date-content"/></optional>
|
||||
|
||||
@@ -92,9 +92,9 @@ gramps(1) @VERSION@ gramps(1)
|
||||
might produce different gramps IDs in the resulting database.
|
||||
|
||||
|
||||
**-e** , **--export=** *FICHIER*
|
||||
**-e** , **--export=** *FILE*
|
||||
Export data into *FILE* . For **gramps-xml** , **gedcom**
|
||||
, **wft** , **gramps-pkg** , et **geneweb** , the *FILE* is the
|
||||
, **wft** , **gramps-pkg** , and **geneweb** , the *FILE* is the
|
||||
name of the resulting file.
|
||||
|
||||
When more than one output file is given, each has to be preceded
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<_tip number="14"><b>Calculating Relationships</b><br/>To check if two people in the database are related (by blood, not marriage) try the tool under "Tools > Utilities > Relationship Calculator...". The exact relationship as well as all common ancestors are reported.</_tip>
|
||||
|
||||
<_tip number="15"><b>SoundEx can help with family research</b><br/>SoundEx solves a long standing problem in genealogy, how to handle spelling variations. The SoundEx utility takes a surname and generates a simplified form that is equivalent for similar sounding names. Knowing the SoundEx Code for a surname is very helpful for researching Census Data files (microfiche) at a library or other research facility. To get the SoundEx codes for surnames in your database, go to "Tools > Utilities > Generate SoundEx Codes...".</_tip>
|
||||
<_tip number="15"><b>SoundEx can help with family research</b><br/>SoundEx solves a long standing problem in genealogy, how to handle spelling variations. The SoundEx Gramplet takes a surname and generates a simplified form that is equivalent for similar sounding names. Knowing the SoundEx Code for a surname is very helpful for researching Census Data files (microfiche) at a library or other research facility. To view the SoundEx codes for surnames in your database, add the SoundEx Gramplet.</_tip>
|
||||
|
||||
<_tip number="16"><b>Setting Your Preferences</b><br/>"Edit > Preferences..." lets you modify a number of settings, such as the path to your media files, and allows you to adjust many aspects of the Gramps presentation to your needs. Each separate view can also be configured under "View > Configure View..."</_tip>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
<_tip number="23"><b>Organising the Views</b><br/>Many of the views can present your data as either a hierarchical tree or as a simple list. Each view can also be configured to the way you like it. Have a look to the right of the top toolbar or under the "View" menu.</_tip>
|
||||
|
||||
<_tip number="24"><b>Navigating Back and Forward</b><br/>Gramps maintains a list of previous active objects such as People, Events and . You can move forward and backward through the list using "Go > Forward" and "Go > Back" or the arrow buttons.</_tip>
|
||||
<_tip number="24"><b>Navigating Back and Forward</b><br/>Gramps maintains a list of previous active objects such as People and Events. You can move forward and backward through the list using "Go > Forward" and "Go > Back" or the arrow buttons.</_tip>
|
||||
|
||||
<_tip number="25"><b>Keyboard Shortcuts</b><br/>Tired of having to take your hand off the keyboard to use the mouse? Many functions in Gramps have keyboard shortcuts. If one exists for a function it is displayed on the right side of the menu.</_tip>
|
||||
|
||||
@@ -67,11 +67,11 @@
|
||||
|
||||
<_tip number="36"><b>Bookmarking Individuals</b><br/>The Bookmarks menu is a convenient place to store the names of frequently used individuals. Selecting a bookmark will make that person the Active Person. To bookmark someone make them the Active Person then go to "Bookmarks > Add Bookmark" or press Ctrl+D. You can also bookmark most of the other objects.</_tip>
|
||||
|
||||
<_tip number="37"><b>Incorrect Dates</b><br/>Everyone occasionally enters dates with an invalid format. Incorrect date formats will show up in Gramps with a reddish background. You can fix the date using the Date Selection dialog which can be opened by clicking on the date button. The format of the date is set under "Edit > Preferences > Display".</_tip>
|
||||
<_tip number="37"><b>Incorrect Dates</b><br/>Everyone occasionally enters dates with an invalid format. Incorrect date formats will show up in Gramps with a either a reddish background or a red dot on the right edge of the field. You can fix the date using the Date Selection dialog which can be opened by clicking on the date button. The format of the date is set under "Edit > Preferences > Display".</_tip>
|
||||
|
||||
<_tip number="38"><b>Listing Events</b><br/>Events are added using the editor opened with "Person > Edit Person > Events". There is a long list of preset event types. You can add your own event types by typing in the text field, they will be added to the available events, but not translated.</_tip>
|
||||
|
||||
<_tip number="39"><b>Managing Names</b><br/>It is easy to manage people with several names in Gramps. In the Person Editor select the Names tab. You can add names of different types and set the prefered name by dragging it to the Prefered Name section.</_tip>
|
||||
<_tip number="39"><b>Managing Names</b><br/>It is easy to manage people with several names in Gramps. In the Person Editor select the Names tab. You can add names of different types and set the preferred name by dragging it to the Preferred Name section.</_tip>
|
||||
|
||||
<_tip number="40"><b>Ancestor View</b><br/>The Ancestry View displays a traditional pedigree chart. Hold the mouse over an individual to see more information about them or right click on an individual to access other family members and settings. Play with the settings to see the different options.</_tip>
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
|
||||
<_tip number="62"><b>The 'How and Why' of Your Genealogy</b><br/> Genealogy isn't only about dates and names. It is about people. Be descriptive. Include why things happened, and how descendants might have been shaped by the events they went through. Narratives go a long way in making your family history come alive.</_tip>
|
||||
|
||||
<_tip number="63"><b>Don't speak English?</b><br/>Volunteers have translated Gramps into more than 20 languages. If Gramps supports your language and it is not being displayed, set the default language in your operating system and restart Gramps.</_tip>
|
||||
<_tip number="63"><b>Don't speak English?</b><br/>Volunteers have translated Gramps into more than 40 languages. If Gramps supports your language and it is not being displayed, set the default language in your operating system and restart Gramps.</_tip>
|
||||
|
||||
<_tip number="64"><b>Gramps Translators</b><br/>Gramps has been designed so that new translations can easily be added with little development effort. If you are interested in participating please email gramps-devel@lists.sf.net</_tip>
|
||||
|
||||
|
||||
26
debian/control
vendored
26
debian/control
vendored
@@ -7,41 +7,45 @@ Build-Depends-Indep:
|
||||
gettext,
|
||||
intltool,
|
||||
libxml-parser-perl,
|
||||
python-all,
|
||||
python-setuptools
|
||||
python3-all,
|
||||
python3-setuptools
|
||||
Build-Depends:
|
||||
dh-python,
|
||||
debhelper (>= 9.0.0)
|
||||
Standards-Version: 3.9.5
|
||||
Vcs-Git: git://anonscm.debian.org/collab-maint/gramps.git
|
||||
Vcs-browser: http://anonscm.debian.org/gitweb/?p=collab-maint/gramps.git
|
||||
Homepage: http://www.gramps-project.org/
|
||||
X-Python-Version: >= 3.0
|
||||
X-Python-Version: >= 3.2
|
||||
|
||||
Package: python-gramps
|
||||
Package: python3-gramps
|
||||
Architecture: all
|
||||
Depends:
|
||||
gir1.2-gtk-3.0,
|
||||
gir1.2-gtk-3.0 (>= 3.10.0),
|
||||
librsvg2-2,
|
||||
python3-gi,
|
||||
python3-gi-cairo,
|
||||
python3-bsddb3,
|
||||
xdg-utils,
|
||||
${misc:Depends},
|
||||
${python:Depends}
|
||||
${python3:Depends}
|
||||
Recommends:
|
||||
graphviz,
|
||||
libosmgpsmap-1.0-0-dev,
|
||||
gir1.2-goocanvas-2.0,
|
||||
libosmgpsmap-1.0-0,
|
||||
gir1.2-osmgpsmap-1.0,
|
||||
python3-pyicu
|
||||
Suggests:
|
||||
fonts-freefont-ttf,
|
||||
gir1.2-gexiv2-0.4,
|
||||
gir1.2-gtk-gtkspell3-3.0,
|
||||
gir1.2-gexiv2-0.10,
|
||||
gir1.2-gtkspell3-3.0,
|
||||
python3-pil,
|
||||
rcs
|
||||
Description: Genealogical research program
|
||||
GRAMPS is an Open Source genealogy program written in Python, using
|
||||
Gramps is an Open Source genealogy program written in Python, using
|
||||
the GTK/GNOME interface. It is an extremely flexible program fitting
|
||||
the needs for both the amateur genealogist and serious genealogical
|
||||
researcher.
|
||||
GRAMPS has the ability to import GEDCOM files exported from many
|
||||
Gramps has the ability to import GEDCOM files exported from many
|
||||
proprietary genealogy programs and can produce a large number of
|
||||
reports in many popular formats.
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/setup.py b/setup.py
|
||||
index 3f702ae..9622d75 100644
|
||||
--- a/setup.py
|
||||
+++ b/setup.py
|
||||
@@ -248,7 +248,7 @@ class install(_install):
|
||||
'utils', 'resource-path')
|
||||
with io.open(resource_file, 'w', encoding='utf-8',
|
||||
errors='strict') as fp:
|
||||
- path = os.path.abspath(os.path.join(self.install_data, 'share'))
|
||||
+ path = '/usr/share'
|
||||
if sys.version_info[0] < 3:
|
||||
path = unicode(path)
|
||||
fp.write(path)
|
||||
22
debian/patches/0002-Disable-HTML-View.patch
vendored
22
debian/patches/0002-Disable-HTML-View.patch
vendored
@@ -1,22 +0,0 @@
|
||||
diff --git a/gramps/plugins/view/htmlrenderer.py b/gramps/plugins/view/htmlrenderer.py
|
||||
index c41942a..8f35b16 100644
|
||||
--- a/gramps/plugins/view/htmlrenderer.py
|
||||
+++ b/gramps/plugins/view/htmlrenderer.py
|
||||
@@ -122,11 +122,12 @@ user_pref("general.useragent.locale, %(lang)s);
|
||||
|
||||
TOOLKIT = NOWEB
|
||||
|
||||
-try:
|
||||
- from gi.repository import WebKit as webkit
|
||||
- TOOLKIT = WEBKIT
|
||||
-except:
|
||||
- pass
|
||||
+#Disable webkit as it is causing a crash in Gramps 4.0.2
|
||||
+#try:
|
||||
+# from gi.repository import WebKit as webkit
|
||||
+# TOOLKIT = WEBKIT
|
||||
+#except:
|
||||
+# pass
|
||||
|
||||
#no interfaces present, raise Error so that options for GeoView do not show
|
||||
if TOOLKIT == NOWEB :
|
||||
2
debian/patches/series
vendored
2
debian/patches/series
vendored
@@ -1,2 +0,0 @@
|
||||
0001-Correct-resource-path-in-setup.py.patch
|
||||
0002-Disable-HTML-View.patch
|
||||
13
debian/rules
vendored
13
debian/rules
vendored
@@ -5,7 +5,7 @@ export DH_VERBOSE=1
|
||||
export DH_OPTIONS=-v
|
||||
|
||||
%:
|
||||
dh $@ --with python3
|
||||
dh $@ --with python3 --buildsystem=pybuild
|
||||
|
||||
# Override auto test because upstream do not use the standard unittest discover
|
||||
override_dh_auto_test:
|
||||
@@ -17,20 +17,19 @@ override_dh_auto_build:
|
||||
# Override of auto_install to remove information from package
|
||||
override_dh_auto_install:
|
||||
#dh_auto_install
|
||||
python3 setup.py install --resourcepath=/usr/share --root=debian/python3-gramps --install-layout=deb
|
||||
# Remove duplicate copyright information
|
||||
#rm $(CURDIR)/debian/python3-gramps/usr/share/doc/gramps/COPYING
|
||||
rm $(CURDIR)/debian/python3-gramps/usr/share/doc/gramps/COPYING
|
||||
# Remove install file as it is not needed by package users
|
||||
#rm $(CURDIR)/debian/python3-gramps/usr/share/doc/gramps/INSTALL
|
||||
rm $(CURDIR)/debian/python3-gramps/usr/share/doc/gramps/INSTALL
|
||||
# Remove duplicate license information
|
||||
#rm $(CURDIR)/debian/python3-gramps/usr/share/doc/gramps/LICENSE
|
||||
python3 setup.py install --root=debian/python3-gramps --install-layout=deb
|
||||
rm $(CURDIR)/debian/python3-gramps/usr/share/doc/gramps/LICENSE
|
||||
ln -s /usr/share/common-licenses/GPL-2 $(CURDIR)/debian/python3-gramps/usr/share/doc/gramps/COPYING
|
||||
|
||||
# Make css style sheets and png icons non-executable
|
||||
override_dh_fixperms:
|
||||
dh_fixperms
|
||||
chmod a-x $(CURDIR)/debian/python3-gramps/usr/share/gramps/css/Web_*.css
|
||||
chmod a-x $(CURDIR)/debian/python3-gramps/usr/share/gramps/images/22x22/gramps*.png
|
||||
chmod a-x $(CURDIR)/debian/python3-gramps/usr/share/gramps/images/16x16/gramps*.png
|
||||
|
||||
# Avoid compressing COPYING file so that it can appear in the "About" dialog
|
||||
override_dh_compress:
|
||||
|
||||
2
debian/source/format
vendored
2
debian/source/format
vendored
@@ -1 +1 @@
|
||||
1.0
|
||||
1.8
|
||||
|
||||
1
debian/source/local-options
vendored
1
debian/source/local-options
vendored
@@ -1 +0,0 @@
|
||||
unapply-patches
|
||||
4
debian/watch
vendored
4
debian/watch
vendored
@@ -1,4 +0,0 @@
|
||||
version=3
|
||||
|
||||
opts="dversionmangle=s/\+dfsg//g" \
|
||||
http://sf.net/gramps/gramps-(.+)\.tar\.gz
|
||||
@@ -10,3 +10,11 @@ Name
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Place
|
||||
====================================
|
||||
.. automodule:: gramps.gen.display.place
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
0
example/gedcom/sample.ged
Executable file → Normal file
0
example/gedcom/sample.ged
Executable file → Normal file
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE database PUBLIC "-//Gramps//DTD Gramps XML 1.6.0//EN"
|
||||
"http://gramps-project.org/xml/1.6.0/grampsxml.dtd">
|
||||
<database xmlns="http://gramps-project.org/xml/1.6.0/">
|
||||
<!DOCTYPE database PUBLIC "-//Gramps//DTD Gramps XML 1.7.1//EN"
|
||||
"http://gramps-project.org/xml/1.7.1/grampsxml.dtd">
|
||||
<database xmlns="http://gramps-project.org/xml/1.7.1/">
|
||||
<header>
|
||||
<created date="2015-01-24" version="4.1.2"/>
|
||||
<created date="2015-07-04" version="4.2.0"/>
|
||||
<researcher>
|
||||
<resname>Alex Roitman,,,</resname>
|
||||
</researcher>
|
||||
@@ -1523,174 +1523,217 @@
|
||||
</source>
|
||||
</sources>
|
||||
<places>
|
||||
<placeobj handle="_4ZLT6DVCWT9LTZRDCS" change="1422124381" id="P0003" name="Ronne" type="City">
|
||||
<placeobj handle="_4ZLT6DVCWT9LTZRDCS" change="1422124381" id="P0003" type="City">
|
||||
<ptitle>Ronne, Bornholm, Denmark</ptitle>
|
||||
<pname value="Ronne"/>
|
||||
<placeref hlink="_cef2428d9dd233688ea3ed3cc24"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_61NT6D3G1JMOTO6Z7Y" change="1422123855" id="P0012" name="Grostorp" type="Municipality">
|
||||
<placeobj handle="_61NT6D3G1JMOTO6Z7Y" change="1422123855" id="P0012" type="Municipality">
|
||||
<ptitle>Grostorp, Kristianstad Lan, Sweden</ptitle>
|
||||
<pname value="Grostorp"/>
|
||||
<placeref hlink="_cef23a81ba8c837cc364895d88"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_67MT6DB6KWOVMBAXSY" change="1422125128" id="P0002" name="San Francisco" type="City">
|
||||
<placeobj handle="_67MT6DB6KWOVMBAXSY" change="1422125128" id="P0002" type="City">
|
||||
<ptitle>San Francisco, San Francisco Co., CA, USA</ptitle>
|
||||
<pname value="San Francisco"/>
|
||||
<placeref hlink="_cef24668db23c27d421f51c667d"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_7JMT6DN2LOF54KXHTU" change="1422125958" id="P0010" name="Reno" type="City">
|
||||
<placeobj handle="_7JMT6DN2LOF54KXHTU" change="1422125958" id="P0010" type="City">
|
||||
<ptitle>Reno, Washoe Co., NV, USA</ptitle>
|
||||
<pname value="Reno"/>
|
||||
<placeref hlink="_cef2513e057732c3f27780750d"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_A9MT6DHVWGWRP59DEV" change="1422123595" id="P0011" name="Sweden" type="Country">
|
||||
<placeobj handle="_A9MT6DHVWGWRP59DEV" change="1422123595" id="P0011" type="Country">
|
||||
<ptitle>Sweden</ptitle>
|
||||
<pname value="Sweden"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_AANT6D026O5SHNUCDH" change="1422123942" id="P0015" name="Simrishamn" type="Municipality">
|
||||
<placeobj handle="_AANT6D026O5SHNUCDH" change="1422123942" id="P0015" type="Municipality">
|
||||
<ptitle>Simrishamn, Kristianstad Lan, Sweden</ptitle>
|
||||
<pname value="Simrishamn"/>
|
||||
<placeref hlink="_cef23a81ba8c837cc364895d88"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_AKMT6DMEYZDTG9J6DS" change="1422124249" id="P0013" name="Copenhagen" type="City">
|
||||
<placeobj handle="_AKMT6DMEYZDTG9J6DS" change="1422124249" id="P0013" type="City">
|
||||
<ptitle>Copenhagen, Denmark</ptitle>
|
||||
<pname value="Copenhagen"/>
|
||||
<placeref hlink="_cef2418f9333e16e00f6ce2eb14"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_BAOT6D1WY6J4O4ARRN" change="1422125198" id="P0030" name="San Ramon" type="City">
|
||||
<placeobj handle="_BAOT6D1WY6J4O4ARRN" change="1422125198" id="P0030" type="City">
|
||||
<ptitle>San Ramon, Conta Costa Co., CA, USA</ptitle>
|
||||
<pname value="San Ramon"/>
|
||||
<placeref hlink="_cef2478a94b48a58d3be6a10493"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_DYLT6DF4DX2MNZICJ8" change="1422126222" id="P0014" name="Hoya" type="City">
|
||||
<placeobj handle="_DYLT6DF4DX2MNZICJ8" change="1422126222" id="P0014" type="City">
|
||||
<ptitle>Hoya, Sweden</ptitle>
|
||||
<alt_name>Jona</alt_name>
|
||||
<alt_name>Hoia</alt_name>
|
||||
<pname value="Hoya"/>
|
||||
<pname value="Jona"/>
|
||||
<pname value="Hoia"/>
|
||||
<placeref hlink="_A9MT6DHVWGWRP59DEV"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_ELNT6DS8GN8WI7Z4SO" change="1422125073" id="P0008" name="Hayward" type="City">
|
||||
<placeobj handle="_ELNT6DS8GN8WI7Z4SO" change="1422125073" id="P0008" type="City">
|
||||
<ptitle>Hayward, Alameda Co., CA, USA</ptitle>
|
||||
<pname value="Hayward"/>
|
||||
<placeref hlink="_cef245b044820b7405a1180f298"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_FBNT6DL92NDY0Z5SGP" change="1422125294" id="P0021" name="Santa Rosa" type="City">
|
||||
<placeobj handle="_FBNT6DL92NDY0Z5SGP" change="1422125294" id="P0021" type="City">
|
||||
<ptitle>Santa Rosa, Sonoma Co., CA, USA</ptitle>
|
||||
<pname value="Santa Rosa"/>
|
||||
<placeref hlink="_cef24b7a76efa8b9d98d67ea5a"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_GWNT6D12ZV06PK969X" change="1422125101" id="P0020" name="Sacramento" type="City">
|
||||
<placeobj handle="_GWNT6D12ZV06PK969X" change="1422125101" id="P0020" type="City">
|
||||
<ptitle>Sacramento, Sacramento Co., CA, USA</ptitle>
|
||||
<pname value="Sacramento"/>
|
||||
<placeref hlink="_cef246117947f75e54c09680419"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_HFNT6D12ZC0KOWY69T" change="1422125018" id="P0016" name="Fremont" type="City">
|
||||
<placeobj handle="_HFNT6D12ZC0KOWY69T" change="1422125018" id="P0016" type="City">
|
||||
<ptitle>Fremont, Alameda Co., CA, USA</ptitle>
|
||||
<pname value="Fremont"/>
|
||||
<placeref hlink="_cef245b044820b7405a1180f298"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_HINT6DP8JGGL0KKB8J" change="1422123879" id="P0000" name="Loderup" type="Municipality">
|
||||
<placeobj handle="_HINT6DP8JGGL0KKB8J" change="1422123879" id="P0000" type="Municipality">
|
||||
<ptitle>Loderup, Malmous Lan, Sweden</ptitle>
|
||||
<pname value="Loderup"/>
|
||||
<placeref hlink="_cef23c1ee8b7da58c764e88c637"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_IEOT6DOW3RE8AQ94HH" change="1422126043" id="P0025" name="Bí" type="Unknown">
|
||||
<placeobj handle="_IEOT6DOW3RE8AQ94HH" change="1422126043" id="P0025" type="Unknown">
|
||||
<ptitle>Bí</ptitle>
|
||||
<pname value="Bí"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_LTNT6DKZ5CR8PZSVUS" change="1422125169" id="P0022" name="San Jose" type="City">
|
||||
<placeobj handle="_LTNT6DKZ5CR8PZSVUS" change="1422125169" id="P0022" type="City">
|
||||
<ptitle>San Jose, Santa Clara Co., CA, USA</ptitle>
|
||||
<pname value="San Jose"/>
|
||||
<placeref hlink="_cef246c95c132bcf6a0255d4d17"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_PUNT6D1XHS0DJW9QP6" change="1422125605" id="P0024" name="UC Berkeley" type="University">
|
||||
<placeobj handle="_PUNT6D1XHS0DJW9QP6" change="1422125605" id="P0024" type="University">
|
||||
<ptitle>UC Berkeley, CA, USA</ptitle>
|
||||
<pname value="UC Berkeley"/>
|
||||
<placeref hlink="_cef243fb5634559442323368f63"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_PXMT6DBL0WSBL76WD7" change="1422123936" id="P0026" name="Smestorp" type="Municipality">
|
||||
<placeobj handle="_PXMT6DBL0WSBL76WD7" change="1422123936" id="P0026" type="Municipality">
|
||||
<ptitle>Smestorp, Kristianstad Lan, Sweden</ptitle>
|
||||
<pname value="Smestorp"/>
|
||||
<placeref hlink="_cef23a81ba8c837cc364895d88"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_QBOT6DN7UCCTZQ055" change="1422125399" id="P0029" name="Woodland" type="City">
|
||||
<placeobj handle="_QBOT6DN7UCCTZQ055" change="1422125399" id="P0029" type="City">
|
||||
<ptitle>Woodland, Yolo Co., CA, USA</ptitle>
|
||||
<pname value="Woodland"/>
|
||||
<placeref hlink="_cef24c2e3592e759b7797f95465"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_QJMT6DGII29FWCPX2E" change="1422124361" id="P0028" name="Ronne Bornholm" type="City">
|
||||
<placeobj handle="_QJMT6DGII29FWCPX2E" change="1422124361" id="P0028" type="City">
|
||||
<ptitle>Ronne Bornholm, Denmark</ptitle>
|
||||
<pname value="Ronne Bornholm"/>
|
||||
<placeref hlink="_cef2418f9333e16e00f6ce2eb14"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_R8MT6DRIZVNRYDK0VN" change="1422123930" id="P0027" name="Tommarp" type="Municipality">
|
||||
<placeobj handle="_R8MT6DRIZVNRYDK0VN" change="1422123930" id="P0027" type="Municipality">
|
||||
<ptitle>Tommarp, Kristianstad Lan, Sweden</ptitle>
|
||||
<pname value="Tommarp"/>
|
||||
<placeref hlink="_cef23a81ba8c837cc364895d88"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_RPMT6DTQR8J7LK98HJ" change="1422125771" id="P0019" name="Denver" type="City">
|
||||
<placeobj handle="_RPMT6DTQR8J7LK98HJ" change="1422125771" id="P0019" type="City">
|
||||
<ptitle>Denver, Denver Co., CO, USA</ptitle>
|
||||
<pname value="Denver"/>
|
||||
<placeref hlink="_cef24ffc57f28a50ea65f0af645"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_S1NT6DPOBYC1JGMR1P" change="1422125992" id="P0001" name="Sparks" type="City">
|
||||
<placeobj handle="_S1NT6DPOBYC1JGMR1P" change="1422125992" id="P0001" type="City">
|
||||
<ptitle>Sparks, Washoe Co., NV, USA</ptitle>
|
||||
<pname value="Sparks"/>
|
||||
<placeref hlink="_cef2513e057732c3f27780750d"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_XLNT6DUONITFPPEGVH" change="1422125508" id="P0009" name="Community Presbyterian Church" type="Church">
|
||||
<placeobj handle="_XLNT6DUONITFPPEGVH" change="1422125508" id="P0009" type="Church">
|
||||
<ptitle>Community Presbyterian Church, Danville, CA, USA</ptitle>
|
||||
<pname value="Community Presbyterian Church"/>
|
||||
<placeref hlink="_cef24d930653dc59ec3a36510e4"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_XSMT6DNISHYRCR1E78" change="1422123836" id="P0004" name="Gladsax" type="Municipality">
|
||||
<placeobj handle="_XSMT6DNISHYRCR1E78" change="1422123836" id="P0004" type="Municipality">
|
||||
<ptitle>Gladsax, Kristianstad Lan, Sweden</ptitle>
|
||||
<pname value="Gladsax"/>
|
||||
<placeref hlink="_cef23a81ba8c837cc364895d88"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef23a81ba8c837cc364895d88" change="1422123677" id="P0005" name="Kristianstad Lan" type="County">
|
||||
<placeobj handle="_cef23a81ba8c837cc364895d88" change="1422123677" id="P0005" type="County">
|
||||
<ptitle>Kristianstad Lan, Sweden</ptitle>
|
||||
<pname value="Kristianstad Lan"/>
|
||||
<placeref hlink="_A9MT6DHVWGWRP59DEV"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef23c1ee8b7da58c764e88c637" change="1422123662" id="P0006" name="Malmous Lan" type="County">
|
||||
<placeobj handle="_cef23c1ee8b7da58c764e88c637" change="1422123662" id="P0006" type="County">
|
||||
<ptitle>Malmous Lan, Sweden</ptitle>
|
||||
<pname value="Malmous Lan"/>
|
||||
<placeref hlink="_A9MT6DHVWGWRP59DEV"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef2418f9333e16e00f6ce2eb14" change="1422124233" id="P0007" name="Denmark" type="Country">
|
||||
<placeobj handle="_cef2418f9333e16e00f6ce2eb14" change="1422124233" id="P0007" type="Country">
|
||||
<ptitle>Denmark</ptitle>
|
||||
<pname value="Denmark"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef2428d9dd233688ea3ed3cc24" change="1422124337" id="P0017" name="Bornholm" type="Region">
|
||||
<placeobj handle="_cef2428d9dd233688ea3ed3cc24" change="1422124337" id="P0017" type="Region">
|
||||
<ptitle>Bornholm, Denmark</ptitle>
|
||||
<pname value="Bornholm"/>
|
||||
<placeref hlink="_cef2418f9333e16e00f6ce2eb14"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef2438892244290ca7fb5750" change="1422124440" id="P0018" name="USA" type="Country">
|
||||
<placeobj handle="_cef2438892244290ca7fb5750" change="1422124440" id="P0018" type="Country">
|
||||
<ptitle>USA</ptitle>
|
||||
<pname value="USA"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef243fb5634559442323368f63" change="1422124487" id="P0023" name="CA" type="State">
|
||||
<placeobj handle="_cef243fb5634559442323368f63" change="1422124487" id="P0023" type="State">
|
||||
<ptitle>CA, USA</ptitle>
|
||||
<pname value="CA"/>
|
||||
<placeref hlink="_cef2438892244290ca7fb5750"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef244224d14af0273799b281e" change="1422124514" id="P0031" name="CO" type="State">
|
||||
<placeobj handle="_cef244224d14af0273799b281e" change="1422124514" id="P0031" type="State">
|
||||
<ptitle>CO, USA</ptitle>
|
||||
<pname value="CO"/>
|
||||
<placeref hlink="_cef2438892244290ca7fb5750"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef24468f6e3a984bf57967e95d" change="1422124542" id="P0032" name="NV" type="State">
|
||||
<placeobj handle="_cef24468f6e3a984bf57967e95d" change="1422124542" id="P0032" type="State">
|
||||
<ptitle>NV, USA</ptitle>
|
||||
<pname value="NV"/>
|
||||
<placeref hlink="_cef2438892244290ca7fb5750"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef245b044820b7405a1180f298" change="1422124666" id="P0033" name="Alameda Co." type="County">
|
||||
<placeobj handle="_cef245b044820b7405a1180f298" change="1422124666" id="P0033" type="County">
|
||||
<ptitle>Alameda Co., CA, USA</ptitle>
|
||||
<pname value="Alameda Co."/>
|
||||
<placeref hlink="_cef243fb5634559442323368f63"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef246117947f75e54c09680419" change="1422124908" id="P0034" name="Sacramento Co." type="County">
|
||||
<placeobj handle="_cef246117947f75e54c09680419" change="1422124908" id="P0034" type="County">
|
||||
<ptitle>Sacramento Co., CA, USA</ptitle>
|
||||
<pname value="Sacramento Co."/>
|
||||
<placeref hlink="_cef243fb5634559442323368f63"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef24668db23c27d421f51c667d" change="1422124741" id="P0035" name="San Francisco Co." type="County">
|
||||
<placeobj handle="_cef24668db23c27d421f51c667d" change="1422124741" id="P0035" type="County">
|
||||
<ptitle>San Francisco Co., CA, USA</ptitle>
|
||||
<pname value="San Francisco Co."/>
|
||||
<placeref hlink="_cef243fb5634559442323368f63"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef246c95c132bcf6a0255d4d17" change="1422124781" id="P0036" name="Santa Clara Co." type="County">
|
||||
<placeobj handle="_cef246c95c132bcf6a0255d4d17" change="1422124781" id="P0036" type="County">
|
||||
<ptitle>Santa Clara Co., CA, USA</ptitle>
|
||||
<pname value="Santa Clara Co."/>
|
||||
<placeref hlink="_cef243fb5634559442323368f63"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef2478a94b48a58d3be6a10493" change="1422124860" id="P0037" name="Conta Costa Co." type="County">
|
||||
<placeobj handle="_cef2478a94b48a58d3be6a10493" change="1422124860" id="P0037" type="County">
|
||||
<ptitle>Conta Costa Co., CA, USA</ptitle>
|
||||
<pname value="Conta Costa Co."/>
|
||||
<placeref hlink="_cef243fb5634559442323368f63"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef24b7a76efa8b9d98d67ea5a" change="1422125273" id="P0038" name="Sonoma Co." type="County">
|
||||
<placeobj handle="_cef24b7a76efa8b9d98d67ea5a" change="1422125273" id="P0038" type="County">
|
||||
<ptitle>Sonoma Co., CA, USA</ptitle>
|
||||
<pname value="Sonoma Co."/>
|
||||
<placeref hlink="_cef243fb5634559442323368f63"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef24c2e3592e759b7797f95465" change="1422125420" id="P0039" name="Yolo Co." type="County">
|
||||
<placeobj handle="_cef24c2e3592e759b7797f95465" change="1422125420" id="P0039" type="County">
|
||||
<ptitle>Yolo Co., CA, USA</ptitle>
|
||||
<pname value="Yolo Co."/>
|
||||
<placeref hlink="_cef243fb5634559442323368f63"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef24d930653dc59ec3a36510e4" change="1422125493" id="P0040" name="Danville" type="City">
|
||||
<placeobj handle="_cef24d930653dc59ec3a36510e4" change="1422125493" id="P0040" type="City">
|
||||
<ptitle>Danville, CA, USA</ptitle>
|
||||
<pname value="Danville"/>
|
||||
<placeref hlink="_cef243fb5634559442323368f63"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef24ffc57f28a50ea65f0af645" change="1422125745" id="P0041" name="Denver Co." type="County">
|
||||
<placeobj handle="_cef24ffc57f28a50ea65f0af645" change="1422125745" id="P0041" type="County">
|
||||
<ptitle>Denver Co., CO, USA</ptitle>
|
||||
<pname value="Denver Co."/>
|
||||
<placeref hlink="_cef244224d14af0273799b281e"/>
|
||||
</placeobj>
|
||||
<placeobj handle="_cef2513e057732c3f27780750d" change="1422125877" id="P0042" name="Washoe Co." type="County">
|
||||
<placeobj handle="_cef2513e057732c3f27780750d" change="1422125877" id="P0042" type="County">
|
||||
<ptitle>Washoe Co., NV, USA</ptitle>
|
||||
<pname value="Washoe Co."/>
|
||||
<placeref hlink="_cef24468f6e3a984bf57967e95d"/>
|
||||
</placeobj>
|
||||
</places>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,7 +46,8 @@ log = logging.getLogger(".")
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.plug import BasePluginManager
|
||||
from gramps.gen.plug.docgen import (StyleSheet, StyleSheetList, PaperStyle,
|
||||
PAPER_PORTRAIT, PAPER_LANDSCAPE, graphdoc)
|
||||
PAPER_PORTRAIT, PAPER_LANDSCAPE, graphdoc,
|
||||
treedoc)
|
||||
from gramps.gen.plug.menu import (FamilyOption, PersonOption, NoteOption,
|
||||
MediaOption, PersonListOption, NumberOption,
|
||||
BooleanOption, DestinationOption, StringOption,
|
||||
@@ -54,8 +55,8 @@ from gramps.gen.plug.menu import (FamilyOption, PersonOption, NoteOption,
|
||||
from gramps.gen.display.name import displayer as name_displayer
|
||||
from gramps.gen.errors import ReportError, FilterError
|
||||
from gramps.gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK,
|
||||
CATEGORY_GRAPHVIZ, CATEGORY_CODE,
|
||||
ReportOptions, append_styles)
|
||||
CATEGORY_GRAPHVIZ, CATEGORY_TREE,
|
||||
CATEGORY_CODE, ReportOptions, append_styles)
|
||||
from gramps.gen.plug.report._paper import paper_sizes
|
||||
from gramps.gen.const import USER_HOME
|
||||
from gramps.gen.dbstate import DbState
|
||||
@@ -225,7 +226,7 @@ class CommandLineReport(object):
|
||||
self.raw_name = name
|
||||
self.option_class = option_class(name, database)
|
||||
if category == CATEGORY_GRAPHVIZ:
|
||||
# Need to include GraphViz options
|
||||
# Need to include Graphviz options
|
||||
self.__gvoptions = graphdoc.GVOptions()
|
||||
menu = self.option_class.menu
|
||||
self.__gvoptions.add_menu_options(menu)
|
||||
@@ -233,6 +234,15 @@ class CommandLineReport(object):
|
||||
if name not in self.option_class.options_dict:
|
||||
self.option_class.options_dict[name] = \
|
||||
menu.get_option_by_name(name).get_value()
|
||||
if category == CATEGORY_TREE:
|
||||
# Need to include Genealogy Tree options
|
||||
self.__toptions = treedoc.TreeOptions()
|
||||
menu = self.option_class.menu
|
||||
self.__toptions.add_menu_options(menu)
|
||||
for name in menu.get_all_option_names():
|
||||
if name not in self.option_class.options_dict:
|
||||
self.option_class.options_dict[
|
||||
name] = menu.get_option_by_name(name).get_value()
|
||||
self.option_class.load_previous_values()
|
||||
_validate_options(self.option_class, database)
|
||||
self.show = options_str_dict.pop('show', None)
|
||||
@@ -301,6 +311,10 @@ class CommandLineReport(object):
|
||||
for graph_format in graphdoc.FORMATS:
|
||||
self.options_help['off'][2].append(
|
||||
graph_format["type"] + "\t" + graph_format["descr"] )
|
||||
elif self.category == CATEGORY_TREE:
|
||||
for tree_format in treedoc.FORMATS:
|
||||
self.options_help['off'][2].append(
|
||||
tree_format["type"] + "\t" + tree_format["descr"])
|
||||
else:
|
||||
self.options_help['off'][2] = "NA"
|
||||
|
||||
@@ -413,7 +427,13 @@ class CommandLineReport(object):
|
||||
elif isinstance(option, EnumeratedListOption):
|
||||
ilist = []
|
||||
for (value, description) in option.get_items():
|
||||
ilist.append("%s\t%s" % (value, description))
|
||||
tabs = '\t'
|
||||
try:
|
||||
tabs = '\t\t' if len(value) < 10 else '\t'
|
||||
except TypeError: #Value is a number, use just one tab.
|
||||
pass
|
||||
val = "%s%s%s" % (value, tabs, description)
|
||||
ilist.append(val)
|
||||
self.options_help[name].append(ilist)
|
||||
elif isinstance(option, Option):
|
||||
self.options_help[name].append(option.get_help())
|
||||
@@ -472,6 +492,15 @@ class CommandLineReport(object):
|
||||
# Pick the first one as the default.
|
||||
self.format = graphdoc.FORMATS[0]["class"]
|
||||
_chosen_format = graphdoc.FORMATS[0]["type"]
|
||||
elif self.category == CATEGORY_TREE:
|
||||
for tree_format in treedoc.FORMATS:
|
||||
if tree_format['type'] == self.options_dict['off']:
|
||||
if not self.format: # choose the first one, not the last
|
||||
self.format = tree_format["class"]
|
||||
if self.format is None:
|
||||
# Pick the first one as the default.
|
||||
self.format = tree_format.FORMATS[0]["class"]
|
||||
_chosen_format = tree_format.FORMATS[0]["type"]
|
||||
else:
|
||||
self.format = None
|
||||
if _chosen_format and _format_str:
|
||||
@@ -587,8 +616,8 @@ class CommandLineReport(object):
|
||||
elif self.show in self.options_help:
|
||||
opt = self.options_help[self.show]
|
||||
tabs = '\t\t' if len(self.show) < 10 else '\t'
|
||||
print(' %s%s%s (%s)' % (self.show, tabs, opt[1], opt[0]))
|
||||
print(_(" Available values are:"))
|
||||
print(' %s%s%s (%s)' % (self.show, tabs, opt[1], opt[0]))
|
||||
vals = opt[2]
|
||||
if isinstance(vals, (list, tuple)):
|
||||
for val in vals:
|
||||
@@ -634,7 +663,7 @@ def cl_report(database, name, category, report_class, options_class,
|
||||
clr.selected_style,
|
||||
PaperStyle(clr.paper,clr.orien,clr.marginl,
|
||||
clr.marginr,clr.margint,clr.marginb))
|
||||
elif category == CATEGORY_GRAPHVIZ:
|
||||
elif category in [CATEGORY_GRAPHVIZ, CATEGORY_TREE]:
|
||||
clr.option_class.handler.doc = clr.format(
|
||||
clr.option_class,
|
||||
PaperStyle(clr.paper,clr.orien,clr.marginl,
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
""" CLI tests for gramps """
|
||||
|
||||
import sys
|
||||
import os
|
||||
import unittest
|
||||
import re
|
||||
@@ -72,10 +73,11 @@ class Test(unittest.TestCase):
|
||||
# This tests the fix for bug #1331-1334
|
||||
# read trivial gedcom input, write gedcom output
|
||||
def test2_exec_CLI(self):
|
||||
pyexec = sys.executable
|
||||
ifile = min1r
|
||||
ofile = out_ged
|
||||
gcmd = "Gramps.py -i %s -e %s" % (ifile, ofile)
|
||||
process = subprocess.Popen("python3 %s" % gcmd,
|
||||
process = subprocess.Popen("%s %s" % (pyexec ,gcmd),
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, shell=True)
|
||||
@@ -104,10 +106,11 @@ class Test(unittest.TestCase):
|
||||
f.write("garbage")
|
||||
|
||||
# ~same as test 2
|
||||
pyexec = sys.executable
|
||||
ifile = min1r
|
||||
ofile = out_ged
|
||||
gcmd = "Gramps.py -i %s -e %s" % (ifile, ofile)
|
||||
process = subprocess.Popen("python3 %s" % gcmd,
|
||||
process = subprocess.Popen("%s %s" % (pyexec, gcmd),
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, shell=True)
|
||||
|
||||
@@ -269,6 +269,7 @@ register('interface.url-width', 600)
|
||||
register('interface.view', True)
|
||||
register('interface.width', 775)
|
||||
register('interface.surname-box-height', 150)
|
||||
register('interface.treemodel-cache-size', 1000)
|
||||
|
||||
register('paths.recent-export-dir', '')
|
||||
register('paths.recent-file', '')
|
||||
@@ -282,6 +283,7 @@ register('paths.quick-backup-filename',
|
||||
register('preferences.date-format', 0)
|
||||
register('preferences.calendar-format-report', 0)
|
||||
register('preferences.cprefix', 'C%04d')
|
||||
register('preferences.alternate-fonthandler', False)
|
||||
register('preferences.default-source', False)
|
||||
register('preferences.tag-on-import', False)
|
||||
register('preferences.tag-on-import-format', _("Imported %Y/%m/%d %H:%M:%S"))
|
||||
|
||||
@@ -55,10 +55,14 @@ from gramps.version import VERSION, VERSION_TUPLE, major_version
|
||||
#-------------------------------------------------------------------------
|
||||
URL_HOMEPAGE = "http://gramps-project.org/"
|
||||
URL_MAILINGLIST = "http://sourceforge.net/mail/?group_id=25770"
|
||||
URL_BUGHOME = "http://bugs.gramps-project.org"
|
||||
URL_BUGTRACKER = "http://bugs.gramps-project.org/bug_report_page.php"
|
||||
URL_BUGHOME = "http://gramps-project.org/bugs"
|
||||
URL_BUGTRACKER = "http://gramps-project.org/bugs/bug_report_page.php"
|
||||
URL_WIKISTRING = "http://gramps-project.org/wiki/index.php?title="
|
||||
URL_MANUAL_PAGE = "Gramps_%s_Wiki_Manual" % major_version
|
||||
URL_MANUAL_DATA = '%s_-_Entering_and_editing_data:_detailed' % URL_MANUAL_PAGE
|
||||
URL_MANUAL_SECT1 = '%s_-_part_1' % URL_MANUAL_DATA
|
||||
URL_MANUAL_SECT2 = '%s_-_part_2' % URL_MANUAL_DATA
|
||||
URL_MANUAL_SECT3 = '%s_-_part_3' % URL_MANUAL_DATA
|
||||
WIKI_FAQ = "FAQ"
|
||||
WIKI_KEYBINDINGS = "Gramps_%s_Wiki_Manual_-_Keybindings" % major_version
|
||||
WIKI_EXTRAPLUGINS= "%s_Addons" % major_version
|
||||
@@ -186,7 +190,7 @@ GTK_GETTEXT_DOMAIN = 'gtk30'
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
COPYRIGHT_MSG = "© 2001-2006 Donald N. Allingham\n" \
|
||||
"© 2007-2015 The Gramps Developers"
|
||||
"© 2007-2018 The Gramps Developers"
|
||||
COMMENTS = _("Gramps\n (Genealogical Research and Analysis "
|
||||
"Management Programming System)\n"
|
||||
"is a personal genealogy program.")
|
||||
|
||||
@@ -48,6 +48,8 @@ from . import _date_es
|
||||
from . import _date_fi
|
||||
from . import _date_fr
|
||||
from . import _date_hr
|
||||
from . import _date_hu
|
||||
from . import _date_is
|
||||
from . import _date_it
|
||||
from . import _date_ja
|
||||
from . import _date_lt
|
||||
|
||||
@@ -164,15 +164,20 @@ class DateParserCZ(DateParser):
|
||||
|
||||
quality_to_int = {
|
||||
'přibližně' : Date.QUAL_ESTIMATED,
|
||||
'odhadované' : Date.QUAL_ESTIMATED,
|
||||
'odhadem' : Date.QUAL_ESTIMATED,
|
||||
'odh.' : Date.QUAL_ESTIMATED,
|
||||
'vypočteno' : Date.QUAL_CALCULATED,
|
||||
'vypočtené' : Date.QUAL_CALCULATED,
|
||||
'vyp.' : Date.QUAL_CALCULATED,
|
||||
}
|
||||
|
||||
# bug 9739 _grampslocale.py gets '%-d.%-m.%Y' and makes it be '%/d.%/m.%Y'
|
||||
fmt = DateParser.fmt.replace('/', '') # so counteract that
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
self._text2 = re.compile('(\d+)?\.?\s+?%s\.?\s*((\d+)(/\d+)?)?\s*$'
|
||||
% self._mon_str, re.IGNORECASE)
|
||||
self._span = re.compile(
|
||||
"(od)\s+(?P<start>.+)\s+(do)\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
@@ -221,7 +226,12 @@ class DateDisplayCZ(DateDisplay):
|
||||
# this must agree with DateDisplayEn's "formats" definition
|
||||
# (since no locale-specific _display_gregorian exists, here)
|
||||
|
||||
def display(self, date):
|
||||
display = DateDisplay.display_formatted
|
||||
|
||||
# bug 9537 _grampslocale.py gets '%-d.%-m.%Y' and makes it be '%/d.%/m.%Y'
|
||||
_tformat = DateDisplay._tformat.replace('/', '') # so counteract that
|
||||
|
||||
def orig_display(self, date): # unused: only here for historical reference
|
||||
"""
|
||||
Return a text string representing the date.
|
||||
"""
|
||||
|
||||
@@ -221,7 +221,7 @@ class DateDisplayDE(DateDisplay):
|
||||
)
|
||||
# this definition must agree with its "_display_gregorian" method
|
||||
|
||||
def _display_gregorian(self, date_val):
|
||||
def _display_gregorian(self, date_val, **kwargs):
|
||||
"""
|
||||
display gregorian calendar date in different format
|
||||
"""
|
||||
|
||||
@@ -155,7 +155,7 @@ class DateDisplayEL(DateDisplay):
|
||||
)
|
||||
# this definition must agree with its "_display_gregorian" method
|
||||
|
||||
def _display_gregorian(self, date_val):
|
||||
def _display_gregorian(self, date_val, **kwargs):
|
||||
"""
|
||||
display gregorian calendar date in different format
|
||||
"""
|
||||
|
||||
@@ -57,8 +57,7 @@ class DateParserHR(DateParser):
|
||||
'po. ' : Date.MOD_AFTER,
|
||||
'okolo' : Date.MOD_ABOUT,
|
||||
'ok. ' : Date.MOD_ABOUT,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
'približno' : Date.QUAL_ESTIMATED,
|
||||
@@ -75,20 +74,20 @@ class DateParserHR(DateParser):
|
||||
compiles regular expression strings for matching dates
|
||||
"""
|
||||
DateParser.init_strings(self)
|
||||
#~ DateParser.calendar_to_int.update({
|
||||
#~ 'персидский' : Date.CAL_PERSIAN,
|
||||
#~ 'п' : Date.CAL_PERSIAN,
|
||||
#~ })
|
||||
_span_1 = ['od']
|
||||
_span_2 = ['do']
|
||||
_range_1 = ['između']
|
||||
_range_2 = ['i']
|
||||
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_span_1), '|'.join(_span_2)),
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1), '|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
# match 'Day. MONTH year.' format with or without dots
|
||||
self._text2 = re.compile('(\d+)?\.?\s*?%s\.?\s*((\d+)(/\d+)?)?\s*\.?$'
|
||||
% self._mon_str, re.IGNORECASE)
|
||||
|
||||
|
||||
# match Day.Month.Year.
|
||||
self._numeric = re.compile(
|
||||
"((\d+)[/\. ])?\s*((\d+)[/\.])?\s*(\d+)\.?$")
|
||||
#"((\d+)[/\.]\s*)?((\d+)[/\.]\s*)?(\d+)\s*$")
|
||||
self._span = re.compile(
|
||||
"(od)\s+(?P<start>.+)\s+(do)\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
self._jtext2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?'\
|
||||
% self._jmon_str, re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -105,6 +104,47 @@ class DateDisplayHR(DateDisplay):
|
||||
|
||||
display = DateDisplay.display_formatted
|
||||
|
||||
def dd_dformat01(self, date_val):
|
||||
"""
|
||||
numerical
|
||||
"""
|
||||
if date_val[3]:
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
if date_val[0] == date_val[1] == 0:
|
||||
return str(date_val[2]) + '.'
|
||||
else:
|
||||
value = self._tformat.replace('%m', str(date_val[1]))
|
||||
value = value.replace('%d', str(date_val[0]))
|
||||
value = value.replace('%Y', str(abs(date_val[2])))
|
||||
return value
|
||||
|
||||
def dd_dformat04(self, date_val, inflect, long_months):
|
||||
"""
|
||||
day month_name year
|
||||
|
||||
this must agree with DateDisplayEn's "formats" definition
|
||||
(it may be overridden if a locale-specific date displayer exists)
|
||||
"""
|
||||
|
||||
_ = self._locale.translation.sgettext
|
||||
year = self._slash_year(date_val[2], date_val[3])
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
return year + '.'
|
||||
else:
|
||||
return self.format_long_month_year(date_val[1], year,
|
||||
inflect, long_months)
|
||||
elif date_val[1] == 0: # month is zero but day is not (see 8477)
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
# TRANSLATORS: this month is ALREADY inflected: ignore it
|
||||
return _("{day:d} {long_month} {year}").format(
|
||||
day = date_val[0],
|
||||
long_month = self.format_long_month(date_val[1],
|
||||
inflect, long_months).replace(' .', ''),
|
||||
year = year)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Register classes
|
||||
|
||||
368
gramps/gen/datehandler/_date_hu.py
Normal file
368
gramps/gen/datehandler/_date_hu.py
Normal file
@@ -0,0 +1,368 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2004-2006 Donald N. Allingham
|
||||
# Copyright (C) 2015 Lajos Nemeséri <nemeseril@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
"""
|
||||
Hungarian-specific classes for parsing and displaying dates.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import re
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ..lib.date import Date
|
||||
from ._dateparser import DateParser
|
||||
from ._datedisplay import DateDisplay
|
||||
from ._datehandler import register_datehandler
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Hungarian parser
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateParserHU(DateParser):
|
||||
|
||||
|
||||
month_to_int = DateParser.month_to_int
|
||||
|
||||
month_to_int["-"]=0 #to make the Zero month to work
|
||||
|
||||
month_to_int["január"] = 1
|
||||
month_to_int["jan"] = 1
|
||||
month_to_int["jan."] = 1
|
||||
month_to_int["I"] = 1
|
||||
# month_to_int["i"] = 1
|
||||
|
||||
month_to_int["február"] = 2
|
||||
month_to_int["feb"] = 2
|
||||
month_to_int["feb."] = 2
|
||||
month_to_int["II"] = 2
|
||||
# month_to_int["ii"] = 2
|
||||
|
||||
month_to_int["március"] = 3
|
||||
month_to_int["márc"] = 3
|
||||
month_to_int["márc."] = 3
|
||||
month_to_int["III"] = 3
|
||||
# month_to_int["iii"] = 3
|
||||
|
||||
month_to_int["április"] = 4
|
||||
month_to_int["ápr"] = 4
|
||||
month_to_int["ápr."] = 4
|
||||
month_to_int["IV"] = 4
|
||||
# month_to_int["iv"] = 4
|
||||
|
||||
month_to_int["május"] = 5
|
||||
month_to_int["máj"] = 5
|
||||
month_to_int["máj."] = 5
|
||||
month_to_int["V"] = 5
|
||||
# month_to_int["v"] = 5
|
||||
|
||||
month_to_int["június"] = 6
|
||||
month_to_int["jún"] = 6
|
||||
month_to_int["jún."] = 6
|
||||
month_to_int["VI"] = 6
|
||||
# month_to_int["vi"] = 6
|
||||
|
||||
month_to_int["július"] = 7
|
||||
month_to_int["júl"] = 7
|
||||
month_to_int["júl."] = 7
|
||||
month_to_int["VII"] = 7
|
||||
# month_to_int["vii"] = 7
|
||||
|
||||
month_to_int["augusztus"] = 8
|
||||
month_to_int["aug"] = 8
|
||||
month_to_int["aug."] = 8
|
||||
month_to_int["VIII"] = 8
|
||||
# month_to_int["viii"] = 8
|
||||
|
||||
month_to_int["szeptember"] = 9
|
||||
month_to_int["szept"] = 9
|
||||
month_to_int["szept."] = 9
|
||||
month_to_int["IX"] = 9
|
||||
# month_to_int["ix"] = 9
|
||||
|
||||
month_to_int["október"] = 10
|
||||
month_to_int["okt"] = 10
|
||||
month_to_int["okt."] = 10
|
||||
month_to_int["X"] = 10
|
||||
# month_to_int["x"] = 10
|
||||
|
||||
month_to_int["november"] = 11
|
||||
month_to_int["nov"] = 11
|
||||
month_to_int["nov."] = 11
|
||||
month_to_int["XI"] = 11
|
||||
# month_to_int["xi"] = 11
|
||||
|
||||
month_to_int["december"] = 12
|
||||
month_to_int["dec"] = 12
|
||||
month_to_int["dec."] = 12
|
||||
month_to_int["XII"] = 12
|
||||
# month_to_int["xii"] = 12
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# Alternative and latin names - not verified
|
||||
#
|
||||
#-----------------------------------------------------------------------
|
||||
# Other common latin names
|
||||
|
||||
# month_to_int["januaris"] = 01
|
||||
# month_to_int["januarii"] = 01
|
||||
# month_to_int["januarius"] = 01
|
||||
# month_to_int["februaris"] = 02
|
||||
# month_to_int["februarii"] = 02
|
||||
# month_to_int["februarius"] = 02
|
||||
# month_to_int["martii"] = 03
|
||||
# month_to_int["martius"] = 03
|
||||
# month_to_int["aprilis"] = 04
|
||||
# month_to_int["maius"] = 05
|
||||
# month_to_int["maii"] = 05
|
||||
# month_to_int["junius"] = 06
|
||||
# month_to_int["junii"] = 06
|
||||
# month_to_int["julius"] = 07
|
||||
# month_to_int["julii"] = 07
|
||||
# month_to_int["augustus"] = 08
|
||||
# month_to_int["augusti"] = 08
|
||||
# month_to_int["septembris"] = 09
|
||||
# month_to_int["7bris"] = 09
|
||||
# month_to_int["september"] = 09
|
||||
# month_to_int["october"] = 10
|
||||
# month_to_int["octobris"] = 10
|
||||
# month_to_int["8bris"] = 10
|
||||
# month_to_int["novembris"] = 11
|
||||
# month_to_int["9bris"] = 11
|
||||
# month_to_int["november"] = 11
|
||||
# month_to_int["decembris"] = 12
|
||||
# month_to_int["10bris"] = 12
|
||||
# month_to_int["xbris"] = 12
|
||||
# month_to_int["december"] = 12
|
||||
|
||||
# old Hungarian names
|
||||
|
||||
# month_to_int["Boldogasszony hava"] = 01
|
||||
# month_to_int["Fergeteg hava"] = 01
|
||||
# month_to_int["Böjtelő hava"] = 02
|
||||
# month_to_int["Jégbontó hava"] = 02
|
||||
# month_to_int["Böjtmás hava"] = 03
|
||||
# month_to_int["Kikelet hava"] = 03
|
||||
# month_to_int["Szent György hava"] = 04
|
||||
# month_to_int["Szelek hava"] = 04
|
||||
# month_to_int["Pünkösd hava"] = 05
|
||||
# month_to_int["Ígéret hava"] = 05
|
||||
# month_to_int["Szent Iván hava"] = 06
|
||||
# month_to_int["Napisten hava"] = 06
|
||||
# month_to_int["Szent Jakab hava"] = 07
|
||||
# month_to_int["Áldás hava"] = 07
|
||||
# month_to_int["Kisasszony hava"] = 08
|
||||
# month_to_int["Újkenyér hava"] = 08
|
||||
# month_to_int["Szent Mihály hava"] = 09
|
||||
# month_to_int["Földanya hava"] = 09
|
||||
# month_to_int["Mindszent hava"] = 10
|
||||
# month_to_int["Magvető hava"] = 10
|
||||
# month_to_int["Szent András hava"] = 11
|
||||
# month_to_int["Enyészet hava"] = 11
|
||||
# month_to_int["Karácsony hava"] = 12
|
||||
# month_to_int["Álom hava"] = 12
|
||||
|
||||
modifier_after_to_int={
|
||||
'előtt' : Date.MOD_BEFORE,
|
||||
'körül' : Date.MOD_ABOUT,
|
||||
'után' : Date.MOD_AFTER,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
'becsült' : Date.QUAL_ESTIMATED,
|
||||
'hozzávetőleg' : Date.QUAL_ESTIMATED,
|
||||
'becs.' : Date.QUAL_ESTIMATED,
|
||||
'számított' : Date.QUAL_CALCULATED,
|
||||
'körülbelül' : Date.QUAL_ESTIMATED,
|
||||
'számolt' : Date.QUAL_CALCULATED,
|
||||
'szám.' : Date.QUAL_CALCULATED,
|
||||
}
|
||||
|
||||
bce = ["időszámításunk előtt", "időszámítás előtt", "i. e.",
|
||||
"Krisztus előtt", "Krisztus előtti", "Kr. e."] + DateParser.bce
|
||||
|
||||
|
||||
calendar_to_int = {
|
||||
'Gergely' : Date.CAL_GREGORIAN,
|
||||
'Julián' : Date.CAL_JULIAN,
|
||||
'héber' : Date.CAL_HEBREW,
|
||||
'iszlám' : Date.CAL_ISLAMIC,
|
||||
'francia köztársasági' : Date.CAL_FRENCH,
|
||||
'perzsa' : Date.CAL_PERSIAN,
|
||||
'svéd' : Date.CAL_SWEDISH,
|
||||
}
|
||||
|
||||
|
||||
def init_strings(self):
|
||||
# Compiles regular expression strings for matching dates
|
||||
DateParser.init_strings(self)
|
||||
|
||||
self._numeric = re.compile(
|
||||
"((\d+)[/\.])?\s*((\d+)[/\.])?\s*(\d+)[/\. ]?$")
|
||||
self._text2 = re.compile('((\d+)(/\d+)?\.)?\s+?%s\.?\s*(\d+\.)?\s*$'
|
||||
% self._mon_str, re.IGNORECASE)
|
||||
_span_1 = ['-tó\(ő\)l', '-tól', '-től']
|
||||
_span_2 = ['-ig']
|
||||
_range_1 = ['és']
|
||||
_range_2 = ['között']
|
||||
self._span = re.compile("(?P<start>.+)(%s)\s+(?P<stop>.+)(%s)" %
|
||||
('|'.join(_span_1), '|'.join(_span_2)),
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(?P<start>.+)\s+(%s)\s+(?P<stop>.+)\s+(%s)" %
|
||||
('|'.join(_range_1), '|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
|
||||
|
||||
def _get_int(self, val):
|
||||
"""
|
||||
Convert the string to an integer if the value is not None. If the
|
||||
value is None, a zero is returned
|
||||
"""
|
||||
if val is None:
|
||||
return 0
|
||||
else:
|
||||
return int(val.replace('.', ''))
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Hungarian display
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateDisplayHU(DateDisplay):
|
||||
"""
|
||||
Hungarian language date display class.
|
||||
"""
|
||||
|
||||
_bce_str = "i. e. %s"
|
||||
|
||||
roman_months=(
|
||||
"-.", "I.", "II.", "III.", "IV.", "V.", "VI.",
|
||||
"VII.", "VIII.", "IX.", "X.", "XI.", "XII."
|
||||
)
|
||||
|
||||
formats = (
|
||||
"ÉÉÉÉ-HH-NN (ISO)", # 0
|
||||
"Alapértelmezett éééé. hh. nn.", # 1
|
||||
"Év hónap nap", # year, full month name, day # 2
|
||||
"Év hó nap", #year, short month name, day # 3
|
||||
"Év római h.sz. nap" #year, Roman number, day # 4
|
||||
)
|
||||
# this definition must agree with its "_display_calendar" method
|
||||
|
||||
display = DateDisplay.display_formatted
|
||||
|
||||
def _display_calendar(self, date_val, long_months, short_months = None,
|
||||
inflect=""):
|
||||
# this must agree with its locale-specific "formats" definition
|
||||
|
||||
year = self._slash_year(date_val[2], date_val[3])
|
||||
|
||||
if short_months is None:
|
||||
# Let the short formats work the same as long formats
|
||||
short_months = long_months
|
||||
|
||||
if self.format == 0:
|
||||
return self.display_iso(date_val)
|
||||
|
||||
elif self.format == 1:
|
||||
# Base defined Hungarian form
|
||||
if date_val[3]:
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
if date_val[0]==0: #No day
|
||||
if date_val[1]==0: #No month -> year
|
||||
value="%s" % year
|
||||
else:
|
||||
value="%s. %02d." % (year, date_val[1]) #If no day -> year, month
|
||||
else:
|
||||
value="%s. %02d. %02d." % (year, date_val[1], date_val[0])
|
||||
|
||||
elif self.format == 2:
|
||||
# year, full month name, day
|
||||
|
||||
if date_val[0]==0:
|
||||
if date_val[1]==0:
|
||||
value="%s" % year
|
||||
else:
|
||||
value="%s. %s" % (year, self.long_months[date_val[1]]) #If no day -> year, month
|
||||
else:
|
||||
if date_val[1]==0:
|
||||
value="%s. %s %02d." % (year, '-', date_val[0]) #To indicate somehow if the month is missing
|
||||
else:
|
||||
value="%s. %s %02d." % (year, self.long_months[date_val[1]], date_val[0])
|
||||
|
||||
|
||||
elif self.format == 3:
|
||||
#year, short month name, day
|
||||
|
||||
if date_val[0]==0:
|
||||
if date_val[1]==0:
|
||||
value="%s" % year
|
||||
else:
|
||||
value="%s. %s" % (year, self.short_months[date_val[1]]) #If no day -> year, month
|
||||
else:
|
||||
if date_val[1]==0:
|
||||
value="%s. %s %02d." % (year, '-.', date_val[0]) #To indicate somehow if the month is missing
|
||||
else:
|
||||
value="%s. %s %02d." % (year, self.short_months[date_val[1]], date_val[0])
|
||||
|
||||
|
||||
elif self.format == 4:
|
||||
#year, Roman number, day
|
||||
|
||||
if date_val[0]==0:
|
||||
if date_val[1]==0:
|
||||
value="%s" % year
|
||||
else:
|
||||
value="%s. %s" % (year, self.roman_months[date_val[1]]) #If no day -> year, month
|
||||
else:
|
||||
value="%s. %s %02d." % (year, self.roman_months[date_val[1]], date_val[0])
|
||||
|
||||
|
||||
else:
|
||||
# day month_name year
|
||||
value = self.dd_dformat04(date_val, inflect, long_months)
|
||||
|
||||
if date_val[2] < 0:
|
||||
# TODO fix BUG 7064: non-Gregorian calendars wrongly use BCE notation for negative dates
|
||||
return self._bce_str % value
|
||||
else:
|
||||
return value
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Register classes
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
register_datehandler(('hu_HU', 'hu', 'hungarian', 'Hungarian', 'magyar'),
|
||||
DateParserHU, DateDisplayHU)
|
||||
180
gramps/gen/datehandler/_date_is.py
Normal file
180
gramps/gen/datehandler/_date_is.py
Normal file
@@ -0,0 +1,180 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2004-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Attempt to parse dates for Icelandic, Sveinn í Felli 2016
|
||||
|
||||
"""
|
||||
Icelandic-specific classes for parsing and displaying dates.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import re
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ..lib.date import Date
|
||||
from ._dateparser import DateParser
|
||||
from ._datedisplay import DateDisplay
|
||||
from ._datehandler import register_datehandler
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Icelandic parser class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateParserIs(DateParser):
|
||||
"""
|
||||
Convert a text string into a Date object, expecting a date
|
||||
notation in the Icelandic language. If the date cannot be converted,
|
||||
the text string is assigned.
|
||||
"""
|
||||
|
||||
# modifiers before the date
|
||||
modifier_to_int = {
|
||||
'fyrir' : Date.MOD_BEFORE,
|
||||
'á undan' : Date.MOD_BEFORE,
|
||||
'eftir' : Date.MOD_AFTER,
|
||||
'í kringum' : Date.MOD_ABOUT,
|
||||
'uþb' : Date.MOD_ABOUT
|
||||
}
|
||||
|
||||
bce = ["f Kr"]
|
||||
|
||||
calendar_to_int = {
|
||||
'gregoríanskt ' : Date.CAL_GREGORIAN,
|
||||
'g' : Date.CAL_GREGORIAN,
|
||||
'júlíanskt' : Date.CAL_JULIAN,
|
||||
'j' : Date.CAL_JULIAN,
|
||||
'hebreskt' : Date.CAL_HEBREW,
|
||||
'h' : Date.CAL_HEBREW,
|
||||
'íslamskt' : Date.CAL_ISLAMIC,
|
||||
'múslimskt' : Date.CAL_ISLAMIC,
|
||||
'i' : Date.CAL_ISLAMIC,
|
||||
'franskt' : Date.CAL_FRENCH,
|
||||
'franska lýðveldisins' : Date.CAL_FRENCH,
|
||||
'f' : Date.CAL_FRENCH,
|
||||
'persneskt' : Date.CAL_PERSIAN,
|
||||
'p' : Date.CAL_PERSIAN,
|
||||
'sænskt' : Date.CAL_SWEDISH,
|
||||
's' : Date.CAL_SWEDISH,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
'áætlað' : Date.QUAL_ESTIMATED,
|
||||
'reiknað' : Date.QUAL_CALCULATED,
|
||||
}
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
self._span = re.compile("(frá)?\s*(?P<start>.+)\s*(til|--|–)\s*(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(milli)\s+(?P<start>.+)\s+og\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Icelandic display class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateDisplayIs(DateDisplay):
|
||||
"""
|
||||
Icelandic language date display class.
|
||||
"""
|
||||
|
||||
long_months = ( "", "janúar", "febrúar", "mars", "apríl", "maí",
|
||||
"júní", "júlí", "ágúst", "september", "október",
|
||||
"nóvember", "desember" )
|
||||
|
||||
short_months = ( "", "jan", "feb", "mar", "apr", "maí", "jún",
|
||||
"júl", "ágú", "sep", "okt", "nóv", "des" )
|
||||
|
||||
formats = (
|
||||
"ÁÁÁÁ-MM-DD (ISO)",
|
||||
"Tölulegt",
|
||||
"Mánuður dagur, ár",
|
||||
"Mán Dag Ár",
|
||||
"Dagur mánuður ár",
|
||||
"Dag Mán Ár",
|
||||
)
|
||||
# this must agree with DateDisplayEn's "formats" definition
|
||||
# (since no locale-specific _display_gregorian exists, here)
|
||||
|
||||
calendar = (
|
||||
"",
|
||||
"júlíanskt",
|
||||
"hebreskt",
|
||||
"franska lýðveldisins",
|
||||
"persneskt",
|
||||
"íslamskt",
|
||||
"sænskt"
|
||||
)
|
||||
|
||||
_mod_str = ("", "fyrir ", "eftir ", "uþb ", "", "", "")
|
||||
|
||||
_qual_str = ("", "reiknað ", "reiknað ")
|
||||
|
||||
_bce_str = "%s f. Kr"
|
||||
|
||||
def display(self, date):
|
||||
"""
|
||||
Return a text string representing the date.
|
||||
"""
|
||||
mod = date.get_modifier()
|
||||
cal = date.get_calendar()
|
||||
qual = date.get_quality()
|
||||
start = date.get_start_date()
|
||||
newyear = date.get_new_year()
|
||||
|
||||
qual_str = self._qual_str[qual]
|
||||
|
||||
if mod == Date.MOD_TEXTONLY:
|
||||
return date.get_text()
|
||||
elif start == Date.EMPTY:
|
||||
return ""
|
||||
elif mod == Date.MOD_SPAN:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%sfrá %s til %s%s" % (qual_str, d1, d2, scal)
|
||||
elif mod == Date.MOD_RANGE:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%smilli %s og %s%s" % (qual_str, d1, d2,
|
||||
scal)
|
||||
else:
|
||||
text = self.display_cal[date.get_calendar()](start)
|
||||
scal = self.format_extras(cal, newyear)
|
||||
return "%s%s%s%s" % (qual_str, self._mod_str[mod],
|
||||
text, scal)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Register classes
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
register_datehandler(('is_IS', 'is', 'íslenskt', 'Icelandic'), DateParserIs, DateDisplayIs)
|
||||
@@ -130,6 +130,8 @@ class DateParserLT(DateParser):
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
self._text2 = re.compile('((\d+)(/\d+)?)?\s+?m\.\s+%s\s*(\d+)?\s*d?\.?$'
|
||||
% self._mon_str, re.IGNORECASE)
|
||||
_span_1 = ['nuo']
|
||||
_span_2 = ['iki']
|
||||
_range_1 = ['tarp']
|
||||
@@ -141,27 +143,6 @@ class DateParserLT(DateParser):
|
||||
('|'.join(_range_1), '|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# FIXME: oficial long date format (ex, 2011 m. vasario 4 d.)
|
||||
# is not recognized correctly:
|
||||
# with self._text2 - day is recognized as year, year - as day
|
||||
# with self._iso - month not recognized, day recognized,
|
||||
# year increased by 1, date treated as double
|
||||
# TODO: in _DateParser.py in _parse_calendar modify groups
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# # gregorian and julian
|
||||
#
|
||||
# self._text2 = re.compile('(\d+)?\s*?m\.?\s*?%s\.?\s*((\d+)(/\d+)?)?\s*?d?\.?' %
|
||||
# self._mon_str, re.IGNORECASE)
|
||||
#
|
||||
# self._iso = re.compile('(\d+)(/\d+)?\s*?m?\.?\s+?%s\.?\s*((\d+))?\s*?d?\.?' %
|
||||
# self._mon_str, re.IGNORECASE)
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Lithuanian displayer
|
||||
@@ -204,7 +185,7 @@ class DateDisplayLT(DateDisplay):
|
||||
"mmmm-MM-DD (ISO)", "mmmm m. mėnesio diena d.", "Mėn diena, metai")
|
||||
# this definition must agree with its "_display_gregorian" method
|
||||
|
||||
def _display_gregorian(self, date_val):
|
||||
def _display_gregorian(self, date_val, **kwargs):
|
||||
"""
|
||||
display gregorian calendar date in different format
|
||||
"""
|
||||
|
||||
@@ -164,7 +164,7 @@ class DateDisplayNL(DateDisplay):
|
||||
)
|
||||
# this definition must agree with its "_display_gregorian" method
|
||||
|
||||
def _display_gregorian(self, date_val):
|
||||
def _display_gregorian(self, date_val, **kwargs):
|
||||
"""
|
||||
display gregorian calendar date in different format
|
||||
"""
|
||||
|
||||
@@ -215,7 +215,7 @@ class DateDisplayPL(DateDisplay):
|
||||
"XII"
|
||||
)
|
||||
|
||||
def _display_gregorian(self, date_val):
|
||||
def _display_gregorian(self, date_val, **kwargs):
|
||||
"""
|
||||
display gregorian calendar date in different format
|
||||
"""
|
||||
|
||||
@@ -130,12 +130,33 @@ class DateDisplayRU(DateDisplay):
|
||||
else:
|
||||
return self.format_long_month_year(date_val[1], year,
|
||||
inflect, long_months)
|
||||
elif date_val[1] == 0: # month is zero but day is not (see 8477)
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
return "{day:d} {long_month.f[Р]} {year}".format(
|
||||
day = date_val[0],
|
||||
long_month = long_months[date_val[1]],
|
||||
year = year)
|
||||
|
||||
def dd_dformat05(self, date_val, inflect, short_months):
|
||||
"""
|
||||
day month_abbreviation year -- for Russian locale
|
||||
"""
|
||||
year = self._slash_year(date_val[2], date_val[3])
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
return year
|
||||
else:
|
||||
return self.format_short_month_year(date_val[1], year,
|
||||
inflect, short_months)
|
||||
elif date_val[1] == 0: # month is zero but day is not (see 8477)
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
return "{day:d} {short_month.f[Р]} {year}".format(
|
||||
day = date_val[0],
|
||||
short_month = short_months[date_val[1]],
|
||||
year = year)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Register classes
|
||||
|
||||
@@ -240,7 +240,7 @@ class DateDisplaySR_Base(DateDisplay):
|
||||
"VII", "VIII", "IX", "X", "XI", "XII"
|
||||
)
|
||||
|
||||
def _display_gregorian(self, date_val):
|
||||
def _display_gregorian(self, date_val, **kwargs):
|
||||
"""
|
||||
display gregorian calendar date in different format
|
||||
"""
|
||||
|
||||
@@ -194,6 +194,7 @@ class DateParser(object):
|
||||
|
||||
_locale = GrampsLocale(lang='en', languages='en')
|
||||
|
||||
fmt = _grampslocale.tformat
|
||||
_fmt_parse = re.compile(".*%(\S).*%(\S).*%(\S).*")
|
||||
|
||||
# RFC-2822 only uses capitalized English abbreviated names, no locales.
|
||||
@@ -343,13 +344,13 @@ class DateParser(object):
|
||||
Date.CAL_SWEDISH : self._parse_swedish,
|
||||
}
|
||||
|
||||
fmt = _grampslocale.tformat
|
||||
match = self._fmt_parse.match(fmt.lower())
|
||||
match = self._fmt_parse.match(self.fmt.lower())
|
||||
if match:
|
||||
self.dmy = (match.groups() == ('d', 'm', 'y') or \
|
||||
match.groups() == ('d', 'b', 'y'))
|
||||
self.ymd = (match.groups() == ('y', 'm', 'd') or \
|
||||
match.groups() == ('y', 'b', 'd'))
|
||||
# note ('m','d','y') is valid -- in which case both will be False
|
||||
else:
|
||||
self.dmy = True
|
||||
self.ymd = False
|
||||
@@ -527,22 +528,38 @@ class DateParser(object):
|
||||
match = regex2.match(text.lower())
|
||||
if match:
|
||||
groups = match.groups()
|
||||
if groups[1] is None:
|
||||
m = 0
|
||||
else:
|
||||
m = mmap[groups[1].lower()]
|
||||
d = self._get_int(groups[0])
|
||||
|
||||
if groups[2] is None:
|
||||
y = None
|
||||
s = False
|
||||
else:
|
||||
if groups[4] is not None: # slash year digit
|
||||
y = int(groups[3]) + 1 # fullyear + 1
|
||||
s = True
|
||||
if self.ymd:
|
||||
if groups[3] is None:
|
||||
m = 0
|
||||
else:
|
||||
y = int(groups[3])
|
||||
m = mmap[groups[3].lower()]
|
||||
d = self._get_int(groups[4])
|
||||
if groups[0] is None:
|
||||
y = None
|
||||
s = False
|
||||
else:
|
||||
if groups[2] is not None: # slash year digit
|
||||
y = int(groups[1]) + 1 # fullyear + 1
|
||||
s = True
|
||||
else: # regular, non-slash year
|
||||
y = int(groups[1])
|
||||
s = False
|
||||
else:
|
||||
if groups[1] is None:
|
||||
m = 0
|
||||
else:
|
||||
m = mmap[groups[1].lower()]
|
||||
d = self._get_int(groups[0])
|
||||
if groups[2] is None:
|
||||
y = None
|
||||
s = False
|
||||
else:
|
||||
if groups[4] is not None: # slash year digit
|
||||
y = int(groups[3]) + 1 # fullyear + 1
|
||||
s = True
|
||||
else: # regular, non-slash year
|
||||
y = int(groups[3])
|
||||
s = False
|
||||
value = (d, m, y, s)
|
||||
if check and not check((d, m, y)):
|
||||
value = Date.EMPTY
|
||||
@@ -580,12 +597,11 @@ class DateParser(object):
|
||||
y = self._get_int(groups[0])
|
||||
m = self._get_int(groups[3])
|
||||
d = self._get_int(groups[4])
|
||||
if check and not check((d, m, y)):
|
||||
return Date.EMPTY
|
||||
if groups[2]: # slash year digit
|
||||
if groups[2] and julian_valid((d, m, y + 1)): # slash year digit
|
||||
return (d, m, y + 1, True)
|
||||
else:
|
||||
if check is None or check((d, m, y)):
|
||||
return (d, m, y, False)
|
||||
return Date.EMPTY
|
||||
|
||||
# Database datetime format, used in ex. MSSQL
|
||||
# YYYYMMDD HH:MM:SS or YYYYMMDD or YYYYMMDDHHMMSS
|
||||
@@ -622,6 +638,10 @@ class DateParser(object):
|
||||
y = self._get_int(groups[4])
|
||||
m = 0
|
||||
d = 0
|
||||
elif groups[3] is None:
|
||||
y = self._get_int(groups[1])
|
||||
m = self._get_int(groups[4])
|
||||
d = 0
|
||||
else:
|
||||
y = self._get_int(groups[1])
|
||||
m = self._get_int(groups[3])
|
||||
|
||||
@@ -21,6 +21,21 @@
|
||||
|
||||
"""
|
||||
Date strings to translate per each language for display and parsing.
|
||||
|
||||
__main__
|
||||
--------
|
||||
|
||||
Run this code with the appropriate ``LANG`` and ``LC_DATE`` set for your target
|
||||
language, in order to generate the .po snippets initialized with the strings
|
||||
from your locale (from the deprecated data provided in _grampslocale).
|
||||
|
||||
E.g., for French::
|
||||
|
||||
LANG=fr_FR.utf8 LC_ALL=fr_FR.utf8 GRAMPS_RESOURCES=$PWD python -m gramps.gen.datehandler._datestrings
|
||||
|
||||
Then merge the output into your language's .po file, and further modify the
|
||||
strings as needed. Then remove the strings from your language's
|
||||
:class:`DateParserXX` and :class:`DateHandlerXX` classes.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -233,23 +248,6 @@ class DateStrings(object):
|
||||
_("Saturday"),
|
||||
)
|
||||
|
||||
__doc__ += """
|
||||
__main__
|
||||
--------
|
||||
|
||||
Run this code with the appropriate ``LANG`` and ``LC_DATE`` set for your target
|
||||
language, in order to generate the .po snippets initialized with the strings
|
||||
from your locale (from the deprecated data provided in _grampslocale).
|
||||
|
||||
E.g., for French::
|
||||
|
||||
LANG=fr_FR.utf8 LC_ALL=fr_FR.utf8 GRAMPS_RESOURCES=$PWD python -m gramps.gen.datehandler._datestrings
|
||||
|
||||
Then merge the output into your language's .po file, and further modify the
|
||||
strings as needed. Then remove the strings from your language's
|
||||
:class:`DateParserXX` and :class:`DateHandlerXX` classes.
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
from ..utils.grampslocale import GrampsLocale
|
||||
|
||||
@@ -186,6 +186,8 @@ except:
|
||||
'10/25/2005' : '%m/%d/%Y',
|
||||
'2005/10/25' : '%Y/%m/%d',
|
||||
'25.10.2005' : '%d.%m.%Y',
|
||||
'25.10.2005.' : '%d.%m.%Y.',
|
||||
'25. 10. 2005.' : '%d. %m. %Y.',
|
||||
'10.25.2005' : '%m.%d.%Y',
|
||||
'2005.10.25' : '%Y.%m.%d',
|
||||
}
|
||||
|
||||
@@ -66,16 +66,30 @@ class DateDisplayInflectionsTestRU(DateDisplayTest):
|
||||
self.assertIn(month_lexeme.f[inflection],
|
||||
self.dd.display(date))
|
||||
|
||||
def test_month_only_date_nominative(self):
|
||||
for qual in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, Date.QUAL_CALCULATED):
|
||||
d1945may = Date(1945, 5, 0)
|
||||
d1945may.set_quality(qual)
|
||||
self.assertInflectionInDate('И', d1945may)
|
||||
def test_month_only_date_nominative_quality_none(self):
|
||||
d1945may = Date(1945, 5, 0)
|
||||
d1945may.set_quality(Date.QUAL_NONE)
|
||||
self.assertInflectionInDate('И', d1945may)
|
||||
|
||||
def test_month_only_date_nominative_quality_estimated(self):
|
||||
d1945may = Date(1945, 5, 0)
|
||||
d1945may.set_quality(Date.QUAL_ESTIMATED)
|
||||
self.assertInflectionInDate('Т', d1945may)
|
||||
|
||||
def test_month_only_date_nominative_quality_calculated(self):
|
||||
d1945may = Date(1945, 5, 0)
|
||||
d1945may.set_quality(Date.QUAL_CALCULATED)
|
||||
self.assertInflectionInDate('И', d1945may)
|
||||
|
||||
def test_day_month_date_genitive(self):
|
||||
d1945may9 = Date(1945, 5, 9)
|
||||
self.assertInflectionInDate('Р', d1945may9)
|
||||
|
||||
def test_day_month_date_genitiive_quality_estimated(self):
|
||||
d1945may9 = Date(1945, 5, 9)
|
||||
d1945may9.set_quality(Date.QUAL_ESTIMATED)
|
||||
self.assertInflectionInDate('Р', d1945may9)
|
||||
|
||||
def test_before_month_only_date_genitive(self):
|
||||
d1945may = Date(1945, 5, 0)
|
||||
d1945may.set_modifier(Date.MOD_BEFORE)
|
||||
@@ -86,6 +100,26 @@ class DateDisplayInflectionsTestRU(DateDisplayTest):
|
||||
# will be the same!
|
||||
self.assertIn("до мая", self.dd.display(d1945may))
|
||||
|
||||
def test_after_month_only_date_genitive(self):
|
||||
d1945may = Date(1945, 5, 0)
|
||||
d1945may.set_modifier(Date.MOD_AFTER)
|
||||
# TODO hardwired magic numbers! Bad API smell.
|
||||
for inflecting_format in (3,4):
|
||||
self.dd.set_format(inflecting_format)
|
||||
# this depends on the fact that in Russian the short and long forms for May
|
||||
# will be the same!
|
||||
self.assertIn("после мая", self.dd.display(d1945may))
|
||||
|
||||
def test_about_month_only_date_genitive(self):
|
||||
d1945may = Date(1945, 5, 0)
|
||||
d1945may.set_modifier(Date.MOD_ABOUT)
|
||||
# TODO hardwired magic numbers! Bad API smell.
|
||||
for inflecting_format in (3,4):
|
||||
self.dd.set_format(inflecting_format)
|
||||
# this depends on the fact that in Russian the short and long forms for May
|
||||
# will be the same!
|
||||
self.assertIn("около мая", self.dd.display(d1945may))
|
||||
|
||||
def test_between_month_only_dates_ablative(self):
|
||||
b1945may_1946may = Date()
|
||||
b1945may_1946may.set(
|
||||
|
||||
@@ -1968,7 +1968,7 @@ class DbBsddbRead(DbReadBase, Callback):
|
||||
"""
|
||||
filepath = os.path.join(self.path, "name.txt")
|
||||
try:
|
||||
name_file = open(filepath, "r")
|
||||
name_file = open(filepath, "r", encoding='utf-8')
|
||||
name = name_file.readline().strip()
|
||||
name_file.close()
|
||||
except (OSError, IOError) as msg:
|
||||
|
||||
@@ -44,10 +44,6 @@ _ = glocale.translation.gettext
|
||||
from ..constfunc import handle2internal
|
||||
from ..lib.markertype import MarkerType
|
||||
from ..lib.nameorigintype import NameOriginType
|
||||
from ..lib.place import Place
|
||||
from ..lib.placeref import PlaceRef
|
||||
from ..lib.placetype import PlaceType
|
||||
from ..lib.placename import PlaceName
|
||||
from ..lib.eventtype import EventType
|
||||
from ..lib.tag import Tag
|
||||
from ..utils.file import create_checksum
|
||||
@@ -95,14 +91,10 @@ def gramps_upgrade_18(self):
|
||||
for handle in self.place_map.keys():
|
||||
place = self.place_map[handle]
|
||||
new_place = list(place)
|
||||
name = PlaceName()
|
||||
name.set_value(new_place[6])
|
||||
new_place[6] = name.serialize()
|
||||
new_place[6] = (new_place[6], None, '')
|
||||
alt_names = []
|
||||
for name in new_place[7]:
|
||||
alt_name = PlaceName()
|
||||
alt_name.set_value(name)
|
||||
alt_names.append(alt_name.serialize())
|
||||
alt_names.append((name, None, ''))
|
||||
new_place[7] = alt_names
|
||||
new_place = tuple(new_place)
|
||||
with BSDDBTxn(self.env, self.place_map) as txn:
|
||||
@@ -204,15 +196,17 @@ def gramps_upgrade_17(self):
|
||||
n -= 1
|
||||
|
||||
if parent_handle is not None:
|
||||
placeref = PlaceRef()
|
||||
placeref.ref = handle2internal(parent_handle)
|
||||
placeref_list = [placeref.serialize()]
|
||||
placeref_list = [(handle2internal(parent_handle), None)]
|
||||
else:
|
||||
placeref_list = []
|
||||
|
||||
type_num = 7 - level if name else PlaceType.UNKNOWN
|
||||
if name:
|
||||
type_num = 7 - level
|
||||
else:
|
||||
name = new_place[2]
|
||||
type_num = -1
|
||||
new_place = new_place[:5] + [placeref_list, name, [],
|
||||
PlaceType(type_num).serialize(), zip_code] + \
|
||||
(type_num, ''), zip_code] + \
|
||||
new_place[6:12] + [[]] + new_place[12:]
|
||||
new_place = tuple(new_place)
|
||||
with BSDDBTxn(self.env, self.place_map) as txn:
|
||||
@@ -335,21 +329,19 @@ def get_location(loc):
|
||||
|
||||
def add_place(self, name, level, parent, title):
|
||||
handle = create_id()
|
||||
place = Place()
|
||||
place.handle = handle
|
||||
self.max_id += 1
|
||||
place.gramps_id = self.place_prefix % self.max_id
|
||||
place.set_name(name)
|
||||
place.set_title(title)
|
||||
place.set_type(PlaceType(7-level))
|
||||
gid = self.place_prefix % self.max_id
|
||||
placetype = (7-level, '')
|
||||
if parent is not None:
|
||||
placeref = PlaceRef()
|
||||
placeref.ref = handle2internal(parent)
|
||||
place.set_placeref_list([placeref])
|
||||
placeref_list = [(handle2internal(parent), None)]
|
||||
else:
|
||||
placeref_list = []
|
||||
place = (handle, gid, title, '', '', placeref_list, name, [], placetype,
|
||||
'', [], [], [], [], [], 0, [], False)
|
||||
with BSDDBTxn(self.env, self.place_map) as txn:
|
||||
if isinstance(handle, str):
|
||||
handle = handle.encode('utf-8')
|
||||
txn.put(handle, place.serialize())
|
||||
txn.put(handle, place)
|
||||
return handle
|
||||
|
||||
def upgrade_datamap_17(datamap):
|
||||
|
||||
@@ -722,8 +722,11 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
|
||||
# Check for pickle upgrade
|
||||
versionpath = os.path.join(self.path, str(PCKVERSFN))
|
||||
if not os.path.isfile(versionpath) and \
|
||||
not self.readonly and not self.update_pickle_version:
|
||||
# Up to gramps 3.4.x PCKVERSFN was not written
|
||||
# Gramps 4.2 incorrectly wrote PCKVERSFN = 'Yes' for Python2, so check
|
||||
# whether python is upgraded
|
||||
if ((not self.readonly and not self.update_pickle_version) and
|
||||
(not os.path.isfile(versionpath) or self.update_python_version)):
|
||||
_LOG.debug("Make backup in case there is a pickle upgrade")
|
||||
self.__make_zip_backup(name)
|
||||
self.update_pickle_version = True
|
||||
@@ -760,11 +763,11 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
|
||||
# The DB_PRIVATE flag must go if we ever move to multi-user setup
|
||||
env_flags = db.DB_CREATE | db.DB_PRIVATE |\
|
||||
db.DB_INIT_MPOOL |\
|
||||
db.DB_INIT_LOG | db.DB_INIT_TXN
|
||||
|
||||
# As opposed to before, we always try recovery on databases
|
||||
env_flags |= db.DB_RECOVER
|
||||
db.DB_INIT_MPOOL
|
||||
if not self.readonly:
|
||||
env_flags |= db.DB_INIT_LOG | db.DB_INIT_TXN
|
||||
# As opposed to before, we always try recovery on databases
|
||||
env_flags |= db.DB_RECOVER
|
||||
|
||||
# Environment name is now based on the filename
|
||||
env_name = name
|
||||
@@ -779,7 +782,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
pass
|
||||
raise DbEnvironmentError(msg)
|
||||
|
||||
self.env.txn_checkpoint()
|
||||
if not self.readonly:
|
||||
self.env.txn_checkpoint()
|
||||
|
||||
if callback:
|
||||
callback(25)
|
||||
@@ -1475,7 +1479,8 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
|
||||
return
|
||||
if self.txn:
|
||||
self.transaction_abort(self.transaction)
|
||||
self.env.txn_checkpoint()
|
||||
if not self.readonly:
|
||||
self.env.txn_checkpoint()
|
||||
|
||||
self.__close_metadata()
|
||||
self.name_group.close()
|
||||
|
||||
@@ -74,7 +74,6 @@ class DbState(Callback):
|
||||
config.get('preferences.rprefix'),
|
||||
config.get('preferences.nprefix') )
|
||||
self.open = True
|
||||
self.signal_change()
|
||||
|
||||
def signal_change(self):
|
||||
"""
|
||||
|
||||
@@ -32,7 +32,7 @@ Specific symbols for parts of a name are defined:
|
||||
'f' given (first names)
|
||||
'l' full surname (lastname)
|
||||
'c' callname
|
||||
'x' nick name if existing, otherwise first first name (common name)
|
||||
'x' nick name, call, or otherwise first first name (common name)
|
||||
'i' initials of the first names
|
||||
'm' primary surname (main)
|
||||
'0m' primary surname prefix
|
||||
@@ -567,7 +567,7 @@ class NameDisplay(object):
|
||||
'f' : given = given (first names)
|
||||
'l' : surname = full surname (lastname)
|
||||
'c' : call = callname
|
||||
'x' : common = nick name if existing, otherwise first first name (common name)
|
||||
'x' : common = nick name, call, otherwise first first name (common name)
|
||||
'i' : initials = initials of the first names
|
||||
'm' : primary = primary surname (main)
|
||||
'0m': primary[pre]= prefix primary surname (main)
|
||||
@@ -601,7 +601,7 @@ class NameDisplay(object):
|
||||
_("suffix")),
|
||||
"c": ("raw_data[_CALL]", "call",
|
||||
_("Name|call")),
|
||||
"x": ("(raw_data[_NICK] or raw_data[_FIRSTNAME].split(' ')[0])",
|
||||
"x": ("(raw_data[_NICK] or raw_data[_CALL] or raw_data[_FIRSTNAME].split(' ')[0])",
|
||||
"common",
|
||||
_("Name|common")),
|
||||
"i": ("''.join([word[0] +'.' for word in ('. ' +" +
|
||||
@@ -668,7 +668,7 @@ class NameDisplay(object):
|
||||
'f' : given = given (first names)
|
||||
'l' : surname = full surname (lastname)
|
||||
'c' : call = callname
|
||||
'x' : common = nick name if existing, otherwise first first name (common name)
|
||||
'x' : common = nick name, call, or otherwise first first name (common name)
|
||||
'i' : initials = initials of the first names
|
||||
'm' : primary = primary surname (main)
|
||||
'0m': primary[pre]= prefix primary surname (main)
|
||||
@@ -701,7 +701,7 @@ class NameDisplay(object):
|
||||
_("suffix")),
|
||||
"c": ("call", "call",
|
||||
_("Name|call")),
|
||||
"x": ("(nick or first.split(' ')[0])", "common",
|
||||
"x": ("(nick or call or first.split(' ')[0])", "common",
|
||||
_("Name|common")),
|
||||
"i": ("''.join([word[0] +'.' for word in ('. ' + first).split()][1:])",
|
||||
"initials",
|
||||
@@ -770,7 +770,7 @@ class NameDisplay(object):
|
||||
'%f' : given (first names)
|
||||
'%l' : full surname (lastname)
|
||||
'%c' : callname
|
||||
'%x' : nick name if existing, otherwise first first name (common name)
|
||||
'%x' : nick name, call, or otherwise first first name (common name)
|
||||
'%i' : initials of the first names
|
||||
'%m' : primary surname (main)
|
||||
'%0m': prefix primary surname (main)
|
||||
|
||||
@@ -65,13 +65,18 @@ class PlaceDisplay(object):
|
||||
else:
|
||||
places = places[index:]
|
||||
|
||||
names = [item[0] for item in places]
|
||||
|
||||
if config.get('preferences.place-number'):
|
||||
if len(places) > 1 and int(places[0][1]) == PlaceType.NUMBER:
|
||||
names = names[1:]
|
||||
names[0] = places[0][0] + ' ' + names[0]
|
||||
types = [item[1] for item in places]
|
||||
try:
|
||||
idx = types.index(PlaceType.NUMBER)
|
||||
except ValueError:
|
||||
idx = None
|
||||
if idx is not None and len(places) > idx+1:
|
||||
combined = (places[idx][0] + ' ' + places[idx+1][0],
|
||||
places[idx+1][1])
|
||||
places = places[:idx] + [combined] + places[idx+2:]
|
||||
|
||||
names = [item[0] for item in places]
|
||||
if config.get('preferences.place-reverse'):
|
||||
names.reverse()
|
||||
|
||||
|
||||
@@ -166,6 +166,9 @@ class FilterParser(handler.ContentHandler):
|
||||
# HasEvent rule has extra primary role field in v3.4.7
|
||||
if self.r == rules.person.HasEvent and len(self.a) == 5:
|
||||
self.a.append('1')
|
||||
# IsEnclosedBy rule has extra inclusive field in v4.2.4
|
||||
if self.r == rules.place.IsEnclosedBy and len(self.a) == 1:
|
||||
self.a.append('0')
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
@@ -96,7 +96,7 @@ class GenericFilter(object):
|
||||
def get_invert(self):
|
||||
return self.invert
|
||||
|
||||
def get_name(self):
|
||||
def get_name(self, ulocale=glocale):
|
||||
return self.name
|
||||
|
||||
def set_name(self, name):
|
||||
|
||||
4
gramps/gen/filters/rules/_hasgallerybase.py
Executable file → Normal file
4
gramps/gen/filters/rules/_hasgallerybase.py
Executable file → Normal file
@@ -49,7 +49,7 @@ class HasGalleryBase(Rule):
|
||||
|
||||
def prepare(self, db):
|
||||
# things we want to do just once, not for every handle
|
||||
if self.list[1] == 'lesser than':
|
||||
if self.list[1] == 'less than':
|
||||
self.count_type = 0
|
||||
elif self.list[1] == 'greater than':
|
||||
self.count_type = 2
|
||||
@@ -60,7 +60,7 @@ class HasGalleryBase(Rule):
|
||||
|
||||
def apply(self, db, obj):
|
||||
count = len( obj.get_media_list())
|
||||
if self.count_type == 0: # "lesser than"
|
||||
if self.count_type == 0: # "less than"
|
||||
return count < self.userSelectedCount
|
||||
elif self.count_type == 2: # "greater than"
|
||||
return count > self.userSelectedCount
|
||||
|
||||
4
gramps/gen/filters/rules/_hasldsbase.py
Executable file → Normal file
4
gramps/gen/filters/rules/_hasldsbase.py
Executable file → Normal file
@@ -52,7 +52,7 @@ class HasLDSBase(Rule):
|
||||
|
||||
def prepare(self, db):
|
||||
# things we want to do just once, not for every handle
|
||||
if self.list[1] == 'lesser than':
|
||||
if self.list[1] == 'less than':
|
||||
self.count_type = 0
|
||||
elif self.list[1] == 'greater than':
|
||||
self.count_type = 2
|
||||
@@ -63,7 +63,7 @@ class HasLDSBase(Rule):
|
||||
|
||||
def apply(self, db, obj):
|
||||
count = len( obj.get_lds_ord_list())
|
||||
if self.count_type == 0: # "lesser than"
|
||||
if self.count_type == 0: # "less than"
|
||||
return count < self.userSelectedCount
|
||||
elif self.count_type == 2: # "greater than"
|
||||
return count > self.userSelectedCount
|
||||
|
||||
4
gramps/gen/filters/rules/_hasnotebase.py
Executable file → Normal file
4
gramps/gen/filters/rules/_hasnotebase.py
Executable file → Normal file
@@ -58,7 +58,7 @@ class HasNoteBase(Rule):
|
||||
|
||||
def prepare(self, db):
|
||||
# things we want to do just once, not for every handle
|
||||
if self.list[1] == 'lesser than':
|
||||
if self.list[1] == 'less than':
|
||||
self.count_type = 0
|
||||
elif self.list[1] == 'greater than':
|
||||
self.count_type = 2
|
||||
@@ -70,7 +70,7 @@ class HasNoteBase(Rule):
|
||||
|
||||
def apply(self, db, obj):
|
||||
count = len( obj.get_note_list())
|
||||
if self.count_type == 0: # "lesser than"
|
||||
if self.count_type == 0: # "less than"
|
||||
return count < self.userSelectedCount
|
||||
elif self.count_type == 2: # "greater than"
|
||||
return count > self.userSelectedCount
|
||||
|
||||
@@ -47,7 +47,7 @@ class HasReferenceCountBase(Rule):
|
||||
|
||||
def prepare(self, db):
|
||||
# things we want to do just once, not for every handle
|
||||
if self.list[0] == 'lesser than':
|
||||
if self.list[0] == 'less than':
|
||||
self.count_type = 0
|
||||
elif self.list[0] == 'greater than':
|
||||
self.count_type = 2
|
||||
@@ -63,7 +63,7 @@ class HasReferenceCountBase(Rule):
|
||||
for item in db.find_backlink_handles(handle):
|
||||
count += 1
|
||||
|
||||
if self.count_type == 0: # "lesser than"
|
||||
if self.count_type == 0: # "less than"
|
||||
return count < self.userSelectedCount
|
||||
elif self.count_type == 2: # "greater than"
|
||||
return count > self.userSelectedCount
|
||||
|
||||
4
gramps/gen/filters/rules/_hassourcecountbase.py
Executable file → Normal file
4
gramps/gen/filters/rules/_hassourcecountbase.py
Executable file → Normal file
@@ -50,7 +50,7 @@ class HasSourceCountBase(Rule):
|
||||
|
||||
def prepare(self, db):
|
||||
# things we want to do just once, not for every handle
|
||||
if self.list[1] == 'lesser than':
|
||||
if self.list[1] == 'less than':
|
||||
self.count_type = 0
|
||||
elif self.list[1] == 'greater than':
|
||||
self.count_type = 2
|
||||
@@ -61,7 +61,7 @@ class HasSourceCountBase(Rule):
|
||||
|
||||
def apply(self, db, obj):
|
||||
count = len(obj.get_citation_list())
|
||||
if self.count_type == 0: # "lesser than"
|
||||
if self.count_type == 0: # "less than"
|
||||
return count < self.userSelectedCount
|
||||
elif self.count_type == 2: # "greater than"
|
||||
return count > self.userSelectedCount
|
||||
|
||||
@@ -82,9 +82,7 @@ class Rule(object):
|
||||
for i in range(len(self.labels)):
|
||||
if self.list[i]:
|
||||
try:
|
||||
self.regex[i] = re.compile(
|
||||
str(self.list[i]),
|
||||
re.I|re.U|re.L)
|
||||
self.regex[i] = re.compile(self.list[i], re.I)
|
||||
except re.error:
|
||||
self.regex[i] = re.compile('')
|
||||
self.match_substring = self.match_regex
|
||||
|
||||
0
gramps/gen/filters/rules/citation/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/citation/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/citation/_hasnote.py
Executable file → Normal file
0
gramps/gen/filters/rules/citation/_hasnote.py
Executable file → Normal file
0
gramps/gen/filters/rules/event/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/event/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/event/_hasnote.py
Executable file → Normal file
0
gramps/gen/filters/rules/event/_hasnote.py
Executable file → Normal file
0
gramps/gen/filters/rules/family/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/family/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/family/_haslds.py
Executable file → Normal file
0
gramps/gen/filters/rules/family/_haslds.py
Executable file → Normal file
0
gramps/gen/filters/rules/family/_hasnote.py
Executable file → Normal file
0
gramps/gen/filters/rules/family/_hasnote.py
Executable file → Normal file
0
gramps/gen/filters/rules/family/_hassourcecount.py
Executable file → Normal file
0
gramps/gen/filters/rules/family/_hassourcecount.py
Executable file → Normal file
@@ -49,7 +49,6 @@ class MatchesRegexpOf(Rule):
|
||||
|
||||
def apply(self, db, note):
|
||||
""" Apply the filter """
|
||||
text = note.get()
|
||||
if self.match_substring(0, text) is not None:
|
||||
if self.match_substring(0, note.get()):
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -68,8 +68,8 @@ def get_family_handle_people(db, exclude_handle, family_handle):
|
||||
|
||||
def possibly_add_handle(h):
|
||||
if h != None and h != exclude_handle:
|
||||
people.add(db.get_person_from_handle(h))
|
||||
|
||||
people.add(h)
|
||||
|
||||
possibly_add_handle(family.get_father_handle())
|
||||
possibly_add_handle(family.get_mother_handle())
|
||||
|
||||
@@ -94,7 +94,9 @@ def get_person_family_people(db, person, person_handle):
|
||||
def find_deep_relations(db, progress, person, path, seen, target_people):
|
||||
if len(target_people) < 1:
|
||||
return []
|
||||
|
||||
|
||||
if person is None:
|
||||
return []
|
||||
handle = person.get_handle()
|
||||
if handle in seen:
|
||||
return []
|
||||
@@ -109,7 +111,8 @@ def find_deep_relations(db, progress, person, path, seen, target_people):
|
||||
|
||||
family_people = get_person_family_people(db, person, handle)
|
||||
for family_person in family_people:
|
||||
return_paths += find_deep_relations(db, progress, family_person, person_path, seen, target_people)
|
||||
pers = db.get_person_from_handle(family_person)
|
||||
return_paths += find_deep_relations(db, progress, pers, person_path, seen, target_people)
|
||||
if progress: progress.step()
|
||||
|
||||
return return_paths
|
||||
|
||||
4
gramps/gen/filters/rules/person/_hasaddress.py
Executable file → Normal file
4
gramps/gen/filters/rules/person/_hasaddress.py
Executable file → Normal file
@@ -53,7 +53,7 @@ class HasAddress(Rule):
|
||||
|
||||
def prepare(self, db):
|
||||
# things we want to do just once, not for every handle
|
||||
if self.list[1] == 'lesser than':
|
||||
if self.list[1] == 'less than':
|
||||
self.count_type = 0
|
||||
elif self.list[1] == 'greater than':
|
||||
self.count_type = 2
|
||||
@@ -64,7 +64,7 @@ class HasAddress(Rule):
|
||||
|
||||
def apply(self, db, person):
|
||||
count = len( person.get_address_list())
|
||||
if self.count_type == 0: # "lesser than"
|
||||
if self.count_type == 0: # "less than"
|
||||
return count < self.userSelectedCount
|
||||
elif self.count_type == 2: # "greater than"
|
||||
return count > self.userSelectedCount
|
||||
|
||||
4
gramps/gen/filters/rules/person/_hasassociation.py
Executable file → Normal file
4
gramps/gen/filters/rules/person/_hasassociation.py
Executable file → Normal file
@@ -52,7 +52,7 @@ class HasAssociation(Rule):
|
||||
|
||||
def prepare(self, db):
|
||||
# things we want to do just once, not for every handle
|
||||
if self.list[1] == 'lesser than':
|
||||
if self.list[1] == 'less than':
|
||||
self.count_type = 0
|
||||
elif self.list[1] == 'greater than':
|
||||
self.count_type = 2
|
||||
@@ -63,7 +63,7 @@ class HasAssociation(Rule):
|
||||
|
||||
def apply(self, db, person):
|
||||
count = len(person.get_person_ref_list())
|
||||
if self.count_type == 0: # "lesser than"
|
||||
if self.count_type == 0: # "less than"
|
||||
return count < self.selected_count
|
||||
elif self.count_type == 2: # "greater than"
|
||||
return count > self.selected_count
|
||||
|
||||
0
gramps/gen/filters/rules/person/_haslds.py
Executable file → Normal file
0
gramps/gen/filters/rules/person/_haslds.py
Executable file → Normal file
0
gramps/gen/filters/rules/person/_hassourcecount.py
Executable file → Normal file
0
gramps/gen/filters/rules/person/_hassourcecount.py
Executable file → Normal file
@@ -78,22 +78,26 @@ class IsDescendantFamilyOf(Rule):
|
||||
return
|
||||
|
||||
# Add self
|
||||
self.matches.add(person.handle)
|
||||
expand = [person]
|
||||
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.db.get_family_from_handle(family_handle)
|
||||
if family:
|
||||
# Add every child recursively
|
||||
for child_ref in family.get_child_ref_list():
|
||||
if child_ref:
|
||||
self.add_matches(self.db.get_person_from_handle(child_ref.ref))
|
||||
|
||||
# Add spouse
|
||||
if person.handle == family.get_father_handle():
|
||||
spouse_handle = family.get_mother_handle()
|
||||
else:
|
||||
spouse_handle = family.get_father_handle()
|
||||
self.matches.add(spouse_handle)
|
||||
while expand:
|
||||
person = expand.pop(0)
|
||||
if person is None:
|
||||
continue
|
||||
self.matches.add(person.handle)
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.db.get_family_from_handle(family_handle)
|
||||
if family:
|
||||
# Add every child recursively
|
||||
for child_ref in family.get_child_ref_list():
|
||||
if child_ref:
|
||||
expand.append(self.db.get_person_from_handle(child_ref.ref))
|
||||
# Add spouse
|
||||
if person.handle == family.get_father_handle():
|
||||
spouse_handle = family.get_mother_handle()
|
||||
else:
|
||||
spouse_handle = family.get_father_handle()
|
||||
self.matches.add(spouse_handle)
|
||||
|
||||
def exclude(self):
|
||||
# This removes root person and his/her spouses from the matches set
|
||||
|
||||
0
gramps/gen/filters/rules/place/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/place/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/place/_hasnote.py
Executable file → Normal file
0
gramps/gen/filters/rules/place/_hasnote.py
Executable file → Normal file
@@ -45,15 +45,22 @@ class IsEnclosedBy(Rule):
|
||||
Rule that checks for a place enclosed by another place
|
||||
"""
|
||||
|
||||
labels = [_('ID:')]
|
||||
labels = [_('ID:'), _('Inclusive:')]
|
||||
name = _('Places enclosed by another place')
|
||||
description = _('Matches a place enclosed by a particular place')
|
||||
category = _('General filters')
|
||||
|
||||
def prepare(self, db):
|
||||
self.handle = db.get_place_from_gramps_id(self.list[0]).handle
|
||||
self.handle = None
|
||||
place = db.get_place_from_gramps_id(self.list[0])
|
||||
if place:
|
||||
self.handle = place.handle
|
||||
|
||||
def apply(self, db, place):
|
||||
if self.handle is None:
|
||||
return False
|
||||
if self.list[1] == '1' and place.handle == self.handle:
|
||||
return True
|
||||
if located_in(db, place.handle, self.handle):
|
||||
return True
|
||||
return False
|
||||
|
||||
0
gramps/gen/filters/rules/source/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/source/_hasgallery.py
Executable file → Normal file
0
gramps/gen/filters/rules/source/_hasnote.py
Executable file → Normal file
0
gramps/gen/filters/rules/source/_hasnote.py
Executable file → Normal file
@@ -50,7 +50,7 @@ class HasRepository(Rule):
|
||||
|
||||
def prepare(self, db):
|
||||
# things we want to do just once, not for every handle
|
||||
if self.list[1] == 'lesser than':
|
||||
if self.list[1] == 'less than':
|
||||
self.count_type = 0
|
||||
elif self.list[1] == 'greater than':
|
||||
self.count_type = 2
|
||||
@@ -61,7 +61,7 @@ class HasRepository(Rule):
|
||||
|
||||
def apply(self, db, obj):
|
||||
count = len(obj.get_reporef_list())
|
||||
if self.count_type == 0: # "lesser than"
|
||||
if self.count_type == 0: # "less than"
|
||||
return count < self.userSelectedCount
|
||||
elif self.count_type == 2: # "greater than"
|
||||
return count > self.userSelectedCount
|
||||
|
||||
@@ -67,6 +67,9 @@ class AttributeRoot(SecondaryObject, PrivacyBase):
|
||||
self.type = None
|
||||
self.value = None
|
||||
|
||||
def __str__(self):
|
||||
return str(self.value)
|
||||
|
||||
def serialize(self):
|
||||
"""
|
||||
Convert the object to a serialized tuple of data.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2015 Paul Franklin
|
||||
#
|
||||
# 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
|
||||
@@ -58,25 +59,32 @@ class AttributeType(GrampsType):
|
||||
_CUSTOM = CUSTOM
|
||||
_DEFAULT = ID
|
||||
|
||||
_DATAMAP = [
|
||||
(UNKNOWN , _("Unknown"), "Unknown"),
|
||||
(CUSTOM , _("Custom"), "Custom"),
|
||||
(CASTE , _("Caste"), "Caste"),
|
||||
(DESCRIPTION , _("Description"), "Description"),
|
||||
(ID , _("Identification Number"), "Identification Number"),
|
||||
(NATIONAL , _("National Origin"), "National Origin"),
|
||||
(NUM_CHILD , _("Number of Children"), "Number of Children"),
|
||||
(SSN , _("Social Security Number"), "Social Security Number"),
|
||||
(NICKNAME , _("Nickname"), "Nickname"),
|
||||
(CAUSE , _("Cause"), "Cause"),
|
||||
(AGENCY , _("Agency"), "Agency"),
|
||||
(AGE , _("Age"), "Age"),
|
||||
(FATHER_AGE , _("Father's Age"), "Father Age"),
|
||||
(MOTHER_AGE , _("Mother's Age"), "Mother Age"),
|
||||
(WITNESS , _("Witness"), "Witness"),
|
||||
(TIME , _("Time"), "Time"),
|
||||
# _T_ is a gramps-defined keyword -- see po/update_po.py and po/genpot.sh
|
||||
def _T_(value): # enable deferred translations (see Python docs 22.1.3.4)
|
||||
return value
|
||||
|
||||
_BASEMAP = [ # allow deferred translation of attribute UI strings
|
||||
(UNKNOWN , _T_("Unknown"), "Unknown"),
|
||||
(CUSTOM , _T_("Custom"), "Custom"),
|
||||
(CASTE , _T_("Caste"), "Caste"),
|
||||
(DESCRIPTION , _T_("Description"), "Description"),
|
||||
(ID , _T_("Identification Number"), "Identification Number"),
|
||||
(NATIONAL , _T_("National Origin"), "National Origin"),
|
||||
(NUM_CHILD , _T_("Number of Children"), "Number of Children"),
|
||||
(SSN , _T_("Social Security Number"),
|
||||
"Social Security Number"),
|
||||
(NICKNAME , _T_("Nickname"), "Nickname"),
|
||||
(CAUSE , _T_("Cause"), "Cause"),
|
||||
(AGENCY , _T_("Agency"), "Agency"),
|
||||
(AGE , _T_("Age"), "Age"),
|
||||
(FATHER_AGE , _T_("Father's Age"), "Father Age"),
|
||||
(MOTHER_AGE , _T_("Mother's Age"), "Mother Age"),
|
||||
(WITNESS , _T_("Witness"), "Witness"),
|
||||
(TIME , _T_("Time"), "Time"),
|
||||
]
|
||||
|
||||
_DATAMAP = [(base[0], _(base[1]), base[2]) for base in _BASEMAP]
|
||||
|
||||
def __init__(self, value=None):
|
||||
GrampsType.__init__(self, value)
|
||||
|
||||
@@ -95,3 +103,14 @@ class AttributeType(GrampsType):
|
||||
|
||||
"""
|
||||
return []
|
||||
|
||||
def type2base(self):
|
||||
"""
|
||||
Return the untranslated string suitable for UI (once translated).
|
||||
"""
|
||||
if self.value == self.CUSTOM:
|
||||
return str(self)
|
||||
elif self._BASEMAP[self.value+1]: # UNKNOWN is before CUSTOM, sigh
|
||||
return self._BASEMAP[self.value+1][1]
|
||||
else:
|
||||
return self.UNKNOWN
|
||||
|
||||
@@ -348,7 +348,10 @@ class Span(object):
|
||||
stop2 = Date(*stop2)
|
||||
_repr = (trans_text("between") + " " + self._format(self._diff(start1, stop2),dlocale) +
|
||||
" " + trans_text("and") + " " + self._format(self._diff(stop1, start2),dlocale))
|
||||
return _repr
|
||||
if _repr.find('-') == -1: # we don't have a negative value to return.
|
||||
return _repr
|
||||
else:
|
||||
return '(' + _repr.replace('-', '') + ')'
|
||||
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
@@ -936,6 +939,25 @@ class Date(object):
|
||||
# return tuples not lists, for comparisons
|
||||
return (tuple(startmin), tuple(stopmax))
|
||||
|
||||
def match_exact(self, other_date):
|
||||
"""
|
||||
Perform an extact match between two dates. The dates are not treated
|
||||
as being person-centric. This is used to match date ranges in places.
|
||||
"""
|
||||
if other_date.modifier == Date.MOD_NONE:
|
||||
return other_date.sortval == self.sortval
|
||||
elif other_date.modifier == Date.MOD_BEFORE:
|
||||
return other_date.sortval > self.sortval
|
||||
elif other_date.modifier == Date.MOD_AFTER:
|
||||
return other_date.sortval < self.sortval
|
||||
elif other_date.is_compound():
|
||||
start, stop = other_date.get_start_stop_range()
|
||||
start = Date(*start)
|
||||
stop = Date(*stop)
|
||||
return start.sortval <= self.sortval <= stop.sortval
|
||||
else:
|
||||
return False
|
||||
|
||||
def match(self, other_date, comparison="="):
|
||||
"""
|
||||
Compare two dates using sophisticated techniques looking for any match
|
||||
|
||||
@@ -49,11 +49,11 @@ class FamilyRelType(GrampsType):
|
||||
_DEFAULT = MARRIED
|
||||
|
||||
_DATAMAP = [
|
||||
(UNKNOWN, _("Unknown"), "Unknown"),
|
||||
(CUSTOM, _("Custom"), "Custom"),
|
||||
(MARRIED, _("Married"), "Married"),
|
||||
(UNMARRIED, _("Unmarried"), "Unmarried"),
|
||||
(CIVIL_UNION, _("Civil Union"), "Civil Union"),
|
||||
(UNMARRIED, _("Unmarried"), "Unmarried"),
|
||||
(MARRIED, _("Married"), "Married"),
|
||||
(UNKNOWN, _("Unknown"), "Unknown"),
|
||||
(CUSTOM, _("Custom"), "Custom"),
|
||||
]
|
||||
|
||||
def __init__(self, value=None):
|
||||
|
||||
@@ -87,7 +87,7 @@ class Location(SecondaryObject, LocationBase):
|
||||
"street": self.street,
|
||||
"locality": self.locality,
|
||||
"city": self.city,
|
||||
"country": self.county,
|
||||
"county": self.county,
|
||||
"state": self.state,
|
||||
"country": self.country,
|
||||
"postal": self.postal,
|
||||
|
||||
@@ -99,7 +99,7 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
|
||||
self.parent_family_list = []
|
||||
self.alternate_names = []
|
||||
self.person_ref_list = []
|
||||
self.gender = Person.UNKNOWN
|
||||
self.__gender = Person.UNKNOWN
|
||||
self.death_ref_index = -1
|
||||
self.birth_ref_index = -1
|
||||
if data:
|
||||
@@ -136,7 +136,7 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
|
||||
return (
|
||||
self.handle, # 0
|
||||
self.gramps_id, # 1
|
||||
self.gender, # 2
|
||||
self.__gender, # 2
|
||||
self.primary_name.serialize(), # 3
|
||||
[name.serialize() for name in self.alternate_names], # 4
|
||||
self.death_ref_index, # 5
|
||||
@@ -181,7 +181,7 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
|
||||
"_class": "Person",
|
||||
"handle": Handle("Person", self.handle), # 0
|
||||
"gramps_id": self.gramps_id, # 1
|
||||
"gender": self.gender, # 2
|
||||
"gender": self.__gender, # 2
|
||||
"primary_name": self.primary_name.to_struct(), # 3
|
||||
"alternate_names": [name.to_struct()
|
||||
for name in self.alternate_names], # 4
|
||||
@@ -276,7 +276,7 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
|
||||
"""
|
||||
(self.handle, # 0
|
||||
self.gramps_id, # 1
|
||||
self.gender, # 2
|
||||
self.__gender, # 2
|
||||
primary_name, # 3
|
||||
alternate_names, # 4
|
||||
self.death_ref_index, # 5
|
||||
@@ -675,7 +675,9 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
|
||||
- Person.UNKNOWN
|
||||
:type gender: int
|
||||
"""
|
||||
self.gender = gender
|
||||
if gender not in (Person.MALE, Person.FEMALE, Person.UNKNOWN):
|
||||
raise ValueError('Attempt to assign invalid gender')
|
||||
self.__gender = gender
|
||||
|
||||
def get_gender(self) :
|
||||
"""
|
||||
@@ -688,7 +690,10 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
|
||||
- Person.UNKNOWN
|
||||
:rtype: int
|
||||
"""
|
||||
return self.gender
|
||||
return self.__gender
|
||||
|
||||
gender = property(get_gender, set_gender, None,
|
||||
'Returns or sets the gender of the person')
|
||||
|
||||
def set_birth_ref(self, event_ref):
|
||||
"""
|
||||
|
||||
14
gramps/gen/lib/place.py
Normal file → Executable file
14
gramps/gen/lib/place.py
Normal file → Executable file
@@ -229,7 +229,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
|
||||
"""
|
||||
|
||||
ret = (self.media_list + self.alt_loc + self.urls +
|
||||
self.name + self.alt_names)
|
||||
self.name.get_text_data_child_list() + self.alt_names)
|
||||
return ret
|
||||
|
||||
def get_citation_child_list(self):
|
||||
@@ -577,9 +577,13 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
|
||||
:param acquisition: instance to merge
|
||||
:type acquisition: :class:'~.place.Place
|
||||
"""
|
||||
if acquisition.name and (acquisition.name not in self.alt_names):
|
||||
self.alt_names.append(acquisition.name)
|
||||
if acquisition.name.value:
|
||||
if acquisition.name != self.name:
|
||||
if acquisition.name not in self.alt_names:
|
||||
self.alt_names.append(acquisition.name)
|
||||
|
||||
for addendum in acquisition.alt_names:
|
||||
if addendum not in self.alt_names:
|
||||
self.alt_names.append(addendum)
|
||||
if addendum.value:
|
||||
if addendum != self.name:
|
||||
if addendum not in self.alt_names:
|
||||
self.alt_names.append(addendum)
|
||||
|
||||
6
gramps/gen/lib/placename.py
Normal file → Executable file
6
gramps/gen/lib/placename.py
Normal file → Executable file
@@ -200,6 +200,12 @@ class PlaceName(SecondaryObject, DateBase):
|
||||
else:
|
||||
return EQUAL
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.is_equal(other)
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.is_equal(other)
|
||||
|
||||
def set_value(self, value):
|
||||
"""
|
||||
Set the name for the PlaceName instance.
|
||||
|
||||
@@ -84,7 +84,7 @@ class Researcher(LocationBase):
|
||||
"street": self.street,
|
||||
"locality": self.locality,
|
||||
"city": self.city,
|
||||
"country": self.county,
|
||||
"county": self.county,
|
||||
"state": self.state,
|
||||
"country": self.country,
|
||||
"postal": self.postal,
|
||||
|
||||
32
gramps/gen/lib/test/merge_test.py
Normal file → Executable file
32
gramps/gen/lib/test/merge_test.py
Normal file → Executable file
@@ -1389,8 +1389,14 @@ class PlaceCheck(unittest.TestCase, PrivacyBaseTest, MediaBaseTest,
|
||||
def setUp(self):
|
||||
self.phoenix = Place()
|
||||
self.phoenix.set_title('Place 1')
|
||||
self.titanic = Place(self.phoenix)
|
||||
self.ref_obj = Place(self.phoenix)
|
||||
# __init__ copy has bad side effects, don't use it
|
||||
# self.titanic = Place(self.phoenix)
|
||||
self.titanic = Place()
|
||||
self.titanic.set_title('Place 1')
|
||||
# __init__ copy has bad side effects, don't use it
|
||||
# self.ref_obj = Place(self.phoenix)
|
||||
self.ref_obj = Place()
|
||||
self.ref_obj.set_title('Place 1')
|
||||
self.amsterdam = PlaceName()
|
||||
self.amsterdam.set_value('Amsterdam')
|
||||
self.rotterdam = PlaceName()
|
||||
@@ -1433,9 +1439,11 @@ class PlaceCheck(unittest.TestCase, PrivacyBaseTest, MediaBaseTest,
|
||||
self.titanic.add_alternative_name(self.leiden)
|
||||
self.ref_obj.set_name(self.amsterdam)
|
||||
self.ref_obj.set_type(PlaceType.CITY)
|
||||
self.ref_obj.add_alternative_name(self.amsterdam)
|
||||
self.ref_obj.add_alternative_name(self.rotterdam)
|
||||
# Base name shouldn't be in alt_names list
|
||||
# self.ref_obj.add_alternative_name(self.amsterdam)
|
||||
# alt_names must be in correct order for test to pass
|
||||
self.ref_obj.add_alternative_name(self.utrecht)
|
||||
self.ref_obj.add_alternative_name(self.rotterdam)
|
||||
self.ref_obj.add_alternative_name(self.leiden)
|
||||
self.phoenix.merge(self.titanic)
|
||||
self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize())
|
||||
@@ -1496,6 +1504,22 @@ class PlaceCheck(unittest.TestCase, PrivacyBaseTest, MediaBaseTest,
|
||||
self.phoenix.merge(self.titanic)
|
||||
self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize())
|
||||
|
||||
def test_merge_empty(self):
|
||||
self.phoenix.set_name(self.amsterdam)
|
||||
self.phoenix.set_type(PlaceType.CITY)
|
||||
self.phoenix.add_alternative_name(self.rotterdam)
|
||||
self.titanic.set_title('Place 2')
|
||||
# titanic gets empty name
|
||||
self.titanic.set_type(PlaceType.CITY)
|
||||
self.titanic.add_alternative_name(self.utrecht)
|
||||
self.titanic.add_alternative_name(PlaceName()) # empty alt_name
|
||||
self.ref_obj.set_name(self.amsterdam)
|
||||
self.ref_obj.set_type(PlaceType.CITY)
|
||||
self.ref_obj.add_alternative_name(self.rotterdam)
|
||||
self.ref_obj.add_alternative_name(self.utrecht)
|
||||
self.phoenix.merge(self.titanic)
|
||||
self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize())
|
||||
|
||||
class RepoCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, UrlBaseTest):
|
||||
def setUp(self):
|
||||
self.phoenix = Repository()
|
||||
|
||||
@@ -134,15 +134,35 @@ class MergeFamilyQuery(object):
|
||||
|
||||
with DbTxn(_('Merge Family'), self.database) as trans:
|
||||
|
||||
phoenix_father = self.database.get_person_from_handle(self.phoenix_fh)
|
||||
titanic_father = self.database.get_person_from_handle(self.titanic_fh)
|
||||
self.merge_person(phoenix_father, titanic_father, 'father', trans)
|
||||
if self.phoenix_fh != self.titanic_fh:
|
||||
if self.phoenix_fh:
|
||||
phoenix_father = self.database.get_person_from_handle(
|
||||
self.phoenix_fh)
|
||||
else:
|
||||
phoenix_father = None
|
||||
if self.titanic_fh:
|
||||
titanic_father = self.database.get_person_from_handle(
|
||||
self.titanic_fh)
|
||||
else:
|
||||
titanic_father = None
|
||||
self.merge_person(phoenix_father, titanic_father,
|
||||
'father', trans)
|
||||
|
||||
phoenix_mother = self.database.get_person_from_handle(self.phoenix_mh)
|
||||
titanic_mother = self.database.get_person_from_handle(self.titanic_mh)
|
||||
if self.phoenix_mh != self.titanic_mh:
|
||||
if self.phoenix_mh:
|
||||
phoenix_mother = self.database.get_person_from_handle(
|
||||
self.phoenix_mh)
|
||||
else:
|
||||
phoenix_mother = None
|
||||
if self.titanic_mh:
|
||||
titanic_mother = self.database.get_person_from_handle(
|
||||
self.titanic_mh)
|
||||
else:
|
||||
titanic_mother = None
|
||||
self.merge_person(phoenix_mother, titanic_mother,
|
||||
'mother', trans)
|
||||
self.phoenix = self.database.get_family_from_handle(new_handle)
|
||||
self.titanic = self.database.get_family_from_handle(old_handle)
|
||||
self.merge_person(phoenix_mother, titanic_mother, 'mother', trans)
|
||||
|
||||
phoenix_father = self.database.get_person_from_handle(self.phoenix_fh)
|
||||
phoenix_mother = self.database.get_person_from_handle(self.phoenix_mh)
|
||||
|
||||
@@ -27,7 +27,7 @@ The "plug" package for handling plugins in Gramps.
|
||||
from ._plugin import Plugin
|
||||
from ._pluginreg import (PluginData, PluginRegister, REPORT, TOOL,
|
||||
CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE,
|
||||
CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ,
|
||||
CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ, CATEGORY_TREE,
|
||||
TOOL_DEBUG, TOOL_ANAL, TOOL_DBPROC, TOOL_DBFIX, TOOL_REVCTL,
|
||||
TOOL_UTILS, CATEGORY_QR_MISC, CATEGORY_QR_PERSON,
|
||||
CATEGORY_QR_FAMILY, CATEGORY_QR_EVENT, CATEGORY_QR_SOURCE,
|
||||
@@ -49,7 +49,7 @@ __all__ = [ "docbackend", "docgen", "menu", Plugin, PluginData,
|
||||
PluginRegister, BasePluginManager,
|
||||
ImportPlugin, ExportPlugin, DocGenPlugin,
|
||||
REPORT, TOOL, CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE,
|
||||
CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ,
|
||||
CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ, CATEGORY_TREE,
|
||||
TOOL_DEBUG, TOOL_ANAL, TOOL_DBPROC, TOOL_DBFIX, TOOL_REVCTL,
|
||||
TOOL_UTILS, CATEGORY_QR_MISC, CATEGORY_QR_PERSON,
|
||||
CATEGORY_QR_FAMILY, CATEGORY_QR_EVENT, CATEGORY_QR_SOURCE,
|
||||
|
||||
@@ -309,8 +309,12 @@ class Gramplet(object):
|
||||
self.interrupt()
|
||||
self._generator = self.main()
|
||||
self._pause = False
|
||||
self._idle_id = GLib.idle_add(self._updater,
|
||||
if GObject.pygobject_version < (3,16,0):
|
||||
self._idle_id = GLib.idle_add(self._updater,
|
||||
priority=GObject.PRIORITY_LOW - 10)
|
||||
else:
|
||||
self._idle_id = GLib.idle_add(self._updater,
|
||||
priority=GLib.PRIORITY_LOW - 10)
|
||||
|
||||
def _updater(self):
|
||||
"""
|
||||
@@ -364,8 +368,12 @@ class Gramplet(object):
|
||||
"""
|
||||
from gi.repository import GObject, GLib
|
||||
self._pause = False
|
||||
self._idle_id = GLib.idle_add(self._updater,
|
||||
if GObject.pygobject_version < (3,16,0):
|
||||
self._idle_id = GLib.idle_add(self._updater,
|
||||
priority=GObject.PRIORITY_LOW - 10)
|
||||
else:
|
||||
self._idle_id = GLib.idle_add(self._updater,
|
||||
priority=GLib.PRIORITY_LOW - 10)
|
||||
|
||||
def update_all(self, *args):
|
||||
"""
|
||||
|
||||
@@ -94,8 +94,10 @@ CATEGORY_CODE = 2
|
||||
CATEGORY_WEB = 3
|
||||
CATEGORY_BOOK = 4
|
||||
CATEGORY_GRAPHVIZ = 5
|
||||
CATEGORY_TREE = 6
|
||||
REPORT_CAT = [ CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE,
|
||||
CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ]
|
||||
CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ,
|
||||
CATEGORY_TREE]
|
||||
#possible tool categories
|
||||
TOOL_DEBUG = -1
|
||||
TOOL_ANAL = 0
|
||||
@@ -1009,6 +1011,7 @@ def make_environment(**kwargs):
|
||||
'CATEGORY_WEB': CATEGORY_WEB,
|
||||
'CATEGORY_BOOK': CATEGORY_BOOK,
|
||||
'CATEGORY_GRAPHVIZ': CATEGORY_GRAPHVIZ,
|
||||
'CATEGORY_TREE': CATEGORY_TREE,
|
||||
'TOOL_DEBUG': TOOL_DEBUG,
|
||||
'TOOL_ANAL': TOOL_ANAL,
|
||||
'TOOL_DBPROC': TOOL_DBPROC,
|
||||
|
||||
@@ -37,3 +37,4 @@ from .textdoc import TextDoc, IndexMark,INDEX_TYPE_ALP, INDEX_TYPE_TOC,\
|
||||
URL_PATTERN, LOCAL_HYPERLINK, LOCAL_TARGET
|
||||
from .drawdoc import DrawDoc
|
||||
from .graphdoc import GVDoc
|
||||
from .treedoc import TreeDoc
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
# Copyright (C) 2007 Brian G. Matherly
|
||||
# Copyright (C) 2009 Benny Malengier
|
||||
# Copyright (C) 2009 Gary Burton
|
||||
# Copyright (C) 2017 Mindaugas Baranauskas
|
||||
# Copyright (C) 2017 Paul Culley
|
||||
#
|
||||
# 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
|
||||
@@ -42,11 +44,13 @@ import sys
|
||||
#-------------------------------------------------------------------------------
|
||||
from ...const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
from ...utils.file import search_for
|
||||
from ...utils.file import search_for, where_is
|
||||
from . import BaseDoc
|
||||
from ..menu import NumberOption, TextOption, EnumeratedListOption, \
|
||||
BooleanOption
|
||||
from ...constfunc import win
|
||||
if win():
|
||||
from ctypes.wintypes import DWORD
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -95,15 +99,14 @@ if win():
|
||||
_GS_CMD = "gswin32.exe"
|
||||
else:
|
||||
_GS_CMD = ""
|
||||
# Process Creation Flags declared in WinBase.h
|
||||
DETACHED_PROCESS = DWORD(0x00000008).value
|
||||
else:
|
||||
_DOT_FOUND = search_for("dot")
|
||||
|
||||
if search_for("gs") == 1:
|
||||
_GS_CMD = "gs"
|
||||
else:
|
||||
_GS_CMD = ""
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
_GS_CMD = where_is("gs")
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# GVOptions
|
||||
#
|
||||
@@ -128,7 +131,7 @@ class GVOptions():
|
||||
:return: nothing
|
||||
"""
|
||||
################################
|
||||
category = _("GraphViz Layout")
|
||||
category = _("Graphviz Layout")
|
||||
################################
|
||||
font_family = EnumeratedListOption(_("Font family"), "")
|
||||
for item in _FONTS:
|
||||
@@ -151,7 +154,7 @@ class GVOptions():
|
||||
menu.add_option(category, "rank_dir", rank_dir)
|
||||
|
||||
h_pages = NumberOption(_("Number of Horizontal Pages"), 1, 1, 25)
|
||||
h_pages.set_help(_("GraphViz can create very large graphs by "
|
||||
h_pages.set_help(_("Graphviz can create very large graphs by "
|
||||
"spreading the graph across a rectangular "
|
||||
"array of pages. This controls the number "
|
||||
"pages in the array horizontally. "
|
||||
@@ -159,7 +162,7 @@ class GVOptions():
|
||||
menu.add_option(category, "h_pages", h_pages)
|
||||
|
||||
v_pages = NumberOption(_("Number of Vertical Pages"), 1, 1, 25)
|
||||
v_pages.set_help(_("GraphViz can create very large graphs by "
|
||||
v_pages.set_help(_("Graphviz can create very large graphs by "
|
||||
"spreading the graph across a rectangular "
|
||||
"array of pages. This controls the number "
|
||||
"pages in the array vertically. "
|
||||
@@ -187,7 +190,7 @@ class GVOptions():
|
||||
self.v_pages.connect('value-changed', self.pages_changed)
|
||||
|
||||
################################
|
||||
category = _("GraphViz Options")
|
||||
category = _("Graphviz Options")
|
||||
################################
|
||||
|
||||
aspect_ratio = EnumeratedListOption(_("Aspect ratio"), "fill")
|
||||
@@ -234,7 +237,7 @@ class GVOptions():
|
||||
menu.add_option(category, "ranksep", ranksep)
|
||||
|
||||
use_subgraphs = BooleanOption(_('Use subgraphs'), True)
|
||||
use_subgraphs.set_help(_("Subgraphs can help GraphViz position "
|
||||
use_subgraphs.set_help(_("Subgraphs can help Graphviz position "
|
||||
"spouses together, but with non-trivial "
|
||||
"graphs will result in longer lines and "
|
||||
"larger graphs."))
|
||||
@@ -510,7 +513,7 @@ class GVDocBase(BaseDoc, GVDoc):
|
||||
text += ' style="%s"' % style
|
||||
|
||||
# note that we always output a label -- even if an empty string --
|
||||
# otherwise GraphViz uses the node ID as the label which is unlikely
|
||||
# otherwise Graphviz uses the node ID as the label which is unlikely
|
||||
# to be what the user wants to see in the graph
|
||||
if label.startswith("<") or htmloutput:
|
||||
text += ' label=<%s>' % label
|
||||
@@ -521,7 +524,7 @@ class GVDocBase(BaseDoc, GVDoc):
|
||||
text += ' URL="%s"' % url
|
||||
|
||||
text += " ]"
|
||||
self.write(' %s %s;\n' % (node_id, text))
|
||||
self.write(' "%s" %s;\n' % (node_id, text))
|
||||
|
||||
def add_link(self, id1, id2, style="", head="", tail="", comment=""):
|
||||
"""
|
||||
@@ -529,7 +532,7 @@ class GVDocBase(BaseDoc, GVDoc):
|
||||
|
||||
Implements GVDocBase.add_link().
|
||||
"""
|
||||
self.write(' %s -> %s' % (id1, id2))
|
||||
self.write(' "%s" -> "%s"' % (id1, id2))
|
||||
|
||||
if style or head or tail:
|
||||
self.write(' [')
|
||||
@@ -577,6 +580,7 @@ class GVDocBase(BaseDoc, GVDoc):
|
||||
|
||||
def start_subgraph(self, graph_id):
|
||||
""" Implement GVDocBase.start_subgraph() """
|
||||
graph_id = graph_id.replace(' ', '_') # for user-defined ID with space
|
||||
self.write(
|
||||
' subgraph cluster_%s\n' % graph_id +
|
||||
' {\n' +
|
||||
@@ -645,7 +649,7 @@ class GVPsDoc(GVDocBase):
|
||||
# Generate the PS file.
|
||||
# Reason for using -Tps:cairo. Needed for Non Latin-1 letters
|
||||
# Some testing with Tps:cairo. Non Latin-1 letters are OK i all cases:
|
||||
# Output format: ps PDF-GostScript PDF-GraphViz
|
||||
# Output format: ps PDF-GostScript PDF-Graphviz
|
||||
# Single page OK OK OK
|
||||
# Multip page 1 page, OK 1 page,
|
||||
# corrupted set by gramps
|
||||
@@ -654,12 +658,21 @@ class GVPsDoc(GVDocBase):
|
||||
# disappeared. I used 1 inch margins always.
|
||||
# See bug tracker issue 2815
|
||||
# :cairo does not work with Graphviz 2.26.3 and later See issue 4164
|
||||
# recent versions of Graphvis doesn't even try, just puts out a single
|
||||
# large page.
|
||||
|
||||
command = 'dot -Tps:cairo -o"%s" "%s"' % (self._filename, tmp_dot)
|
||||
dotversion = str(Popen(['dot', '-V'], stderr=PIPE).communicate(input=None)[1])
|
||||
if win():
|
||||
dotversion = str(Popen(['dot', '-V'],
|
||||
creationflags=DETACHED_PROCESS,
|
||||
stdin=PIPE, stdout=PIPE,
|
||||
stderr=PIPE).communicate(input=None)[1])
|
||||
else:
|
||||
dotversion = str(Popen(['dot', '-V'],
|
||||
stderr=PIPE).communicate(input=None)[1])
|
||||
# Problem with dot 2.26.3 and later and multiple pages, which gives "cairo: out of
|
||||
# memory" If the :cairo is skipped for these cases it gives acceptable
|
||||
# result.
|
||||
# memory" If the :cairo is skipped for these cases it gives bad
|
||||
# result for non-Latin-1 characters (utf-8).
|
||||
if (dotversion.find('2.26.3') or dotversion.find('2.28.0') != -1) and (self.vpages * self.hpages) > 1:
|
||||
command = command.replace(':cairo','')
|
||||
os.system(command)
|
||||
@@ -909,29 +922,78 @@ class GVPdfGsDoc(GVDocBase):
|
||||
# Generate PostScript using dot
|
||||
# Reason for using -Tps:cairo. Needed for Non Latin-1 letters
|
||||
# See bug tracker issue 2815
|
||||
# :cairo does not work with Graphviz 2.26.3 and later See issue 4164
|
||||
|
||||
command = 'dot -Tps:cairo -o"%s" "%s"' % ( tmp_ps, tmp_dot )
|
||||
dotversion = str(Popen(['dot', '-V'], stderr=PIPE).communicate(input=None)[1])
|
||||
# Problem with dot 2.26.3 and later and multiple pages, which gives "cairo: out
|
||||
# of memory". If the :cairo is skipped for these cases it gives
|
||||
# acceptable result.
|
||||
if (dotversion.find('2.26.3') or dotversion.find('2.28.0') != -1) and (self.vpages * self.hpages) > 1:
|
||||
command = command.replace(':cairo','')
|
||||
# :cairo does not work with with multi-page See issue 4164
|
||||
# recent versions of Graphvis doesn't even try, just puts out a single
|
||||
# large page, so we use Ghostscript to split it up.
|
||||
|
||||
command = 'dot -Tps:cairo -o"%s" "%s"' % (tmp_ps, tmp_dot)
|
||||
if win():
|
||||
dotversion = str(Popen(['dot', '-V'],
|
||||
creationflags=DETACHED_PROCESS,
|
||||
stdin=PIPE, stdout=PIPE,
|
||||
stderr=PIPE).communicate(input=None)[1])
|
||||
else:
|
||||
dotversion = str(Popen(['dot', '-V'],
|
||||
stderr=PIPE).communicate(input=None)[1])
|
||||
os.system(command)
|
||||
|
||||
# Add .5 to remove rounding errors.
|
||||
paper_size = self._paper.get_size()
|
||||
width_pt = int( (paper_size.get_width_inches() * 72) + 0.5 )
|
||||
height_pt = int( (paper_size.get_height_inches() * 72) + 0.5 )
|
||||
|
||||
width_pt = int((paper_size.get_width_inches() * 72) + .5)
|
||||
height_pt = int((paper_size.get_height_inches() * 72) + .5)
|
||||
if (self.vpages * self.hpages) == 1:
|
||||
# -dDEVICEWIDTHPOINTS=%d' -dDEVICEHEIGHTPOINTS=%d
|
||||
command = '%s -q -sDEVICE=pdfwrite -dNOPAUSE '\
|
||||
'-dDEVICEWIDTHPOINTS=%d -dDEVICEHEIGHTPOINTS=%d '\
|
||||
'-sOutputFile="%s" "%s" -c quit' % (
|
||||
_GS_CMD, width_pt, height_pt, self._filename, tmp_ps)
|
||||
os.system(command)
|
||||
os.remove(tmp_ps)
|
||||
return
|
||||
# Margins (in centimeters) to pixels 72/2.54=28.345
|
||||
MarginT = int(28.345 * self._paper.get_top_margin())
|
||||
MarginB = int(28.345 * self._paper.get_bottom_margin())
|
||||
MarginR = int(28.345 * self._paper.get_right_margin())
|
||||
MarginL = int(28.345 * self._paper.get_left_margin())
|
||||
MarginX = MarginL + MarginR
|
||||
MarginY = MarginT + MarginB
|
||||
# Convert to PDF using ghostscript
|
||||
command = '%s -q -sDEVICE=pdfwrite -dNOPAUSE -dDEVICEWIDTHPOINTS=%d' \
|
||||
' -dDEVICEHEIGHTPOINTS=%d -sOutputFile="%s" "%s" -c quit' \
|
||||
% ( _GS_CMD, width_pt, height_pt, self._filename, tmp_ps )
|
||||
list_of_pieces = []
|
||||
|
||||
x_rng = range(1, self.hpages + 1) if 'L' in self.pagedir \
|
||||
else range(self.hpages , 0, -1)
|
||||
y_rng = range(1, self.vpages + 1) if 'B' in self.pagedir \
|
||||
else range(self.vpages , 0, -1)
|
||||
if self.pagedir[0] in 'TB':
|
||||
the_list = ((x, y) for y in y_rng for x in x_rng)
|
||||
else:
|
||||
the_list = ((x, y) for x in x_rng for y in y_rng)
|
||||
for x, y in the_list:
|
||||
# Slit PS file to pieces of PDF
|
||||
PageOffsetX = (x - 1) * (MarginX - width_pt)
|
||||
PageOffsetY = (y - 1) * (MarginY - height_pt)
|
||||
tmp_pdf_piece = "%s_%d_%d.pdf" % (tmp_ps, x, y)
|
||||
list_of_pieces.append(tmp_pdf_piece)
|
||||
# Generate Ghostscript code
|
||||
command = '%s -q -dBATCH -dNOPAUSE -dSAFER -g%dx%d '\
|
||||
'-sOutputFile="%s" -r72 -sDEVICE=pdfwrite '\
|
||||
'-c "<</.HWMargins [%d %d %d %d] /PageOffset [%d %d]>> '\
|
||||
'setpagedevice" -f "%s"' % (
|
||||
_GS_CMD, width_pt + 10, height_pt + 10, tmp_pdf_piece,
|
||||
MarginL, MarginB, MarginR, MarginT,
|
||||
PageOffsetX + 5, PageOffsetY + 5, tmp_ps)
|
||||
# Execute Ghostscript
|
||||
os.system(command)
|
||||
# Merge pieces to single multipage PDF ;
|
||||
command = '%s -q -dBATCH -dNOPAUSE '\
|
||||
'-sOUTPUTFILE="%s" -r72 -sDEVICE=pdfwrite %s '\
|
||||
% (_GS_CMD, self._filename, ' '.join(list_of_pieces))
|
||||
os.system(command)
|
||||
|
||||
|
||||
# Clean temporary files
|
||||
os.remove(tmp_ps)
|
||||
for tmp_pdf_piece in list_of_pieces:
|
||||
os.remove(tmp_pdf_piece)
|
||||
os.remove(tmp_dot)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
632
gramps/gen/plug/docgen/treedoc.py
Normal file
632
gramps/gen/plug/docgen/treedoc.py
Normal file
@@ -0,0 +1,632 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2017-2018 Nick Hall
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
""" LaTeX Genealogy Tree adapter for Trees """
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from abc import ABCMeta, abstractmethod
|
||||
import os
|
||||
import shutil
|
||||
from io import StringIO
|
||||
import tempfile
|
||||
import logging
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ...utils.file import search_for
|
||||
from ...lib import Person, EventType, EventRoleType, Date
|
||||
from ...display.place import displayer as _pd
|
||||
from ...utils.file import media_path_full
|
||||
from . import BaseDoc, PAPER_PORTRAIT
|
||||
from ..menu import NumberOption, TextOption, EnumeratedListOption
|
||||
from ...constfunc import win
|
||||
from ...config import config
|
||||
from ...const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# set up logging
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
LOG = logging.getLogger(".treedoc")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Private Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
_DETAIL = [{'name': _("Full"), 'value': "full"},
|
||||
{'name': _("Medium"), 'value': "medium"},
|
||||
{'name': _("Short"), 'value': "short"}]
|
||||
|
||||
_MARRIAGE = [{'name': _("Default"), 'value': ""},
|
||||
{'name': _("Above"), 'value': "marriage above"},
|
||||
{'name': _("Below"), 'value': "marriage below"},
|
||||
{'name': _("Not shown"), 'value': "no marriage"}]
|
||||
|
||||
_COLOR = [{'name': _("None"), 'value': "none"},
|
||||
{'name': _("Default"), 'value': "default"},
|
||||
{'name': _("Preferences"), 'value': "preferences"}]
|
||||
|
||||
_TIMEFLOW = [{'name': _("Down (↓)"), 'value': ""},
|
||||
{'name': _("Up (↑)"), 'value': "up"},
|
||||
{'name': _("Right (→)"), 'value': "right"},
|
||||
{'name': _("Left (←)"), 'value': "left"}]
|
||||
|
||||
_EDGES = [{'name': _("Perpendicular"), 'value': ""},
|
||||
{'name': _("Rounded"), 'value': "rounded", },
|
||||
{'name': _("Swing"), 'value': "swing", },
|
||||
{'name': _("Mesh"), 'value': 'mesh'}]
|
||||
|
||||
_NOTELOC = [{'name': _("Top"), 'value': "t"},
|
||||
{'name': _("Bottom"), 'value': "b"}]
|
||||
|
||||
_NOTESIZE = [{'name': _("Tiny"), 'value': "tiny"},
|
||||
{'name': _("Script"), 'value': "scriptsize"},
|
||||
{'name': _("Footnote"), 'value': "footnotesize"},
|
||||
{'name': _("Small"), 'value': "small"},
|
||||
{'name': _("Normal"), 'value': "normalsize"},
|
||||
{'name': _("Large"), 'value': "large"},
|
||||
{'name': _("Very large"), 'value': "Large"},
|
||||
{'name': _("Extra large"), 'value': "LARGE"},
|
||||
{'name': _("Huge"), 'value': "huge"},
|
||||
{'name': _("Extra huge"), 'value': "Huge"}]
|
||||
|
||||
if win():
|
||||
_LATEX_FOUND = search_for("lualatex.exe")
|
||||
else:
|
||||
_LATEX_FOUND = search_for("lualatex")
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# TreeOptions
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
class TreeOptions:
|
||||
"""
|
||||
Defines all of the controls necessary
|
||||
to configure the genealogy tree reports.
|
||||
"""
|
||||
def add_menu_options(self, menu):
|
||||
"""
|
||||
Add all graph related options to the menu.
|
||||
|
||||
:param menu: The menu the options should be added to.
|
||||
:type menu: :class:`.Menu`
|
||||
:return: nothing
|
||||
"""
|
||||
################################
|
||||
category = _("Node Options")
|
||||
################################
|
||||
|
||||
detail = EnumeratedListOption(_("Node detail"), "full")
|
||||
for item in _DETAIL:
|
||||
detail.add_item(item["value"], item["name"])
|
||||
detail.set_help(_("Detail of information to be shown in a node."))
|
||||
menu.add_option(category, "detail", detail)
|
||||
|
||||
marriage = EnumeratedListOption(_("Marriage"), "")
|
||||
for item in _MARRIAGE:
|
||||
marriage.add_item(item["value"], item["name"])
|
||||
marriage.set_help(_("Position of marriage information."))
|
||||
menu.add_option(category, "marriage", marriage)
|
||||
|
||||
nodesize = NumberOption(_("Node size"), 25, 5, 100, 5)
|
||||
nodesize.set_help(_("One dimension of a node, in mm. If the timeflow "
|
||||
"is up or down then this is the width, otherwise "
|
||||
"it is the height."))
|
||||
menu.add_option(category, "nodesize", nodesize)
|
||||
|
||||
levelsize = NumberOption(_("Level size"), 35, 5, 100, 5)
|
||||
levelsize.set_help(_("One dimension of a node, in mm. If the timeflow "
|
||||
"is up or down then this is the height, otherwise "
|
||||
"it is the width."))
|
||||
menu.add_option(category, "levelsize", levelsize)
|
||||
|
||||
nodecolor = EnumeratedListOption(_("Color"), "none")
|
||||
for item in _COLOR:
|
||||
nodecolor.add_item(item["value"], item["name"])
|
||||
nodecolor.set_help(_("Node color."))
|
||||
menu.add_option(category, "nodecolor", nodecolor)
|
||||
|
||||
################################
|
||||
category = _("Tree Options")
|
||||
################################
|
||||
|
||||
timeflow = EnumeratedListOption(_("Timeflow"), "")
|
||||
for item in _TIMEFLOW:
|
||||
timeflow.add_item(item["value"], item["name"])
|
||||
timeflow.set_help(_("Direction that the graph will grow over time."))
|
||||
menu.add_option(category, "timeflow", timeflow)
|
||||
|
||||
edges = EnumeratedListOption(_("Edge style"), "")
|
||||
for item in _EDGES:
|
||||
edges.add_item(item["value"], item["name"])
|
||||
edges.set_help(_("Style of the edges between nodes."))
|
||||
menu.add_option(category, "edges", edges)
|
||||
|
||||
leveldist = NumberOption(_("Level distance"), 5, 1, 20, 1)
|
||||
leveldist.set_help(_("The minimum amount of free space, in mm, "
|
||||
"between levels. For vertical graphs, this "
|
||||
"corresponds to spacing between rows. For "
|
||||
"horizontal graphs, this corresponds to spacing "
|
||||
"between columns."))
|
||||
menu.add_option(category, "leveldist", leveldist)
|
||||
|
||||
################################
|
||||
category = _("Note")
|
||||
################################
|
||||
|
||||
note = TextOption(_("Note to add to the tree"), [""])
|
||||
note.set_help(_("This text will be added to the tree."))
|
||||
menu.add_option(category, "note", note)
|
||||
|
||||
noteloc = EnumeratedListOption(_("Note location"), 't')
|
||||
for item in _NOTELOC:
|
||||
noteloc.add_item(item["value"], item["name"])
|
||||
noteloc.set_help(_("Whether note will appear on top "
|
||||
"or bottom of the page."))
|
||||
menu.add_option(category, "noteloc", noteloc)
|
||||
|
||||
notesize = EnumeratedListOption(_("Note size"), 'normalsize')
|
||||
for item in _NOTESIZE:
|
||||
notesize.add_item(item["value"], item["name"])
|
||||
notesize.set_help(_("The size of note text."))
|
||||
menu.add_option(category, "notesize", notesize)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# TreeDoc
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
class TreeDoc(metaclass=ABCMeta):
|
||||
"""
|
||||
Abstract Interface for genealogy tree document generators. Output formats
|
||||
for genealogy tree reports must implement this interface to be used by the
|
||||
report system.
|
||||
"""
|
||||
@abstractmethod
|
||||
def start_tree(self, option_list):
|
||||
"""
|
||||
Write the start of a tree.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def end_tree(self):
|
||||
"""
|
||||
Write the end of a tree.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def start_subgraph(self, level, subgraph_type, family, option_list=None):
|
||||
"""
|
||||
Write the start of a subgraph.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def end_subgraph(self, level):
|
||||
"""
|
||||
Write the end of a subgraph.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def write_node(self, db, level, node_type, person, marriage_flag,
|
||||
option_list=None):
|
||||
"""
|
||||
Write the contents of a node.
|
||||
"""
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# TreeDocBase
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
class TreeDocBase(BaseDoc, TreeDoc):
|
||||
"""
|
||||
Base document generator for all Graphviz document generators. Classes that
|
||||
inherit from this class will only need to implement the close function.
|
||||
The close function will generate the actual file of the appropriate type.
|
||||
"""
|
||||
def __init__(self, options, paper_style):
|
||||
BaseDoc.__init__(self, None, paper_style)
|
||||
|
||||
self._filename = None
|
||||
self._tex = StringIO()
|
||||
self._paper = paper_style
|
||||
|
||||
get_option = options.menu.get_option_by_name
|
||||
|
||||
self.detail = get_option('detail').get_value()
|
||||
self.marriage = get_option('marriage').get_value()
|
||||
self.nodesize = get_option('nodesize').get_value()
|
||||
self.levelsize = get_option('levelsize').get_value()
|
||||
self.nodecolor = get_option('nodecolor').get_value()
|
||||
|
||||
self.timeflow = get_option('timeflow').get_value()
|
||||
self.edges = get_option('edges').get_value()
|
||||
self.leveldist = get_option('leveldist').get_value()
|
||||
|
||||
self.note = get_option('note').get_value()
|
||||
self.noteloc = get_option('noteloc').get_value()
|
||||
self.notesize = get_option('notesize').get_value()
|
||||
|
||||
def write_start(self):
|
||||
"""
|
||||
Write the start of the document.
|
||||
"""
|
||||
paper_size = self._paper.get_size()
|
||||
name = paper_size.get_name().lower()
|
||||
if name == 'custom size':
|
||||
width = str(paper_size.get_width())
|
||||
height = str(paper_size.get_width())
|
||||
paper = 'papersize={%scm,%scm}' % (width, height)
|
||||
elif name in ('a', 'b', 'c', 'd', 'e'):
|
||||
paper = 'ansi' + name + 'paper'
|
||||
else:
|
||||
paper = name + 'paper'
|
||||
|
||||
if self._paper.get_orientation() == PAPER_PORTRAIT:
|
||||
orientation = 'portrait'
|
||||
else:
|
||||
orientation = 'landscape'
|
||||
|
||||
lmargin = self._paper.get_left_margin()
|
||||
rmargin = self._paper.get_right_margin()
|
||||
tmargin = self._paper.get_top_margin()
|
||||
bmargin = self._paper.get_bottom_margin()
|
||||
if lmargin == rmargin == tmargin == bmargin:
|
||||
margin = 'margin=%scm'% lmargin
|
||||
else:
|
||||
if lmargin == rmargin:
|
||||
margin = 'hmargin=%scm' % lmargin
|
||||
else:
|
||||
margin = 'hmargin={%scm,%scm}' % (lmargin, rmargin)
|
||||
if tmargin == bmargin:
|
||||
margin += ',vmargin=%scm' % tmargin
|
||||
else:
|
||||
margin += ',vmargin={%scm,%scm}' % (tmargin, bmargin)
|
||||
|
||||
self.write(0, '\\documentclass[%s]{article}\n' % orientation)
|
||||
|
||||
self.write(0, '\\IfFileExists{libertine.sty}{\n')
|
||||
self.write(0, ' \\usepackage{libertine}\n')
|
||||
self.write(0, '}{}\n')
|
||||
|
||||
self.write(0, '\\usepackage[%s,%s]{geometry}\n' % (paper, margin))
|
||||
self.write(0, '\\usepackage[all]{genealogytree}\n')
|
||||
self.write(0, '\\usepackage{color}\n')
|
||||
self.write(0, '\\begin{document}\n')
|
||||
|
||||
if self.nodecolor == 'preferences':
|
||||
male_bg = config.get('preferences.color-gender-male-death')[1:]
|
||||
female_bg = config.get('preferences.color-gender-female-death')[1:]
|
||||
neuter_bg = config.get('preferences.color-gender-unknown-death')[1:]
|
||||
self.write(0, '\\definecolor{male-bg}{HTML}{%s}\n' % male_bg)
|
||||
self.write(0, '\\definecolor{female-bg}{HTML}{%s}\n' % female_bg)
|
||||
self.write(0, '\\definecolor{neuter-bg}{HTML}{%s}\n' % neuter_bg)
|
||||
|
||||
if ''.join(self.note) != '' and self.noteloc == 't':
|
||||
for line in self.note:
|
||||
self.write(0, '{\\%s %s}\\par\n' % (self.notesize, line))
|
||||
self.write(0, '\\bigskip\n')
|
||||
|
||||
self.write(0, '\\begin{tikzpicture}\n')
|
||||
|
||||
def start_tree(self, option_list):
|
||||
self.write(0, '\\genealogytree[\n')
|
||||
self.write(0, 'processing=database,\n')
|
||||
if self.marriage:
|
||||
info = self.detail + ' ' + self.marriage
|
||||
else:
|
||||
info = self.detail
|
||||
self.write(0, 'database format=%s,\n' % info)
|
||||
if self.timeflow:
|
||||
self.write(0, 'timeflow=%s,\n' % self.timeflow)
|
||||
if self.edges:
|
||||
self.write(0, 'edges=%s,\n' % self.edges)
|
||||
if self.leveldist != 5:
|
||||
self.write(0, 'level distance=%smm,\n' % self.leveldist)
|
||||
if self.nodesize != 25:
|
||||
self.write(0, 'node size=%smm,\n' % self.nodesize)
|
||||
if self.levelsize != 35:
|
||||
self.write(0, 'level size=%smm,\n' % self.levelsize)
|
||||
if self.nodecolor == 'none':
|
||||
self.write(0, 'tcbset={male/.style={},\n')
|
||||
self.write(0, ' female/.style={},\n')
|
||||
self.write(0, ' neuter/.style={}},\n')
|
||||
if self.nodecolor == 'preferences':
|
||||
self.write(0, 'tcbset={male/.style={colback=male-bg},\n')
|
||||
self.write(0, ' female/.style={colback=female-bg},\n')
|
||||
self.write(0, ' neuter/.style={colback=neuter-bg}},\n')
|
||||
|
||||
for option in option_list:
|
||||
self.write(0, '%s,\n' % option)
|
||||
|
||||
self.write(0, ']{\n')
|
||||
|
||||
def end_tree(self):
|
||||
self.write(0, '}\n')
|
||||
|
||||
def write_end(self):
|
||||
"""
|
||||
Write the end of the document.
|
||||
"""
|
||||
self.write(0, '\\end{tikzpicture}\n')
|
||||
|
||||
if ''.join(self.note) != '' and self.noteloc == 'b':
|
||||
self.write(0, '\\bigskip\n')
|
||||
for line in self.note:
|
||||
self.write(0, '\\par{\\%s %s}\n' % (self.notesize, line))
|
||||
|
||||
self.write(0, '\\end{document}\n')
|
||||
|
||||
def start_subgraph(self, level, subgraph_type, family, option_list=None):
|
||||
options = ['id=%s' % family.gramps_id]
|
||||
if option_list:
|
||||
options.extend(option_list)
|
||||
if subgraph_type == 'sandclock':
|
||||
self.write(level, 'sandclock{\n')
|
||||
else:
|
||||
self.write(level, '%s[%s]{\n' % (subgraph_type, ','.join(options)))
|
||||
|
||||
def end_subgraph(self, level):
|
||||
self.write(level, '}\n')
|
||||
|
||||
def write_node(self, db, level, node_type, person, marriage_flag,
|
||||
option_list=None):
|
||||
options = ['id=%s' % person.gramps_id]
|
||||
if option_list:
|
||||
options.extend(option_list)
|
||||
self.write(level, '%s[%s]{\n' % (node_type, ','.join(options)))
|
||||
if person.gender == Person.MALE:
|
||||
self.write(level+1, 'male,\n')
|
||||
elif person.gender == Person.FEMALE:
|
||||
self.write(level+1, 'female,\n')
|
||||
elif person.gender == Person.UNKNOWN:
|
||||
self.write(level+1, 'neuter,\n')
|
||||
name = person.get_primary_name()
|
||||
nick = name.get_nick_name()
|
||||
surn = name.get_surname()
|
||||
name_parts = [self.format_given_names(name),
|
||||
'\\nick{{{}}}'.format(nick) if nick else '',
|
||||
'\\surn{{{}}}'.format(surn) if surn else '']
|
||||
self.write(level+1, 'name = {{{}}},\n'.format(
|
||||
' '.join([e for e in name_parts if e])))
|
||||
for eventref in person.get_event_ref_list():
|
||||
if eventref.role == EventRoleType.PRIMARY:
|
||||
event = db.get_event_from_handle(eventref.ref)
|
||||
self.write_event(db, level+1, event)
|
||||
if marriage_flag:
|
||||
for handle in person.get_family_handle_list():
|
||||
family = db.get_family_from_handle(handle)
|
||||
for eventref in family.get_event_ref_list():
|
||||
if eventref.role == EventRoleType.FAMILY:
|
||||
event = db.get_event_from_handle(eventref.ref)
|
||||
self.write_event(db, level+1, event)
|
||||
for attr in person.get_attribute_list():
|
||||
if str(attr.get_type()) == 'Occupation':
|
||||
self.write(level+1, 'profession = {%s},\n' % attr.get_value())
|
||||
if str(attr.get_type()) == 'Comment':
|
||||
self.write(level+1, 'comment = {%s},\n' % attr.get_value())
|
||||
for mediaref in person.get_media_list():
|
||||
media = db.get_object_from_handle(mediaref.ref)
|
||||
path = media_path_full(db, media.get_path())
|
||||
if os.path.isfile(path):
|
||||
self.write(level+1, 'image = {%s},\n' % path)
|
||||
break # first image only
|
||||
self.write(level, '}\n')
|
||||
|
||||
def write_event(self, db, level, event):
|
||||
"""
|
||||
Write an event.
|
||||
"""
|
||||
modifier = None
|
||||
if event.type == EventType.BIRTH:
|
||||
event_type = 'birth'
|
||||
if 'died' in event.description.lower():
|
||||
modifier = 'died'
|
||||
if 'stillborn' in event.description.lower():
|
||||
modifier = 'stillborn'
|
||||
# modifier = 'out of wedlock'
|
||||
elif event.type == EventType.BAPTISM:
|
||||
event_type = 'baptism'
|
||||
elif event.type == EventType.ENGAGEMENT:
|
||||
event_type = 'engagement'
|
||||
elif event.type == EventType.MARRIAGE:
|
||||
event_type = 'marriage'
|
||||
elif event.type == EventType.DIVORCE:
|
||||
event_type = 'divorce'
|
||||
elif event.type == EventType.DEATH:
|
||||
event_type = 'death'
|
||||
elif event.type == EventType.BURIAL:
|
||||
event_type = 'burial'
|
||||
if 'killed' in event.description.lower():
|
||||
modifier = 'killed'
|
||||
elif event.type == EventType.CREMATION:
|
||||
event_type = 'burial'
|
||||
modifier = 'cremated'
|
||||
else:
|
||||
return
|
||||
|
||||
date = event.get_date_object()
|
||||
|
||||
if date.get_calendar() == Date.CAL_GREGORIAN:
|
||||
calendar = 'AD' # GR
|
||||
elif date.get_calendar() == Date.CAL_JULIAN:
|
||||
calendar = 'JU'
|
||||
else:
|
||||
calendar = ''
|
||||
|
||||
if date.get_modifier() == Date.MOD_ABOUT:
|
||||
calendar = 'ca' + calendar
|
||||
|
||||
date_str = self.format_iso(date.get_ymd(), calendar)
|
||||
if date.get_modifier() == Date.MOD_BEFORE:
|
||||
date_str = '/' + date_str
|
||||
elif date.get_modifier() == Date.MOD_AFTER:
|
||||
date_str = date_str + '/'
|
||||
elif date.is_compound():
|
||||
stop_date = self.format_iso(date.get_stop_ymd(), calendar)
|
||||
date_str = date_str + '/' + stop_date
|
||||
|
||||
place = _pd.display_event(db, event)
|
||||
|
||||
if modifier:
|
||||
event_type += '+'
|
||||
self.write(level, '%s = {%s}{%s}{%s},\n' %
|
||||
(event_type, date_str, place, modifier))
|
||||
elif place == '':
|
||||
event_type += '-'
|
||||
self.write(level, '%s = {%s},\n' % (event_type, date_str))
|
||||
else:
|
||||
self.write(level, '%s = {%s}{%s},\n' %
|
||||
(event_type, date_str, place))
|
||||
|
||||
def format_given_names(self, name):
|
||||
"""
|
||||
Format given names.
|
||||
"""
|
||||
first = name.get_first_name()
|
||||
call = name.get_call_name()
|
||||
if call:
|
||||
if call in first:
|
||||
where = first.index(call)
|
||||
return '{before}\\pref{{{call}}}{after}'.format(
|
||||
before=first[:where],
|
||||
call=call,
|
||||
after=first[where+len(call):])
|
||||
else:
|
||||
# ignore erroneous call name
|
||||
return first
|
||||
else:
|
||||
return first
|
||||
|
||||
def format_iso(self, date_tuple, calendar):
|
||||
"""
|
||||
Format an iso date.
|
||||
"""
|
||||
year, month, day = date_tuple
|
||||
if year == 0:
|
||||
iso_date = ''
|
||||
elif month == 0:
|
||||
iso_date = str(year)
|
||||
elif day == 0:
|
||||
iso_date = '%s-%s' % (year, month)
|
||||
else:
|
||||
iso_date = '%s-%s-%s' % (year, month, day)
|
||||
if calendar and calendar != 'AD':
|
||||
iso_date = '(%s)%s' % (calendar, iso_date)
|
||||
return iso_date
|
||||
|
||||
def write(self, level, text):
|
||||
"""
|
||||
Write indented text.
|
||||
"""
|
||||
self._tex.write(' '*level + text)
|
||||
|
||||
def open(self, filename):
|
||||
""" Implement TreeDocBase.open() """
|
||||
self._filename = os.path.normpath(os.path.abspath(filename))
|
||||
self.write_start()
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
This isn't useful by itself. Other classes need to override this and
|
||||
actually generate a file.
|
||||
"""
|
||||
self.write_end()
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# TreeTexDoc
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
class TreeTexDoc(TreeDocBase):
|
||||
"""
|
||||
TreeTexDoc implementation that generates a .tex file.
|
||||
"""
|
||||
|
||||
def close(self):
|
||||
""" Implements TreeDocBase.close() """
|
||||
TreeDocBase.close(self)
|
||||
|
||||
# Make sure the extension is correct
|
||||
if self._filename[-4:] != ".tex":
|
||||
self._filename += ".tex"
|
||||
|
||||
with open(self._filename, "w") as texfile:
|
||||
texfile.write(self._tex.getvalue())
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# TreePdfDoc
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
class TreePdfDoc(TreeDocBase):
|
||||
"""
|
||||
TreePdfDoc implementation that generates a .pdf file.
|
||||
"""
|
||||
|
||||
def close(self):
|
||||
""" Implements TreeDocBase.close() """
|
||||
TreeDocBase.close(self)
|
||||
|
||||
# Make sure the extension is correct
|
||||
if self._filename[-4:] != ".pdf":
|
||||
self._filename += ".pdf"
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
with open(os.path.join(tmpdir, 'temp.tex'), "w") as texfile:
|
||||
texfile.write(self._tex.getvalue())
|
||||
os.system('lualatex -output-directory %s temp.tex >/dev/null'
|
||||
% tmpdir)
|
||||
shutil.copy(os.path.join(tmpdir, 'temp.pdf'), self._filename)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Various Genealogy Tree formats.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
FORMATS = []
|
||||
|
||||
if _LATEX_FOUND:
|
||||
FORMATS += [{'type' : "pdf",
|
||||
'ext' : "pdf",
|
||||
'descr': _("PDF"),
|
||||
'mime' : "application/pdf",
|
||||
'class': TreePdfDoc}]
|
||||
|
||||
FORMATS += [{'type' : "tex",
|
||||
'ext' : "tex",
|
||||
'descr': _("LaTeX File"),
|
||||
'mime' : "application/x-latex",
|
||||
'class': TreeTexDoc}]
|
||||
@@ -457,79 +457,98 @@ class BookList(object):
|
||||
"""
|
||||
Saves the current BookList to the associated file.
|
||||
"""
|
||||
f = open(self.file, "w")
|
||||
f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
||||
f.write('<booklist>\n')
|
||||
for name in sorted(self.bookmap): # enable a diff of archived copies
|
||||
book = self.get_book(name)
|
||||
dbname = book.get_dbname()
|
||||
f.write('<book name="%s" database="%s">\n' % (name, dbname) )
|
||||
for item in book.get_item_list():
|
||||
f.write(' <item name="%s" trans_name="%s">\n' %
|
||||
(item.get_name(),item.get_translated_name() ) )
|
||||
options = item.option_class.handler.options_dict
|
||||
for option_name in sorted(options.keys()): # enable a diff
|
||||
option_value = options[option_name]
|
||||
if isinstance(option_value, (list, tuple)):
|
||||
f.write(' <option name="%s" value="" '
|
||||
'length="%d">\n' % (
|
||||
escape(option_name),
|
||||
len(options[option_name]) ) )
|
||||
for list_index in range(len(option_value)):
|
||||
option_type = type_name(option_value[list_index])
|
||||
value = escape(str(option_value[list_index]))
|
||||
with open(self.file, "w", encoding="utf-8") as b_f:
|
||||
b_f.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
|
||||
b_f.write('<booklist>\n')
|
||||
for name in sorted(self.bookmap): # enable a diff of archived copies
|
||||
book = self.get_book(name)
|
||||
dbname = escape(book.get_dbname())
|
||||
b_f.write(' <book name="%s" database="%s">'
|
||||
'\n' % (escape(name), dbname))
|
||||
for item in book.get_item_list():
|
||||
b_f.write(' <item name="%s" '
|
||||
'trans_name="%s">\n' % (
|
||||
item.get_name(),
|
||||
item.get_translated_name()))
|
||||
options = item.option_class.handler.options_dict
|
||||
for option_name in sorted(options.keys()): # enable a diff
|
||||
option_value = options[option_name]
|
||||
if isinstance(option_value, (list, tuple)):
|
||||
b_f.write(' <option name="%s" value="" '
|
||||
'length="%d">\n' % (
|
||||
escape(option_name),
|
||||
len(options[option_name])))
|
||||
for list_index in range(len(option_value)):
|
||||
option_type = type_name(
|
||||
option_value[list_index])
|
||||
value = escape(str(option_value[list_index]))
|
||||
value = value.replace('"', '"')
|
||||
b_f.write(' <listitem number="%d" '
|
||||
'type="%s" value="%s"/>\n' % (
|
||||
list_index,
|
||||
option_type,
|
||||
value))
|
||||
b_f.write(' </option>\n')
|
||||
else:
|
||||
option_type = type_name(option_value)
|
||||
value = escape(str(option_value))
|
||||
value = value.replace('"', '"')
|
||||
f.write(' <listitem number="%d" type="%s" '
|
||||
'value="%s"/>\n' % (
|
||||
list_index,
|
||||
option_type,
|
||||
value ) )
|
||||
f.write(' </option>\n')
|
||||
else:
|
||||
option_type = type_name(option_value)
|
||||
value = escape(str(option_value))
|
||||
value = value.replace('"', '"')
|
||||
f.write(' <option name="%s" type="%s" '
|
||||
'value="%s"/>\n' % (
|
||||
escape(option_name),
|
||||
option_type,
|
||||
value) )
|
||||
b_f.write(' <option name="%s" type="%s" '
|
||||
'value="%s"/>\n' % (
|
||||
escape(option_name),
|
||||
option_type,
|
||||
value))
|
||||
|
||||
f.write(' <style name="%s"/>\n' % item.get_style_name() )
|
||||
f.write(' </item>\n')
|
||||
if book.get_paper_name():
|
||||
f.write(' <paper name="%s"/>\n' % book.get_paper_name() )
|
||||
if book.get_orientation() is not None: # 0 is legal
|
||||
f.write(' <orientation value="%s"/>\n' %
|
||||
book.get_orientation() )
|
||||
if book.get_paper_metric() is not None: # 0 is legal
|
||||
f.write(' <metric value="%s"/>\n' % book.get_paper_metric() )
|
||||
if book.get_custom_paper_size():
|
||||
size = book.get_custom_paper_size()
|
||||
f.write(' <size value="%f %f"/>\n' % (size[0], size[1]) )
|
||||
if book.get_margins():
|
||||
for pos in range(len(book.get_margins())):
|
||||
f.write(' <margin number="%s" value="%f"/>\n' %
|
||||
(pos, book.get_margin(pos)) )
|
||||
if book.get_format_name():
|
||||
f.write(' <format name="%s"/>\n' % book.get_format_name() )
|
||||
if book.get_output():
|
||||
f.write(' <output name="%s"/>\n' % book.get_output() )
|
||||
f.write('</book>\n')
|
||||
b_f.write(' <style name="%s"/>'
|
||||
'\n' % item.get_style_name())
|
||||
b_f.write(' </item>\n')
|
||||
if book.get_paper_name():
|
||||
b_f.write(' <paper name="%s"/>'
|
||||
'\n' % book.get_paper_name())
|
||||
if book.get_orientation() is not None: # 0 is legal
|
||||
b_f.write(' <orientation value="%s"/>'
|
||||
'\n' % book.get_orientation())
|
||||
if book.get_paper_metric() is not None: # 0 is legal
|
||||
b_p_metric = book.get_paper_metric()
|
||||
if isinstance(b_p_metric, bool):
|
||||
b_p_metric = int(b_p_metric)
|
||||
b_f.write(' <metric value="%s"/>'
|
||||
'\n' % b_p_metric)
|
||||
if book.get_custom_paper_size():
|
||||
size = book.get_custom_paper_size()
|
||||
b_f.write(' <size value="%f %f"/>'
|
||||
'\n' % (size[0], size[1]))
|
||||
if book.get_margins():
|
||||
for pos in range(len(book.get_margins())):
|
||||
b_f.write(' <margin number="%s" '
|
||||
'value="%f"/>\n' % (
|
||||
pos, book.get_margin(pos)))
|
||||
if book.get_format_name():
|
||||
b_f.write(' <format name="%s"/>'
|
||||
'\n' % book.get_format_name())
|
||||
if book.get_output():
|
||||
b_f.write(' <output name="%s"/>'
|
||||
'\n' % escape(book.get_output()))
|
||||
b_f.write(' </book>\n')
|
||||
|
||||
b_f.write('</booklist>\n')
|
||||
|
||||
f.write('</booklist>\n')
|
||||
f.close()
|
||||
|
||||
def parse(self):
|
||||
"""
|
||||
Loads the BookList from the associated file, if it exists.
|
||||
"""
|
||||
try:
|
||||
p = make_parser()
|
||||
p.setContentHandler(BookParser(self, self.dbase))
|
||||
the_file = open(self.file)
|
||||
p.parse(the_file)
|
||||
the_file.close()
|
||||
parser = make_parser()
|
||||
parser.setContentHandler(BookParser(self, self.dbase))
|
||||
# bug 10387; XML should be utf8, but was not previously saved
|
||||
# that way. So try to read utf8, if fails, try with system
|
||||
# encoding. Only an issue on non-utf8 systems.
|
||||
try:
|
||||
with open(self.file, encoding="utf-8") as the_file:
|
||||
parser.parse(the_file)
|
||||
except UnicodeDecodeError:
|
||||
with open(self.file) as the_file:
|
||||
parser.parse(the_file)
|
||||
except (IOError, OSError, ValueError, SAXParseException, KeyError,
|
||||
AttributeError):
|
||||
pass
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user