Merge branch 'gramps51'

This commit is contained in:
prculley 2019-11-08 11:46:40 -06:00
commit e3eedb2219
59 changed files with 15495 additions and 26407 deletions

View File

@ -473,11 +473,10 @@ table.eventlist tbody tr td.ColumnSources {
margin: 0px auto;
display: block;
border: solid 1px #999;
max-width: 800px;
height: auto;
}
@media only screen and (max-width: 1080px) {
@media only screen and (max-width: 1600px) {
#GalleryDisplay img {
max-width: 100%;
}

View File

@ -838,11 +838,10 @@ div#EventDetail table.eventlist tbody tr td.ColumnDate {
}
#GalleryDisplay img {
margin: 0 auto;
max-width: 800px;
height: auto;
}
@media only screen and (max-width: 1080px) {
@media only screen and (max-width: 1600px) {
#GalleryDisplay img {
max-width: 100%;
}

View File

@ -524,11 +524,10 @@ table.eventlist tbody tr td.ColumnSources {
margin: 0px auto;
display: block;
border: solid 1px #7C8F7C;
max-width: 800px;
height: auto;
}
@media only screen and (max-width: 1080px) {
@media only screen and (max-width: 1600px) {
#GalleryDisplay img {
max-width: 100%;
}

View File

@ -512,15 +512,15 @@ table.eventlist tbody tr td.ColumnSources {
margin: 0px auto;
display: block;
border: solid 1px #669;
max-width: 800px;
height: auto;
}
@media only screen and (max-width: 1080px) {
@media only screen and (max-width: 1600px) {
#GalleryDisplay img {
max-width: 100%;
}
}
#GalleryDetail h3 {
text-align: center;
}

View File

@ -512,11 +512,10 @@ table.eventlist tbody tr td.ColumnSources {
margin: 0px auto;
display: block;
border: solid 1px #EA8414;
max-width: 800px;
height: auto;
}
@media only screen and (max-width: 1080px) {
@media only screen and (max-width: 1600px) {
#GalleryDisplay img {
max-width: 100%;
}

View File

@ -513,11 +513,10 @@ table.eventlist tbody tr td.ColumnSources {
margin: 0px auto;
display: block;
border: solid 1px #7CA3DD;
max-width: 800px;
height: auto;
}
@media only screen and (max-width: 1080px) {
@media only screen and (max-width: 1600px) {
#GalleryDisplay img {
max-width: 100%;
}

View File

@ -82,6 +82,7 @@ body > div {
}
.content {
padding: 1.5em 1.5em;
overflow: auto;
background: url(../images/Web_Mainz_Mid.png) #FFF2C6 repeat;
}
#ThumbnailPreview div.snapshot {
@ -467,11 +468,10 @@ table.eventlist tbody tr td.ColumnSources {
margin: 0px auto;
display:block;
border: solid 1px #7D5925;
max-width: 800px;
height: auto;
}
@media only screen and (max-width: 1080px) {
@media only screen and (max-width: 1600px) {
#GalleryDisplay img {
max-width: 100%;
}

View File

@ -747,11 +747,10 @@ table.eventlist tbody tr td.ColumnSources {
}
#GalleryDisplay img {
margin:0 auto;
max-width: 800px;
height: auto;
}
@media only screen and (max-width: 1080px) {
@media only screen and (max-width: 1600px) {
#GalleryDisplay img {
max-width: 100%;
}

View File

@ -9,7 +9,7 @@
# 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,
# 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.
@ -20,10 +20,10 @@
#
# $Id: $
#
**************************************************************************************************
*******************************************************************************
GRAMPS Cascading Style Sheet
Style Name: Combined Ancestor Tree Style Sheet
***************************************************************************************************
*******************************************************************************
#
===== Ancestor Graph Color Scheme =====
Males #BCEAF6
@ -33,10 +33,8 @@ Unknown #000
===== Web Graphics =====
Males Web_Gender_Male.png
Females Web_Gender_Female.png
# ------------------------------------------------------------------------------------------------- */
/* Subsections : Ancestors Tree
----------------------------------------------------- */
# -------------------------------------------------------------------------- #
/* Subsections : Ancestors Tree -------------------------------------------- */
#tree {
page-break-before:always;
margin:0;
@ -52,8 +50,8 @@ Females Web_Gender_Female.png
}
#treeContainer div.boxbg {
position:absolute;
margin:0;
padding:0;
margin:0px;
padding:0px;
background:none;
}
#treeContainer div.boxbg a,
@ -61,41 +59,43 @@ Females Web_Gender_Female.png
position:relative;
z-index:10;
display:block;
font:normal .7em/1.4em sans-serif;
font:normal 1.1em/1.4em sans-serif;
text-align:center;
word-break:break-word;
word-wrap:break-word;
text-decoration:none;
color: #00029D;
width:118px;
padding:5px 20px 7px 20px;
width:280px;
min-height: 70px;
margin-left:16px;
background-color: #FFF;
border: solid 1px #000;
border: solid 2px #000;
border-radius: 10px;
}
#treeContainer div.boxbg a.noThumb,
#treeContainer div.AncCol3 a,
#treeContainer div.AncCol4 a,
#treeContainer div.AncCol3 span.unlinked,
#treeContainer div.AncCol4 a,
#treeContainer div.AncCol4 span.unlinked {
margin-top:10px;
float: right;
}
#treeContainer div.boxbg a:hover {
position:relative;
z-index:999;
font-size:1em;
font-size:1.3em;
word-break:break-word;
word-wrap:break-word;
text-decoration:none;
color: #00029D;
width:190px;
width:400px;
margin-left:-20px;
padding:10px 25px 12px 25px;
border: solid 2px #000;
padding: 0px 0px 0px 40px;
}
#treeContainer div.boxbg a:hover,
#treeContainer div.AncCol3 a:hover,
#treeContainer div.boxbg a:hover,
#treeContainer div.AncCol4 a:hover {
margin-top:-44px;
}
#treeContainer div.boxbg a.noThumb:hover {
margin-top:0;
padding-left: 10px;
}
#treeContainer div.AncCol0 a:hover {
margin-left:12px;
@ -105,48 +105,73 @@ Females Web_Gender_Female.png
}
#treeContainer div.boxbg span.thumbnail {
display:block;
max-width:80px;
max-height:65px;
margin:0 auto;
padding:4px 0;
position: absolute;
max-width:85px;
max-height:75px;
left: 3px;
top: 3px;
}
#treeContainer div.boxbg span.thumbnail img {
max-width:80px;
max-height:65px;
margin:0 auto;
#treeContainer div.boxbg a.thumbnail table td.img {
padding-right: 5px;
}
#treeContainer div.boxbg a:hover span.thumbnail, #treeContainer div.boxbg a:hover span.thumbnail img {
height:80px;
#treeContainer div.boxbg a.thumbnail:hover table td.img {
padding-right: 9px;
}
#treeContainer div.AncCol3 span.thumbnail, #treeContainer div.AncCol4 span.thumbnail {
#treeContainer div.boxbg a.thumbnail table td.name {
padding-top:3px;
padding-left: 2px;
padding-right: 23px;
width: 90%;
}
#treeContainer div.boxbg a.thumbnail img {
margin-left:0px;
padding-left: 0px;
border-radius: 5px;
}
#treeContainer div.boxbg a.thumbnail:hover img {
max-height:90%;
margin-left:5px;
position: absolute;
left: 0px;
top: 4px;
border-radius: 5px;
}
#treeContainer div.boxbg table td:first-child, table th:first-child {
padding-left: 5px;
padding-top: 5px;
}
#IndividualDetail div.subsection table tr td:first-child {
padding-left: 5px;
padding-top: 5px;
}
#treeContainer #treeContainer div.AncCol4 span.thumbnail {
display:none;
}
#treeContainer div.boxbg a:hover span.thumbnail {
display:block;
}
#treeContainer div.boxbg span.fullname {
display: none;
}
#treeContainer div.boxbg span.shortname {
display: inline;
}
#treeContainer div.boxbg a:hover span.fullname {
display: inline;
}
#treeContainer div.boxbg a:hover span.shortname {
display: none;
}
#treeContainer div.boxbg a:hover {
float: right;
margin-top: 10px;
border: solid 4px #000;
}
#treeContainer div.male a,
#treeContainer div.male span.unlinked {
background:url(../images/Web_Gender_Male.png) #BCEAF6 no-repeat top right;
}
#treeContainer div.female a,
#treeContainer div.female a,
#treeContainer div.female span.unlinked {
background:url(../images/Web_Gender_Female.png) #FFC0CB no-repeat top right;
}

View File

@ -9,6 +9,12 @@ beg
- h Hans_Peter.8 17/4/1904 #bp Rønne,_Bornholm,_Denmark 29/1/1977 #dp San_Francisco,_San_Francisco_Co.,_CA
end
notes Hansdotter Anna.1
beg
******************************************************************890123456789
******************************************************************89 123456789
end notes
notes Smith Hjalmar.5
beg
BIOGRAPHY
@ -61,7 +67,7 @@ Some Bold Unicode Characters: ࣶǼЀج⿄㑝&#15691
Some Italic Unicode Characters: ࣶǼЀج⿄㑝㵋圛墉幵聟聦𐅉🚶🛈
end notes
fam Smith Gus.6 +~1920 Michaels Evelyn.25 ~1897
fam Smith Gus.6 +~1920 Michaels Evelyn.25 ~1897 0
fam Smith Hjalmar.5 +31/10/1927 #mp Reno,_Washoe_Co.,_NV Ohman Marjorie.26 3/6/1903 #bp Denver,_Denver_Co.,_CO,_Denver_Co.,_Colorado,_USA 22/6/1980 #dp Reno,_Washoe_Co.,_NV
beg
@ -98,13 +104,18 @@ beg
- h Martin.17 1794..1796 #bp Tommarp,_Kristianstad_Län,_Sweden #dp Sweden
end
fam Willard Edwin.42 ~1886 +~1910 Smith Kirsti_Marie.2
fam Willard Edwin.42 ~1886 0 +~1910 Smith Kirsti_Marie.2
fam Smith Magnes.38 +24/8/1884 #mp Rønne,_Bornholm,_Denmark Streiffert Anna.43 23/9/1860 #bp Hoya/Jona/Hoia,_Sweden 2/2/1927 #dp Rønne,_Bornholm,_Denmark
fam Tester The.14 + Tester Mrs.44 0
beg
- h Tom.45 0
- h Tom.45 Von_Tester_y_tested 0
- Fake.46 von_Person 1954 #bp Fremont,_Alameda_Co.,_CA
- f Mary.47 0
- f Martha.48 0
- h John.49 0
- h Mark.50 0
end
notes Tester Mrs.44

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +1,52 @@
Anna Hansdotter;;;;;2/10/1864-29/9/1945
Keith Lloyd Smith;Lloyd Smith;Janis Green;;;11/8/1966
Hans Peter Smith;Gustaf Smith;Anna Hansdotter;;;17/4/1904-29/1/1977
Hanna Smith;Martin Smith0;Elna Jefferson;;;29/1/1821
Herman Julius Nielsen;;;;;31/8/1889-1945
Evelyn Michaels;;;;;1897
Marjorie Lee Smith;Hjalmar Smith0;Marjorie Ohman;;;4/11/1934
Gus Smith;Gustaf Smith;Anna Hansdotter;;;11/9/1897-21/10/1963
Jennifer Anderson;;;;;5/11/1907-29/5/1985
Lillie Harriet Jones;;;;;2/5/1910-26/6/1990
John Hjalmar Smith;Hjalmar Smith0;Marjorie Ohman;;;30/1/1932
Eric Lloyd Smith;Lloyd Smith;Janis Green;;;28/8/1963
Amber Marie Smith;Edwin Smith;Janice Adams;;;12/4/1998
Carl Emil Smith;Gustaf Smith;Anna Hansdotter;;;20/12/1899-28/1/1959
Hjalmar Smith;Gustaf Smith;Anna Hansdotter;;;31/1/1893-25/9/1894
Martin Smith;Martin Smith0;Elna Jefferson;;;19/11/1830-1899
Astrid Shermanna Augusta Smith;Gustaf Smith;Anna Hansdotter;;;31/1/1889-21/12/1963
Gustaf Smith, Sr.;Martin Smith;Kerstina Hansdotter;;;28/11/1862-23/7/1930
Marta Ericsdotter;;;;;1775
Kirsti Marie Smith;Gustaf Smith;Anna Hansdotter;;;15/12/1886-18/7/1966
Ingeman Smith;;;;;1770
Anna Streiffert;;;;;23/9/1860-2/2/1927
Craig Peter Smith;Lloyd Smith;Janis Green;;;1966
Magnes Smith;Martin Smith;Kerstina Hansdotter;;;6/10/1858-20/2/1910
Janice Ann Adams;;;;;26/8/1965
Marjorie Ohman;;;;;3/6/1903-22/6/1980
Darcy Horne;;;;;2/7/1966
Alice Paula Perkins;;;;;22/11/1933
Lars Peter Smith;Eric Smith;Darcy Horne;;;16/9/1991
Ingeman Smith0;Martin Smith0;Elna Jefferson;;;29/1/1826
Lloyd Smith;Hans Smith;Lillie Jones;;;13/3/1935
Elna Jefferson;;;;;14/9/1800-
Edwin Michael Smith;John Smith;Alice Perkins;;;24/5/1961
Kerstina Hansdotter;;;;;29/11/1832-1908
Martin Smith0;Ingeman Smith;Marta Ericsdotter;;;1794-
Marjorie Alice Smith0;John Smith;Alice Perkins;;;5/2/1960
Janis Elaine Green;;;;;2/12/1935
Mason Michael Smith;Edwin Smith;Janice Adams;;;26/6/1996
Edwin Willard;;;;;1886
Ingar Smith;Martin Smith0;Elna Jefferson;;;1823
Hjalmar Smith0;Gustaf Smith;Anna Hansdotter;;;7/4/1895-26/6/1975
Emil Smith;Martin Smith;Kerstina Hansdotter;;;27/9/1860
雪 Ke 柯;Herman Nielsen;Astrid Smith;;;
The Tester;Lloyd Smith;Janis Green;;;29/12/1954
Mrs Tester;;;;;
ピーター リチミシキスイミ;;;;;
Tom Tester;The Tester;Mrs Tester;;;
Anna Hansdotter;;;;;2/10/1864-29/9/1945
Keith Lloyd Smith;Lloyd Smith;Janis Green;;;11/8/1966
Hans Peter Smith;Gustaf Smith;Anna Hansdotter;;;17/4/1904-29/1/1977
Hanna Smith;Martin Smith0;Elna Jefferson;;;29/1/1821
Herman Julius Nielsen;;;;;31/8/1889-1945
Evelyn Michaels;;;;;1897
Marjorie Lee Smith;Hjalmar Smith0;Marjorie Ohman;;;4/11/1934
Gus Smith;Gustaf Smith;Anna Hansdotter;;;11/9/1897-21/10/1963
Jennifer Anderson;;;;;5/11/1907-29/5/1985
Lillie Harriet Jones;;;;;2/5/1910-26/6/1990
John Hjalmar Smith;Hjalmar Smith0;Marjorie Ohman;;;30/1/1932
Eric Lloyd Smith;Lloyd Smith;Janis Green;;;28/8/1963
Amber Marie Smith;Edwin Smith;Janice Adams;;;12/4/1998
Carl Emil Smith;Gustaf Smith;Anna Hansdotter;;;20/12/1899-28/1/1959
Hjalmar Smith;Gustaf Smith;Anna Hansdotter;;;31/1/1893-25/9/1894
Martin Smith;Martin Smith0;Elna Jefferson;;;19/11/1830-1899
Astrid Shermanna Augusta Smith;Gustaf Smith;Anna Hansdotter;;;31/1/1889-21/12/1963
Gustaf Smith, Sr.;Martin Smith;Kerstina Hansdotter;;;28/11/1862-23/7/1930
Marta Ericsdotter;;;;;1775
Kirsti Marie Smith;Gustaf Smith;Anna Hansdotter;;;15/12/1886-18/7/1966
Ingeman Smith;;;;;1770
Anna Streiffert;;;;;23/9/1860-2/2/1927
Craig Peter Smith;Lloyd Smith;Janis Green;;;1966
Magnes Smith;Martin Smith;Kerstina Hansdotter;;;6/10/1858-20/2/1910
Janice Ann Adams;;;;;26/8/1965
Marjorie Ohman;;;;;3/6/1903-22/6/1980
Darcy Horne;;;;;2/7/1966
Lloyd Smith;Hans Smith;Lillie Jones;;;13/3/1935
Alice Paula Perkins;;;;;22/11/1933
Lars Peter Smith;Eric Smith;Darcy Horne;;;16/9/1991
Elna Jefferson;;;;;14/9/1800-
Edwin Michael Smith;John Smith;Alice Perkins;;;24/5/1961
Kerstina Hansdotter;;;;;29/11/1832-1908
Martin Smith0;Ingeman Smith;Marta Ericsdotter;;;1794-
Ingeman Smith0;Martin Smith0;Elna Jefferson;;;29/1/1826
Marjorie Alice Smith0;John Smith;Alice Perkins;;;5/2/1960
Janis Elaine Green;;;;;2/12/1935
Mason Michael Smith;Edwin Smith;Janice Adams;;;26/6/1996
Edwin Willard;;;;;1886
Ingar Smith;Martin Smith0;Elna Jefferson;;;1823
Hjalmar Smith0;Gustaf Smith;Anna Hansdotter;;;7/4/1895-26/6/1975
Emil Smith;Martin Smith;Kerstina Hansdotter;;;27/9/1860
雪 Ke 柯;Herman Nielsen;Astrid Smith;;;
ピーター リチミシキスイミ;;;;;
The Tester;Lloyd Smith;Janis Green;;;29/12/1954
Mrs Tester;;;;;
Tom Von Tester y tested;The Tester;Mrs Tester;;;
Fake von Person, I;The Tester;Mrs Tester;;;1954-
Mary Tester;The Tester;Mrs Tester;;;
Martha Tester;The Tester;Mrs Tester;;;
John Tester;The Tester;Mrs Tester;;;
Mark Tester;The Tester;Mrs Tester;;;

View File

@ -30,66 +30,65 @@
[P0014],"Denver, Denver Co., CO","Denver, Denver Co., CO",City,39.7392,104.9903 W,,[P0024],
Person,Surname,Given,Call,Suffix,Prefix,Title,Gender,Birth date,Birth place,Birth source,Baptism date,Baptism place,Baptism source,Death date,Death place,Death source,Burial date,Burial place,Burial source,Note
[I0030],Adams,Janice Ann,,,,,female,26 Aug 1965,"Fremont, Alameda Co., CA",,,,,,,,,,,
[I0016],Anderson,Jennifer,,,,,female,5 Nov 1907,"Rønne, Bornholm, Denmark",,,,,29 May 1985,"San Francisco, San Francisco Co., CA",,,,,
[I0025],Ericsdotter,Marta,,,,,female,about 1775,Sweden,,,,,,,,,,,
[I0041],Green,Janis Elaine,,,,,female,2 Dec 1935,,,,,,,,,,,,
[I0000],Hansdotter,Anna,,,,,female,2 Oct 1864,"Löderup, Malmöhus Län, Sweden",,,,,29 Sep 1945,"Sparks, Washoe Co., NV",,,,,
[I0038],Hansdotter,Kerstina,,,,,female,29 Nov 1832,"Smestorp, Kristianstad Län, Sweden",,,,,before 1908,Sweden,,,,,
[I0032],Horne,Darcy,,,,,female,2 Jul 1966,"Sacramento, Sacramento Co., CA",,,,,,,,,,,
[I0036],Jefferson,Elna,,,,,female,14 Sep 1800,"Gladsax, Kristianstad Län, Sweden",,,,,,Sweden,,,,,
[I0017],Jones,Lillie Harriet,,,,,female,2 May 1910,"Rønne, Bornholm, Denmark",,,,,26 Jun 1990,,,,,,
[I0030],Adams,Janice Ann,,,,,female,1965-08-26,[P0013],,,,,,,,,,,
[I0016],Anderson,Jennifer,,,,,female,1907-11-05,[P0003],,,,,1985-05-29,[P0002],,,,,
[I0025],Ericsdotter,Marta,,,,,female,about 1775,[P0008],,,,,,,,,,,
[I0041],Green,Janis Elaine,,,,,female,1935-12-02,,,,,,,,,,,,
[I0000],Hansdotter,Anna,,,,,female,1864-10-02,[P0000],,,,,1945-09-29,[P0001],,,,,
[I0038],Hansdotter,Kerstina,,,,,female,1832-11-29,[P0019],,,,,before 1908,[P0008],,,,,
[I0032],Horne,Darcy,,,,,female,1966-07-02,[P0015],,,,,,,,,,,
[I0036],Jefferson,Elna,,,,,female,1800-09-14,[P0004],,,,,,[P0008],,,,,
[I0017],Jones,Lillie Harriet,,,,,female,1910-05-02,[P0003],,,,,1990-06-26,,,,,,
[I0042],Ke 柯,雪,,,,,male,,,,,,,,,,,,,
[I0013],Michaels,Evelyn,,,,,female,about 1897,,,,,,,,,,,,
[I0012],Nielsen,Herman Julius,,,,,male,31 Aug 1889,"Rønne, Bornholm, Denmark",,,,,1945,,,,,,
[I0031],Ohman,Marjorie,,,,,female,3 Jun 1903,"Denver, Denver Co., CO, Denver Co., Colorado, USA",,,,,22 Jun 1980,"Reno, Washoe Co., NV",,,,,
[I0034],Perkins,Alice Paula,,,,,female,22 Nov 1933,"Sparks, Washoe Co., NV",,,,,,,,,,,
[I0002],Smith,Amber Marie,,,,,female,12 Apr 1998,"Hayward, Alameda Co., CA",,,,,,,,,,,
[I0023],Smith,Astrid Shermanna Augusta,,,,,female,31 Jan 1889,"Rønne, Bornholm, Denmark",,,,,21 Dec 1963,"San Francisco, San Francisco Co., CA",,,,,
[I0020],Smith,Carl Emil,,,,,male,20 Dec 1899,"Rønne, Bornholm, Denmark",,,,,28 Jan 1959,"Reno, Washoe Co., NV",,,,,
[I0029],Smith,Craig Peter,,,,,male,after 1966,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
[I0037],Smith,Edwin Michael,,,,,male,24 May 1961,"San Jose, Santa Clara Co., CA","Birth, Death and Marriage Records",,,,,,,,,,
[I0009],Smith,Emil,,,,,male,27 Sep 1860,"Simrishamn, Kristianstad Län, Sweden",,,,,,,,,,,
[I0019],Smith,Eric Lloyd,,,,Dr.,male,28 Aug 1963,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
[I0015],Smith,Gus,,,,,male,11 Sep 1897,"Rønne, Bornholm, Denmark",,,,,21 Oct 1963,"San Francisco, San Francisco Co., CA",,,,,
[I0024],Smith,Gustaf,,Sr.,,,male,28 Nov 1862,"Grostorp, Kristianstad Län, Sweden",,,,,before 23 Jul 1930,"Sparks, Washoe Co., NV",,,,,
[I0011],Smith,Hanna,,,,,female,29 Jan 1821,"Gladsax, Kristianstad Län, Sweden",,,,,,,,,,,
[I0010],Smith,Hans Peter,,,,,male,17 Apr 1904,"Rønne, Bornholm, Denmark",Birth Records,,,,29 Jan 1977,"San Francisco, San Francisco Co., CA",,5 Feb 1977,"San Francisco, San Francisco Co., CA",findagrave.com,
[I0021],Smith,Hjalmar,,,,,male,31 Jan 1893,"Rønne, Bornholm, Denmark",,,,,25 Sep 1894,"Rønne, Bornholm, Denmark",,,,,
[I0008],Smith,Hjalmar,,,,,male,7 Apr 1895,"Rønne, Bornholm, Denmark",,3 Jun 1895,"Rønne Bornholm, Denmark",,26 Jun 1975,"Reno, Washoe Co., NV",,,,,
[I0007],Smith,Ingar,,,,,female,after 1823,"Gladsax, Kristianstad Län, Sweden",,,,,,,,,,,
[I0027],Smith,Ingeman,,,,,male,about 1770,Sweden,,,,,,,,,,,
[I0004],Smith,Ingeman,,,,,male,29 Jan 1826,"Gladsax, Kristianstad Län, Sweden",,,,,,,,,,,
[I0018],Smith,John Hjalmar,,,,,male,30 Jan 1932,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
[I0001],Smith,Keith Lloyd,,,,,male,11 Aug 1966,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
[I0026],Smith,Kirsti Marie,,,,,female,15 Dec 1886,"Rønne, Bornholm, Denmark",,,,,18 Jul 1966,"San Francisco, San Francisco Co., CA",,,,,
[I0035],Smith,Lars Peter,,,,,male,16 Sep 1991,"Santa Rosa, Sonoma Co., CA",,,,,,,,,,,
[I0033],Smith,Lloyd,,,,,male,13 Mar 1935,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
[I0003],Smith,Magnes,,,,,male,6 Oct 1858,"Simrishamn, Kristianstad Län, Sweden",,,,,20 Feb 1910,"Rønne, Bornholm, Denmark",,,,,
[I0040],Smith,Marjorie Alice,,,,,female,5 Feb 1960,"San Jose, Santa Clara Co., CA",,,,,,,,,,,
[I0014],Smith,Marjorie Lee,,,,,female,4 Nov 1934,"Reno, Washoe Co., NV",,,,,,,,,,,
[I0022],Smith,Martin,,,,,male,19 Nov 1830,"Gladsax, Kristianstad Län, Sweden",,23 Nov 1830,"Gladsax, Kristianstad Län, Sweden",,between 1899 and 1905,Sweden,,,,,
[I0039],Smith,Martin,,,,,male,between 1794 and 1796,"Tommarp, Kristianstad Län, Sweden",,,,,,Sweden,,,,,
[I0005],Smith,Mason Michael,,,,,male,26 Jun 1996,"Hayward, Alameda Co., CA",,,,,,,,,,,
[I0028],Streiffert,Anna,,,,,female,23 Sep 1860,"Hoya/Jona/Hoia, Sweden",,,,,2 Feb 1927,"Rønne, Bornholm, Denmark",,,,,
[I0012],Nielsen,Herman Julius,,,,,male,1889-08-31,[P0003],,,,,1945,,,,,,
[I0031],Ohman,Marjorie,,,,,female,1903-06-03,[P0014],,,,,1980-06-22,[P0005],,,,,
[I0034],Perkins,Alice Paula,,,,,female,1933-11-22,[P0001],,,,,,,,,,,
[I0002],Smith,Amber Marie,,,,,female,1998-04-12,[P0006],,,,,,,,,,,
[I0023],Smith,Astrid Shermanna Augusta,,,,,female,1889-01-31,[P0003],,,,,1963-12-21,[P0002],,,,,
[I0020],Smith,Carl Emil,,,,,male,1899-12-20,[P0003],,,,,1959-01-28,[P0005],,,,,
[I0029],Smith,Craig Peter,,,,,male,after 1966,[P0002],,,,,,,,,,,
[I0037],Smith,Edwin Michael,,,,,male,1961-05-24,[P0017],"Birth, Death and Marriage Records",,,,,,,,,,
[I0009],Smith,Emil,,,,,male,1860-09-27,[P0012],,,,,,,,,,,
[I0019],Smith,Eric Lloyd,,,,Dr.,male,1963-08-28,[P0002],,,,,,,,,,,
[I0015],Smith,Gus,,,,,male,1897-09-11,[P0003],,,,,1963-10-21,[P0002],,,,,
[I0024],Smith,Gustaf,,Sr.,,,male,1862-11-28,[P0009],,,,,before 1930-07-23,[P0001],,,,,
[I0011],Smith,Hanna,,,,,female,1821-01-29,[P0004],,,,,,,,,,,
[I0010],Smith,Hans Peter,,,,,male,1904-04-17,[P0003],Birth Records,,,,1977-01-29,[P0002],,1977-02-05,[P0002],findagrave.com,
[I0021],Smith,Hjalmar,,,,,male,1893-01-31,[P0003],,,,,1894-09-25,[P0003],,,,,
[I0008],Smith,Hjalmar,,,,,male,1895-04-07,[P0003],,1895-06-03,[P0021],,1975-06-26,[P0005],,,,,
[I0007],Smith,Ingar,,,,,female,after 1823,[P0004],,,,,,,,,,,
[I0027],Smith,Ingeman,,,,,male,about 1770,[P0008],,,,,,,,,,,
[I0004],Smith,Ingeman,,,,,male,1826-01-29,[P0004],,,,,,,,,,,
[I0018],Smith,John Hjalmar,,,,,male,1932-01-30,[P0002],,,,,,,,,,,
[I0001],Smith,Keith Lloyd,,,,,male,1966-08-11,[P0002],,,,,,,,,,,
[I0026],Smith,Kirsti Marie,,,,,female,1886-12-15,[P0003],,,,,1966-07-18,[P0002],,,,,
[I0035],Smith,Lars Peter,,,,,male,1991-09-16,[P0016],,,,,,,,,,,
[I0033],Smith,Lloyd,,,,,male,1935-03-13,[P0002],,,,,,,,,,,
[I0003],Smith,Magnes,,,,,male,1858-10-06,[P0012],,,,,1910-02-20,[P0003],,,,,
[I0040],Smith,Marjorie Alice,,,,,female,1960-02-05,[P0017],,,,,,,,,,,
[I0014],Smith,Marjorie Lee,,,,,female,1934-11-04,[P0005],,,,,,,,,,,
[I0022],Smith,Martin,,,,,male,1830-11-19,[P0004],,1830-11-23,[P0004],,between 1899 and 1905,[P0008],,,,,
[I0039],Smith,Martin,,,,,male,between 1794 and 1796,[P0020],,,,,,[P0008],,,,,
[I0005],Smith,Mason Michael,,,,,male,1996-06-26,[P0006],,,,,,,,,,,
[I0028],Streiffert,Anna,,,,,female,1860-09-23,[P0011],,,,,1927-02-02,[P0003],,,,,
[I0006],Willard,Edwin,,,,,male,about 1886,,,,,,,,,,,,
[I0043],リチミシキスイミ,ピーター,,,,,male,,,,,,,,,,,,,
Marriage,Husband,Wife,Date,Place,Source,Note
[F0000],[I0039],[I0036],about 1816,"Gladsax, Kristianstad Län, Sweden",,
[F0001],[I0027],[I0025],about 1790,Sweden,,
[F0000],[I0039],[I0036],about 1816,[P0004],,
[F0001],[I0027],[I0025],about 1790,[P0008],,
[F0002],[I0022],[I0038],about 1856,,,
[F0003],[I0024],[I0000],27 Nov 1885,"Rønne, Bornholm, Denmark",,
[F0003],[I0024],[I0000],1885-11-27,[P0003],,
[F0004],[I0006],[I0026],about 1910,,,
[F0005],[I0012],[I0023],30 Nov 1912,"Rønne, Bornholm, Denmark",,
[F0006],[I0008],[I0031],31 Oct 1927,"Reno, Washoe Co., NV",,
[F0005],[I0012],[I0023],1912-11-30,[P0003],,
[F0006],[I0008],[I0031],1927-10-31,[P0005],,
[F0007],[I0015],[I0013],about 1920,,,
[F0008],[I0033],[I0041],10 Aug 1958,"San Francisco, San Francisco Co., CA",,
[F0008],[I0033],[I0041],1958-08-10,[P0002],,
[F0009],[I0010],[I0017],,,,
[F0010],[I0019],[I0032],12 Jul 1986,"Woodland, Yolo Co., CA",,
[F0011],[I0003],[I0028],24 Aug 1884,"Rønne, Bornholm, Denmark",,
[F0012],[I0018],[I0034],4 Jun 1954,"Sparks, Washoe Co., NV",Marriage Certificae,
[F0013],[I0037],[I0030],27 May 1995,"San Ramon, Conta Costa Co., CA",,
[F0010],[I0019],[I0032],1986-07-12,[P0022],,
[F0011],[I0003],[I0028],1884-08-24,[P0003],,
[F0012],[I0018],[I0034],1954-06-04,[P0001],Marriage Certificae,
[F0013],[I0037],[I0030],1995-05-27,[P0023],,
[F0014],[I0010],[I0016],,,,
Family,Child

Can't render this file because it has a wrong number of fields in line 32.

7
debian/changelog vendored
View File

@ -1,3 +1,10 @@
gramps (5.1.1-1) unstable; urgency=medium
* New release
* Add python3-fontconfig to recommends
-- Ross Gammon <rossgammon@debian.org> Tue, 17 Sep 2019 15:21:43 +0200
gramps (5.1.0-1) unstable; urgency=medium
* New release

3
debian/control vendored
View File

@ -42,7 +42,8 @@ Recommends:
gir1.2-gexiv2-0.10,
gir1.2-osmgpsmap-1.0,
python3-icu,
gir1.2-geocodeglib-1.0
gir1.2-geocodeglib-1.0,
python3-fontconfig
Suggests:
fonts-freefont-ttf,
gir1.2-goocanvas-2.0,

View File

@ -280,7 +280,7 @@ class CLIManager:
# Attempt to figure out the database title
path = os.path.join(filename, "name.txt")
try:
with open(path) as ifile:
with open(path, encoding='utf8') as ifile:
title = ifile.readline().strip()
except:
title = filename

View File

@ -88,9 +88,9 @@ def _convert_str_to_match_type(str_val, type_val):
return str(str_val)
elif ret_type == int:
if str_val.isdigit():
try:
return int(str_val)
else:
except ValueError:
print("'%s' is not an integer number" % str_val)
return 0

View File

@ -757,7 +757,7 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
if self._directory:
filepath = os.path.join(self._directory, "name.txt")
try:
with open(filepath, "r") as name_file:
with open(filepath, "r", encoding='utf8') as name_file:
name = name_file.readline().strip()
except (OSError, IOError) as msg:
LOG.error(str(msg))

View File

@ -212,7 +212,7 @@ def show_settings():
Gtk.get_minor_version(), Gtk.get_micro_version())
except: # any failure to 'get' the version
gtkver_str = 'unknown version'
except ImportError:
except (ImportError, ValueError):
gtkver_str = 'not found'
# no DISPLAY is a RuntimeError in an older pygtk (e.g. 2.17 in Fedora 14)
except RuntimeError:

View File

@ -1256,14 +1256,15 @@ class GrampsPreferences(ConfigureDialog):
_("Years, Months, Days")]
list(map(obox.append_text, age_precision))
# Combo_box active index is from 0 to 2, we need values from 1 to 3
constant = 'preferences.age-display-precision'
active = config.get(constant) - 1
active = config.get('preferences.age-display-precision') - 1
if active >= 0 and active <= 2:
obox.set_active(active)
else:
obox.set_active(0)
obox.connect('changed',
lambda obj: config.set(constant, obj.get_active() + 1))
obox.connect(
'changed',
lambda obj: config.set('preferences.age-display-precision',
obj.get_active() + 1))
lwidget = BasicLabel(_("%s: ")
% _('Age display precision (requires restart)'))
grid.attach(lwidget, 0, row, 1, 1)
@ -1300,10 +1301,10 @@ class GrampsPreferences(ConfigureDialog):
obox = Gtk.ComboBoxText()
formats = FamilyRelType().get_standard_names()
list(map(obox.append_text, formats))
constant = 'preferences.family-relation-type'
obox.set_active(config.get(constant))
obox.set_active(config.get('preferences.family-relation-type'))
obox.connect('changed',
lambda obj: config.set(constant, obj.get_active()))
lambda obj: config.set('preferences.family-relation-type',
obj.get_active()))
lwidget = BasicLabel(_("%s: ") % _('Default family relationship'))
grid.attach(lwidget, 0, row, 1, 1)
grid.attach(obox, 1, row, 2, 1)
@ -1489,6 +1490,26 @@ class GrampsPreferences(ConfigureDialog):
align=Gtk.Align.CENTER, bold=True)
row = 1
self.add_pos_int_entry(
grid, _('Markup for invalid date format'),
row, 'preferences.invalid-date-format',
self.update_markup_entry,
helptext=_(
'Convenience markups are:\n'
'<b>&lt;b&gt;Bold&lt;/b&gt;</b>\n'
'<big>&lt;big&gt;'
'Makes font relatively larger&lt;/big&gt;</big>\n'
'<i>&lt;i&gt;Italic&lt;/i&gt;</i>\n'
'<s>&lt;s&gt;Strikethrough&lt;/s&gt;</s>\n'
'<sub>&lt;sub&gt;Subscript&lt;/sub&gt;</sub>\n'
'<sup>&lt;sup&gt;Superscript&lt;/sup&gt;</sup>\n'
'<small>&lt;small&gt;'
'Makes font relatively smaller&lt;/small&gt;</small>\n'
'<tt>&lt;tt&gt;Monospace font&lt;/tt&gt;</tt>\n'
'<u>&lt;u&gt;Underline&lt;/u&gt;</u>\n\n'
'For example: &lt;u&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/u&gt;\n'
'will display <u><b>Underlined bold date</b></u>.\n'))
row += 1
self.add_spinner(
grid, _('Date about range'),
row, 'behavior.date-about-range', (1, 9999))
@ -1516,26 +1537,6 @@ class GrampsPreferences(ConfigureDialog):
self.add_spinner(
grid, _('Average years between generations'),
row, 'behavior.avg-generation-gap', (10, 30))
row += 1
self.add_pos_int_entry(
grid, _('Markup for invalid date format'),
row, 'preferences.invalid-date-format',
self.update_markup_entry,
helptext=_(
'Convenience markups are:\n'
'<b>&lt;b&gt;Bold&lt;/b&gt;</b>\n'
'<big>&lt;big&gt;'
'Makes font relatively larger&lt;/big&gt;</big>\n'
'<i>&lt;i&gt;Italic&lt;/i&gt;</i>\n'
'<s>&lt;s&gt;Strikethrough&lt;/s&gt;</s>\n'
'<sub>&lt;sub&gt;Subscript&lt;/sub&gt;</sub>\n'
'<sup>&lt;sup&gt;Superscript&lt;/sup&gt;</sup>\n'
'<small>&lt;small&gt;'
'Makes font relatively smaller&lt;/small&gt;</small>\n'
'<tt>&lt;tt&gt;Monospace font&lt;/tt&gt;</tt>\n'
'<u>&lt;u&gt;Underline&lt;/u&gt;</u>\n\n'
'For example: &lt;u&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/u&gt;\n'
'will display <u><b>Underlined bold date</b></u>.\n'))
return _('Dates'), grid
@ -2089,9 +2090,9 @@ class GrampsPreferences(ConfigureDialog):
self.all_avail_fonts, callback=self.utf8_update_font,
valueactive=True, setactive=active_val)
if len(available_fonts) == 1:
single_font = self.all_avail_fonts[choosefont.get_active()][1]
single_font = self.all_avail_fonts[choosefont.get_active()][0]
config.set('utf8.selected-font',
self.all_avail_fonts[single_font])
self.all_avail_fonts[single_font][1])
self.utf8_show_example()
symbols = Symbols()
all_sbls = symbols.get_death_symbols()

View File

@ -158,24 +158,30 @@ class EditPlace(EditPrimary):
self.obj.set_code, self.obj.get_code,
self.db.readonly)
entry = self.top.get_object("lon_entry")
entry.set_ltr_mode()
self.longitude = MonitoredEntry(
self.top.get_object("lon_entry"),
entry,
self.obj.set_longitude, self.obj.get_longitude,
self.db.readonly)
self.longitude.connect("validate", self._validate_coordinate, "lon")
#force validation now with initial entry
self.top.get_object("lon_entry").validate(force=True)
entry.validate(force=True)
entry = self.top.get_object("lat_entry")
entry.set_ltr_mode()
self.latitude = MonitoredEntry(
self.top.get_object("lat_entry"),
entry,
self.obj.set_latitude, self.obj.get_latitude,
self.db.readonly)
self.latitude.connect("validate", self._validate_coordinate, "lat")
#force validation now with initial entry
self.top.get_object("lat_entry").validate(force=True)
entry.validate(force=True)
entry = self.top.get_object("latlon_entry")
entry.set_ltr_mode()
self.latlon = MonitoredEntry(
self.top.get_object("latlon_entry"),
entry,
self.set_latlongitude, self.get_latlongitude,
self.db.readonly)

View File

@ -151,24 +151,30 @@ class EditPlaceRef(EditReference):
self.source.set_code, self.source.get_code,
self.db.readonly)
entry = self.top.get_object("lon_entry")
entry.set_ltr_mode()
self.longitude = MonitoredEntry(
self.top.get_object("lon_entry"),
entry,
self.source.set_longitude, self.source.get_longitude,
self.db.readonly)
self.longitude.connect("validate", self._validate_coordinate, "lon")
#force validation now with initial entry
self.top.get_object("lon_entry").validate(force=True)
entry.validate(force=True)
entry = self.top.get_object("lat_entry")
entry.set_ltr_mode()
self.latitude = MonitoredEntry(
self.top.get_object("lat_entry"),
entry,
self.source.set_latitude, self.source.get_latitude,
self.db.readonly)
self.latitude.connect("validate", self._validate_coordinate, "lat")
#force validation now with initial entry
self.top.get_object("lat_entry").validate(force=True)
entry.validate(force=True)
entry = self.top.get_object("latlon_entry")
entry.set_ltr_mode()
self.latlon = MonitoredEntry(
self.top.get_object("latlon_entry"),
entry,
self.set_latlongitude, self.get_latlongitude,
self.db.readonly)

View File

@ -311,7 +311,10 @@ class PlaceEntry(ObjEntry):
def get_label(self, place):
place_title = place_displayer.display(self.db, place)
return "%s [%s]" % (place_title, place.gramps_id)
# When part of the place title contains RTL text, the gramps_id gets
# messed up; so use Unicode FSI/PDI and LRM chars to isolate it.
# see bug 10124 and PR924
return "%s \u2068[%s]\u200e\u2069" % (place_title, place.gramps_id)
def call_editor(self, obj=None):
if obj is None:
@ -356,7 +359,7 @@ class SourceEntry(ObjEntry):
return self.db.get_source_from_handle(handle)
def get_label(self, source):
return "%s [%s]" % (source.get_title(), source.gramps_id)
return "%s \u2068[%s]\u200e\u2069" % (source.get_title(), source.gramps_id)
def call_editor(self, obj=None):
if obj is None:
@ -402,7 +405,8 @@ class MediaEntry(ObjEntry):
return self.db.get_media_from_handle(handle)
def get_label(self, object):
return "%s [%s]" % (object.get_description(), object.gramps_id)
return "%s \u2068[%s]\u200e\u2069" % (object.get_description(),
object.gramps_id)
def call_editor(self, obj=None):
if obj is None:
@ -462,7 +466,7 @@ class NoteEntry(ObjEntry):
txt = " ".join(note.get().split())
if len(txt) > 35:
txt = txt[:35] + "..."
return "%s [%s]" % (txt, note.gramps_id)
return "%s \u2068[%s]\u200e\u2069" % (txt, note.gramps_id)
def call_editor(self, obj=None):
if obj is None:

View File

@ -766,7 +766,7 @@ class ToolManagedWindowBase(ManagedWindow):
self.notebook = Gtk.Notebook()
self.notebook.set_border_width(6)
self.window.get_content_area().add(self.notebook)
self.window.get_content_area().pack_start(self.notebook, True, True, 0)
self.results_text = Gtk.TextView()
self.results_text.connect('button-press-event',

View File

@ -551,16 +551,17 @@ def color_graph_box(alive=False, gender=Person.MALE):
def hex_to_rgb_float(value):
"""
Convert a hexademical value #FF00FF to rgb. Returns tuple of float between
0 and 1
Convert a 6 or 12 digit hexademical value to rgb. Returns tuple of floats
between 0 and 1.
"""
value = value.lstrip('#')
lenv = len(value)
return tuple(int(value[i:i+lenv//3], 16)/256.0 for i in range(0, lenv, lenv//3))
return tuple(int(value[i:i+lenv//3], 16)/16.0**(lenv//3)
for i in range(0, lenv, lenv//3))
def hex_to_rgb(value):
"""
Convert a hexadecimal value #FF00FF to rgb. Returns tuple of integers
Convert a 6 or 12 digit hexadecimal value to rgb. Returns tuple of integers.
"""
value = value.lstrip('#')
lenv = len(value)

View File

@ -435,19 +435,15 @@ class NavigationView(PageView):
hobj = self.get_history()
menu_len = min(len(items) - 1, MRU_SIZE)
for index in range(0, menu_len):
name, obj = navigation_label(self.dbstate.db, nav_type,
items[index])
menus += menuitem % (nav_type, index, html.escape(name))
self.mru_ui = [MRU_TOP + menus + MRU_BTM]
mitems = items[-MRU_SIZE - 1:-1] # Ignore current handle
mitems.reverse()
data = []
for index, handle in enumerate(mitems):
data.append(('%s%02d'%(nav_type, index),
make_callback(hobj.push, handle),
"%s%d" % (mod_key(), index)))
for index in range(menu_len - 1, -1, -1):
name, _obj = navigation_label(self.dbstate.db, nav_type,
items[index])
menus += menuitem % (nav_type, index, html.escape(name))
data.append(('%s%02d' % (nav_type, index),
make_callback(hobj.push, items[index]),
"%s%d" % (mod_key(), menu_len - 1 - index)))
self.mru_ui = [MRU_TOP + menus + MRU_BTM]
self.mru_action = ActionGroup(name=self.title + '/MRU')
self.mru_action.add_actions(data)

View File

@ -143,7 +143,7 @@ class PlaceBaseModel:
value = conv_lat_lon('0', data[3], format='DEG')[1]
if not value:
return _("Error in format")
return value
return ("\u202d" + value + "\u202e") if glocale.rtl_locale else value
def column_latitude(self, data):
if not data[4]:
@ -151,7 +151,7 @@ class PlaceBaseModel:
value = conv_lat_lon(data[4], '0', format='DEG')[0]
if not value:
return _("Error in format")
return value
return ("\u202d" + value + "\u202e") if glocale.rtl_locale else value
def sort_longitude(self, data):
if not data[3]:

View File

@ -64,8 +64,6 @@ from gramps.gen.errors import ValidationError
_RETURN = Gdk.keyval_from_name("Return")
_KP_ENTER = Gdk.keyval_from_name("KP_Enter")
# table for skipping illegal control chars
INVISIBLE = dict.fromkeys(list(range(32)))
#-------------------------------------------------------------------------
#
@ -141,14 +139,10 @@ class MonitoredEntry:
self.obj.connect(signal, callback, *data)
def _on_quit(self, obj, event):
text = obj.get_text().translate(INVISIBLE).strip()
self.set_val(text)
obj.set_text(text)
self.set_val(obj.get_text().strip())
def _on_change(self, obj):
new_text = obj.get_text().translate(INVISIBLE)
self.set_val(new_text)
obj.set_text(new_text)
self.set_val(obj.get_text())
if self.changed:
self.changed(obj)

View File

@ -46,6 +46,11 @@ from gi.repository import Gtk
#
#-------------------------------------------------------------------------
from .undoablebuffer import Stack
from gramps.gen.const import GRAMPS_LOCALE as glocale
# table for skipping illegal control chars
INVISIBLE = dict.fromkeys(list(range(32)) + [0x202d, 0x202e])
class UndoableInsertEntry:
"""something that has been inserted into our Gtk.editable"""
@ -84,6 +89,10 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
Additional features:
- Undo and Redo on CTRL-Z/CTRL-SHIFT-Z
- ltr_mode (forces the field to always be left to right, useful for GPS
coordinates and similar numbers that might contain RTL characters.
See set_ltr_mode.
"""
__gtype_name__ = 'UndoableEntry'
@ -94,12 +103,12 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
undo_stack_size = 50
def __init__(self):
Gtk.Entry.__init__(self)
self.undo_stack = Stack(self.undo_stack_size)
self.redo_stack = []
self.not_undoable_action = False
self.undo_in_progress = False
self.ltr_mode = False
Gtk.Entry.__init__(self)
self.connect('delete-text', self._on_delete_text)
self.connect('key-press-event', self._on_key_press_event)
@ -156,10 +165,17 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
return False
return True
text = text.translate(INVISIBLE)
if self.ltr_mode:
if position == 0:
position = 1
elif position >= self.get_text_length():
position -= 1
if not self.undo_in_progress:
self.__empty_redo_stack()
while not self.not_undoable_action:
undo_action = self.insertclass(text, length, self.get_position())
undo_action = self.insertclass(text, length, position)
try:
prev_insert = self.undo_stack.pop()
except IndexError:
@ -180,6 +196,7 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
self.get_buffer().insert_text(position, text, len(text))
return position + len(text)
def _on_delete_text(self, editable, start, end):
def can_be_merged(prev, cur):
"""
@ -206,32 +223,49 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
return False
return True
if not self.undo_in_progress:
self.__empty_redo_stack()
if self.not_undoable_action:
return
undo_action = self.deleteclass(editable, start, end)
try:
prev_delete = self.undo_stack.pop()
except IndexError:
self.undo_stack.append(undo_action)
return
if not isinstance(prev_delete, self.deleteclass):
self.undo_stack.append(prev_delete)
self.undo_stack.append(undo_action)
return
if can_be_merged(prev_delete, undo_action):
if prev_delete.start == undo_action.start: # delete key used
prev_delete.text += undo_action.text
prev_delete.end += (undo_action.end - undo_action.start)
else: # Backspace used
prev_delete.text = "%s%s" % (undo_action.text,
prev_delete.text)
prev_delete.start = undo_action.start
self.undo_stack.append(prev_delete)
else:
self.undo_stack.append(prev_delete)
self.undo_stack.append(undo_action)
if self.ltr_mode: # limit deletes to area between LRO/PDF
if start == 0:
start = 1
elif start > self.get_text_length() - 1:
start -= 1
if end == 0:
end = 1
elif end > self.get_text_length() - 1:
end -= 1
elif end < 0:
end = self.get_text_length() - 1
while True:
if not self.undo_in_progress:
self.__empty_redo_stack()
if self.not_undoable_action:
break
undo_action = self.deleteclass(self, start, end)
try:
prev_delete = self.undo_stack.pop()
except IndexError:
self.undo_stack.append(undo_action)
break
if not isinstance(prev_delete, self.deleteclass):
self.undo_stack.append(prev_delete)
self.undo_stack.append(undo_action)
break
if can_be_merged(prev_delete, undo_action):
if prev_delete.start == undo_action.start: # delete key used
prev_delete.text += undo_action.text
prev_delete.end += (undo_action.end - undo_action.start)
else: # Backspace used
prev_delete.text = "%s%s" % (undo_action.text,
prev_delete.text)
prev_delete.start = undo_action.start
self.undo_stack.append(prev_delete)
else:
self.undo_stack.append(prev_delete)
self.undo_stack.append(undo_action)
break
self.get_buffer().delete_text(start, end - start)
self.stop_emission_by_name('delete-text')
return True
def begin_not_undoable_action(self):
"""don't record the next actions
@ -323,3 +357,40 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
def _handle_redo(self, redo_action):
raise NotImplementedError
def set_ltr_mode(self):
""" sets up the Entry to always be in LTR left to right even if some
characters are RTL.
This works by inserting the LRO/PDF Unicode Explicit Directional
Override characters around the entry text. These characters are then
protected agains insert/delete operations.
This call must be made before other text is inserted to the Entry.
Note: we only enable this during rtl_local languages because it has a
minor consequence; if cutting a field from this Entry with this mode
enabled, the LRO/PDF characters may end up in the clipboard. If pasted
back into another UndoableEntry, this is ignored, but if pasted in
another app it may be noticable.
"""
if glocale.rtl_locale:
self.get_buffer().set_text("\u202d\u202e", -1)
self.ltr_mode = True
def do_set_position(self, position):
""" In ltr_mode, this ensures that the cursor cannot be put outside
the LRO/PDF characters on the ends of the buffer. """
if position < 0:
position = self.get_text_length()
if self.ltr_mode:
if position == 0:
position = 1
elif position == self.get_text_length():
position -= 1
Gtk.Editable.select_region(self, position, position)
def get_text(self):
""" Used to remove the LRO/PDF characters when in ltr_mode.
"""
text = Gtk.Entry.get_text(self)
return text[1:-1] if self.ltr_mode else text

View File

@ -1541,7 +1541,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
Insert a mark at this point in the document.
"""
if mark:
key = escape(mark.key, ESC_MAP)
key = escape(mark.key)
key = key.replace('"', '&quot;')
if mark.type == INDEX_TYPE_ALP:
self.cntnt.write(

View File

@ -225,7 +225,10 @@ class TitleDPY(DescendantTitleBase):
center = self.database.get_person_from_gramps_id(person_id)
family2_h = center.get_main_parents_family_handle()
family2 = self.database.get_family_from_handle(family2_h)
if family2_h:
family2 = self.database.get_family_from_handle(family2_h)
else:
family2 = None
person_list = None
if family2:
@ -270,8 +273,11 @@ class TitleDFY(DescendantTitleBase):
parent_list = None
family_h = person.get_main_parents_family_handle()
family = self.database.get_family_from_handle(family_h)
if family: #family = fathers parents
if family_h:
family = self.database.get_family_from_handle(family_h)
else:
family = None
if family: # family = fathers parents
father_h = family.get_father_handle()
mother_h = family.get_mother_handle()
parent_list = [self.database.get_person_from_handle(handle)

View File

@ -82,7 +82,8 @@ class FtreeWriter:
self.option_box.parse_options()
self.db = option_box.get_filtered_database(self.db)
self.plist = [x for x in self.db.iter_person_handles()]
self.plist = self.db.get_person_handles()
self.plist.sort()
# the following are used to update the progress meter
self.total = 2 * len(self.plist)
self.count = 0

View File

@ -596,7 +596,7 @@ class GedcomWriter(UpdateCallback):
if val.strip():
self._writeln(2, 'TYPE', val)
else:
self._writeln(2, 'TYPE', str(event.get_type()))
self._writeln(2, 'TYPE', event.get_type().xml_str())
self._dump_event_stats(event, event_ref)
if etype == EventType.ADOPT and not adop_written:
adop_written = True
@ -656,7 +656,7 @@ class GedcomWriter(UpdateCallback):
attr_type = int(attr.get_type())
name = libgedcom.PERSONALCONSTANTATTRIBUTES.get(attr_type)
key = str(attr.get_type())
key = attr.get_type().xml_str()
value = attr.get_value().strip().replace('\r', ' ')
if key in ("AFN", "RFN", "REFN", "_UID", "_FSFTID"):
@ -735,14 +735,14 @@ class GedcomWriter(UpdateCallback):
child.mrel == ChildRefType.FOSTER:
self._writeln(2, 'PEDI foster')
elif child.frel == child.mrel:
self._writeln(2, 'PEDI %s' % str(child.frel))
self._writeln(2, 'PEDI %s' % child.frel.xml_str())
else:
self._writeln(2, '_FREL %s' %
PEDIGREE_TYPES.get(child.frel.value,
str(child.frel)))
self._writeln(2, '_MREL %s' %
PEDIGREE_TYPES.get(child.mrel.value,
str(child.mrel)))
self._writeln(
2, '_FREL %s' % PEDIGREE_TYPES.get(
child.frel.value, child.frel.xml_str()))
self._writeln(
2, '_MREL %s' % PEDIGREE_TYPES.get(
child.mrel.value, child.mrel.xml_str()))
def _parent_families(self, person):
"""
@ -910,9 +910,9 @@ class GedcomWriter(UpdateCallback):
self._writeln(1, 'EVEN', descr)
else:
self._writeln(1, 'EVEN')
the_type = str(event.get_type())
the_type = event.get_type()
if the_type:
self._writeln(2, 'TYPE', the_type)
self._writeln(2, 'TYPE', the_type.xml_str())
def _family_event_attrs(self, attr_list, level):
"""
@ -946,7 +946,7 @@ class GedcomWriter(UpdateCallback):
attr_type = int(attr.get_type())
name = libgedcom.FAMILYCONSTANTATTRIBUTES.get(attr_type)
key = str(attr.get_type())
key = attr.get_type().xml_str()
value = attr.get_value().replace('\r', ' ')
if key in ("AFN", "RFN", "REFN", "_UID"):
@ -1097,7 +1097,8 @@ class GedcomWriter(UpdateCallback):
if reporef.get_call_number():
self._writeln(level + 1, 'CALN', reporef.get_call_number())
if reporef.get_media_type():
self._writeln(level + 2, 'MEDI', str(reporef.get_media_type()))
self._writeln(level + 2, 'MEDI',
reporef.get_media_type().xml_str())
def _person_event_ref(self, key, event_ref):
"""

View File

@ -91,7 +91,8 @@ class GeneWebWriter:
self.dirname = os.path.dirname (self.filename)
try:
with open(self.filename, "wb") as self.g:
self.flist = [x for x in self.db.iter_family_handles()]
self.flist = self.db.get_family_handles()
self.flist.sort()
if len(self.flist) < 1:
self.user.notify_error(_("No families matched by selected filter"))
return False

View File

@ -30,7 +30,7 @@
#-------------------------------------------------------------------------
import os
import sys
from time import localtime
import time
#------------------------------------------------------------------------
#
@ -51,10 +51,10 @@ _ = glocale.translation.gettext
from gramps.gui.plug.export import WriterOptionBox
from gramps.gen.utils.db import family_name
from gramps.gen.lib import Date, EventType
from gramps.gui.glade import Glade
from gramps.gen.display.name import displayer as name_displayer
from gramps.gen.display.place import displayer as _pd
class CalendarWriter:
def __init__(self, database, filename, user, option_box=None):
self.db = database
@ -95,24 +95,27 @@ class CalendarWriter:
def export_data(self, filename):
self.dirname = os.path.dirname (filename)
self.dirname = os.path.dirname(filename)
try:
with open(filename,"w") as self.g:
with open(filename, "w", encoding='utf8',
newline='\r\n') as self.g:
self.writeln("BEGIN:VCALENDAR")
self.writeln("PRODID:-//GNU//Gramps//EN")
self.writeln("VERSION:1.0")
self.writeln("VERSION:2.0")
self.total = (len([x for x in self.db.iter_person_handles()]) +
len([x for x in self.db.iter_family_handles()]))
for key in self.db.iter_person_handles():
p_hndls = self.db.get_person_handles()
p_hndls.sort()
f_hndls = self.db.get_family_handles()
f_hndls.sort()
self.total = len(p_hndls) + len(f_hndls)
for key in p_hndls:
self.write_person(key)
self.update()
for key in self.db.iter_family_handles():
for key in f_hndls:
self.write_family(key)
self.update()
self.writeln("")
self.writeln("END:VCALENDAR")
return True
@ -129,16 +132,11 @@ class CalendarWriter:
if family:
for event_ref in family.get_event_ref_list():
event = self.db.get_event_from_handle(event_ref.ref)
if event.get_type() == EventType.MARRIAGE:
m_date = event.get_date_object()
place_handle = event.get_place_handle()
if event and event.get_type() == EventType.MARRIAGE:
# feature requests 2356, 1657: avoid genitive form
text = "%s - %s" % (family_name(family, self.db), _("Marriage"))
if place_handle:
place_title = _pd.display_event(self.db, event)
self.write_vevent( text, m_date, place_title)
else:
self.write_vevent( text, m_date)
text = "%s - %s" % (family_name(family, self.db),
_("Marriage"))
self.write_vevent(text, event)
def write_person(self, person_handle):
person = self.db.get_person_from_handle(person_handle)
@ -147,45 +145,26 @@ class CalendarWriter:
if birth_ref:
birth = self.db.get_event_from_handle(birth_ref.ref)
if birth:
b_date = birth.get_date_object()
place_handle = birth.get_place_handle()
if place_handle:
# feature requests 2356, 1657: avoid genitive form
place_title = _pd.display_event(self.db, birth)
self.write_vevent("%s - %s" %
(name_displayer.display(person), _("Birth")),
b_date, place_title)
else:
# feature requests 2356, 1657: avoid genitive form
self.write_vevent("%s - %s" %
(name_displayer.display(person), _("Birth")),
b_date)
# feature requests 2356, 1657: avoid genitive form
self.write_vevent("%s - %s" %
(name_displayer.display(person),
_("Birth")), birth)
death_ref = person.get_death_ref()
if death_ref:
death = self.db.get_event_from_handle(death_ref.ref)
if death:
d_date = death.get_date_object()
place_handle = death.get_place_handle()
if place_handle:
# feature requests 2356, 1657: avoid genitive form
place_title = _pd.display_event(self.db, death)
self.write_vevent("%s - %s" %
(name_displayer.display(person), _("Death")),
d_date, place_title)
else:
# feature requests 2356, 1657: avoid genitive form
self.write_vevent("%s - %s" %
(name_displayer.display(person), _("Death")),
d_date)
# feature requests 2356, 1657: avoid genitive form
self.write_vevent("%s - %s" %
(name_displayer.display(person),
_("Death")), death)
def format_single_date(self, subdate, thisyear, cal):
retval = ""
(day, month, year, sl) = subdate
if thisyear:
year = localtime().tm_year
year = time.localtime().tm_year
if not cal == Date.CAL_GREGORIAN:
return ""
@ -196,7 +175,6 @@ class CalendarWriter:
retval = "%s%02d%02d" % (year, month, day)
return retval
def format_date(self, date, thisyear=0):
retval = ""
if date.get_modifier() == Date.MOD_TEXTONLY:
@ -220,23 +198,43 @@ class CalendarWriter:
start)
return retval
def write_vevent(self, event_text, date, location=""):
def write_vevent(self, event_text, event):
date = event.get_date_object()
place_handle = event.get_place_handle()
date_string = self.format_date(date, 1)
if date_string is not "":
self.writeln("")
# self.writeln("")
self.writeln("BEGIN:VEVENT")
self.writeln("SUMMARY:%s %s" % (date.get_year(), event_text))
if location:
self.writeln("LOCATION:%s" % location)
time_s = time.gmtime(event.change)
self.writeln("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ" % time_s[0:6])
self.writeln("UID:%s@gramps.com" % event.handle)
self.writeln(fold("SUMMARY:%s %s" % (date.get_year(), event_text)))
if place_handle:
location = _pd.display_event(self.db, event)
if location:
self.writeln("LOCATION:%s" % location)
self.writeln("RRULE:FREQ=YEARLY")
self.writeln(date_string)
self.writeln("END:VEVENT")
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
# -------------------------------------------------------------------------
def fold(txt):
""" Limit line length to 75 octets (per RFC 5545) """
l_len = 0
text = ''
for char in txt:
c_len = len(char.encode('utf8'))
if c_len + l_len > 75:
l_len = 1
text += '\n ' + char
else:
l_len += c_len
text += char
return text
def exportData(database, filename, user, option_box=None):
cw = CalendarWriter(database, filename, user, option_box)
return cw.export_data(filename)

View File

@ -51,13 +51,13 @@ class AgeStatsGramplet(Gramplet):
def build_options(self):
from gramps.gen.plug.menu import NumberOption
self.add_option(NumberOption(_("Max age"),
self.max_age, 1, 150))
self.max_age, 5, 150, 5))
self.add_option(NumberOption(_("Max age of Mother at birth"),
self.max_mother_diff, 1, 150))
self.max_mother_diff, 5, 150, 5))
self.add_option(NumberOption(_("Max age of Father at birth"),
self.max_father_diff, 1, 150))
self.max_father_diff, 5, 150, 5))
self.add_option(NumberOption(_("Chart width"),
self.chart_width, 1, 150))
self.chart_width, 45, 150))
def save_options(self):
self.max_age = int(self.get_option(_("Max age")).get_value())

View File

@ -33,6 +33,7 @@ Family Lines, a Graphviz-based plugin for Gramps.
#
#------------------------------------------------------------------------
from functools import partial
import html
#------------------------------------------------------------------------
#
@ -818,10 +819,10 @@ class FamilyLinesReport(Report):
if bth_event and self._incdates:
date = bth_event.get_date_object()
if self._just_years and date.get_year_valid():
birth_str = self._get_date( # localized year
birth_str = self.get_date( # localized year
Date(date.get_year()))
else:
birth_str = self._get_date(date)
birth_str = self.get_date(date)
# get birth place (one of: hamlet, village, town, city, parish,
# county, province, region, state or country)
@ -834,10 +835,10 @@ class FamilyLinesReport(Report):
if dth_event and self._incdates:
date = dth_event.get_date_object()
if self._just_years and date.get_year_valid():
death_str = self._get_date( # localized year
death_str = self.get_date( # localized year
Date(date.get_year()))
else:
death_str = self._get_date(date)
death_str = self.get_date(date)
# get death place (one of: hamlet, village, town, city, parish,
# county, province, region, state or country)
@ -876,8 +877,7 @@ class FamilyLinesReport(Report):
label += '<TD>'
# at the very least, the label must have the person's name
name = name.replace('"', '&#34;')
label += name.replace('<', '&#60;').replace('>', '&#62;')
label += html.escape(name)
if self.includeid == 1: # same line
label += " (%s)" % p_id
elif self.includeid == 2: # own line
@ -964,10 +964,10 @@ class FamilyLinesReport(Report):
if self._incdates:
date = event.get_date_object()
if self._just_years and date.get_year_valid():
wedding_date = self._get_date( # localized year
wedding_date = self.get_date( # localized year
Date(date.get_year()))
else:
wedding_date = self._get_date(date)
wedding_date = self.get_date(date)
# get the wedding location
if self._incplaces:
wedding_place = self.get_event_place(event)
@ -1090,6 +1090,9 @@ class FamilyLinesReport(Report):
place = self._db.get_place_from_handle(place_handle)
if place:
place_text = _pd.display(self._db, place)
place_text = place_text.replace('<', '&#60;')
place_text = place_text.replace('>', '&#62;')
place_text = html.escape(place_text)
return place_text
def get_date(self, date):
""" return a formatted date """
return html.escape(self._get_date(date))

View File

@ -32,6 +32,7 @@ Generate an hourglass graph using the Graphviz generator.
# python modules
#
#------------------------------------------------------------------------
import html
#------------------------------------------------------------------------
#
@ -251,18 +252,17 @@ class HourGlassReport(Report):
"""
p_id = person.get_gramps_id()
name = self._name_display.display(person)
name = name.replace('"', '&#34;')
name = name.replace('<', '&#60;').replace('>', '&#62;')
name = html.escape(name)
birth_evt = get_birth_or_fallback(self.__db, person)
if birth_evt:
birth = self._get_date(birth_evt.get_date_object())
birth = self.get_date(birth_evt.get_date_object())
else:
birth = ""
death_evt = get_death_or_fallback(self.__db, person)
if death_evt:
death = self._get_date(death_evt.get_date_object())
death = self.get_date(death_evt.get_date_object())
else:
death = ""
@ -295,7 +295,7 @@ class HourGlassReport(Report):
label = ""
marriage = utils.find_marriage(self.__db, family)
if marriage:
label = self._get_date(marriage.get_date_object())
label = self.get_date(marriage.get_date_object())
if self.includeid == 1 and label: # same line
label = "%s (%s)" % (label, family_id)
elif self.includeid == 1 and not label:
@ -343,7 +343,9 @@ class HourGlassReport(Report):
else:
fill = self.colors['unknown']
return(shape, style, color, fill)
def get_date(self, date):
""" return a formatted date """
return html.escape(self._get_date(date))
#------------------------------------------------------------------------
#

View File

@ -40,6 +40,7 @@ Create a relationship graph using Graphviz
#
#------------------------------------------------------------------------
from functools import partial
import html
#------------------------------------------------------------------------
#
@ -616,8 +617,7 @@ class RelGraphReport(Report):
# at the very least, the label must have the person's name
p_name = self._name_display.display(person)
p_name = p_name.replace('"', '&#34;')
label += p_name.replace('<', '&#60;').replace('>', '&#62;')
label += html.escape(p_name)
p_id = person.get_gramps_id()
if self.includeid == 1: # same line
label += " (%s)" % p_id
@ -751,10 +751,10 @@ class RelGraphReport(Report):
event_date = event.get_date_object()
if event_date.get_year_valid():
if self.event_choice in [4, 5]:
return self._get_date( # localized year
return self.get_date( # localized year
Date(event_date.get_year()))
elif self.event_choice in [1, 2, 3, 7]:
return self._get_date(event_date)
return self.get_date(event_date)
return ''
def get_place_string(self, event):
@ -768,8 +768,11 @@ class RelGraphReport(Report):
"""
if event and self.event_choice in [2, 3, 5, 6, 7]:
place = _pd.display_event(self._db, event)
return place.replace('<', '&#60;').replace('>', '&#62;')
return html.escape(place)
return ''
def get_date(self, date):
""" return a formatted date """
return html.escape(self._get_date(date))
#------------------------------------------------------------------------
#

View File

@ -22,6 +22,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import unittest
import os
import difflib
from unittest.mock import patch
from time import localtime, strptime
from gramps.test.test_util import Gramps
from gramps.gen.const import TEMP_DIR, DATA_DIR
@ -33,6 +35,13 @@ TREE_NAME = "Test_exporttest"
TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests"))
def mock_localtime(*args):
"""
Mock up a dummy to replace the varying 'time string results'
"""
return strptime("25 Dec 1999", "%d %b %Y")
def call(*args):
""" Call Gramps to perform the action with out and err captured """
#print("call:", args)
@ -84,6 +93,8 @@ def compare(expect_file, result_file, dfilter=None):
msg += line
if dfilter:
fail += dfilter(line)
else:
fail = True
return msg if fail else ""
@ -184,6 +195,9 @@ class ExportControl(unittest.TestCase):
export dates, file names etc. that don't count as differences.
"""
def setUp(self):
config.set('behavior.date-before-range', 50)
config.set('behavior.date-after-range', 50)
config.set('behavior.date-about-range', 10)
self.tearDown() # removes it if it existed
# out, err = self.call("-C", TREE_NAME,
@ -195,6 +209,17 @@ class ExportControl(unittest.TestCase):
def test_csv(self):
""" Run a csv export test """
set_format(0) # Use ISO date for test
config.set('database.backend', 'bsddb')
src_file = 'exp_sample_csv.gramps'
tst_file = 'exp_sample_csv.csv'
msg = do_it(src_file, tst_file)
if msg:
self.fail(tst_file + ': ' + msg)
def test_csv_sq(self):
""" Run a csv export test """
set_format(0) # Use ISO date for test
config.set('database.backend', 'sqlite')
src_file = 'exp_sample_csv.gramps'
tst_file = 'exp_sample_csv.csv'
msg = do_it(src_file, tst_file)
@ -204,6 +229,17 @@ class ExportControl(unittest.TestCase):
def test_ged(self):
""" Run a Gedcom export test """
config.set('preferences.place-auto', True)
config.set('database.backend', 'bsddb')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample_ged.ged'
msg = do_it(src_file, tst_file, gedfilt)
if msg:
self.fail(tst_file + ': ' + msg)
def test_ged_sq(self):
""" Run a Gedcom export test """
config.set('preferences.place-auto', True)
config.set('database.backend', 'sqlite')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample_ged.ged'
msg = do_it(src_file, tst_file, gedfilt)
@ -213,15 +249,39 @@ class ExportControl(unittest.TestCase):
def test_vcard(self):
""" Run a vcard export test """
config.set('preferences.place-auto', True)
config.set('database.backend', 'bsddb')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample.vcf'
msg = do_it(src_file, tst_file, vcffilt)
if msg:
self.fail(tst_file + ': ' + msg)
def test_vcard_sq(self):
""" Run a vcard export test """
config.set('preferences.place-auto', True)
config.set('database.backend', 'sqlite')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample.vcf'
msg = do_it(src_file, tst_file, vcffilt)
if msg:
self.fail(tst_file + ': ' + msg)
@patch('gramps.plugins.export.exportvcalendar.time.localtime', mock_localtime)
def test_vcs(self):
""" Run a Vcalandar export test """
config.set('preferences.place-auto', True)
config.set('database.backend', 'bsddb')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample.vcs'
msg = do_it(src_file, tst_file)
if msg:
self.fail(tst_file + ': ' + msg)
@patch('gramps.plugins.export.exportvcalendar.time.localtime', mock_localtime)
def test_vcs_sq(self):
""" Run a Vcalandar export test """
config.set('preferences.place-auto', True)
config.set('database.backend', 'sqlite')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample.vcs'
msg = do_it(src_file, tst_file)
@ -231,6 +291,17 @@ class ExportControl(unittest.TestCase):
def test_gw(self):
""" Run a Geneweb export test """
config.set('preferences.place-auto', True)
config.set('database.backend', 'bsddb')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample.gw'
msg = do_it(src_file, tst_file)
if msg:
self.fail(tst_file + ': ' + msg)
def test_gw_sq(self):
""" Run a Geneweb export test """
config.set('preferences.place-auto', True)
config.set('database.backend', 'sqlite')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample.gw'
msg = do_it(src_file, tst_file)
@ -241,6 +312,18 @@ class ExportControl(unittest.TestCase):
""" Run a Web Family Tree export test """
set_format(0) # Use ISO date for test
config.set('preferences.place-auto', True)
config.set('database.backend', 'bsddb')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample.wft'
msg = do_it(src_file, tst_file)
if msg:
self.fail(tst_file + ': ' + msg)
def test_wft_sq(self):
""" Run a Web Family Tree export test """
set_format(0) # Use ISO date for test
config.set('preferences.place-auto', True)
config.set('database.backend', 'sqlite')
src_file = 'exp_sample.gramps'
tst_file = 'exp_sample.wft'
msg = do_it(src_file, tst_file)

View File

@ -66,6 +66,9 @@ WIKI_HELP_SEC = _('manual|Reorder_Gramps_ID')
PREFIXES = {'person': 'i', 'family': 'f', 'event': 'e', 'place': 'p',
'source': 's', 'citation': 'c', 'repository': 'r',
'media': 'o', 'note': 'n'}
DB_INDXES = {'person': 'p', 'family': 'f', 'event': 'e', 'place': 'l',
'source': 's', 'citation': 'c', 'repository': 'r',
'media': 'o', 'note': 'n'}
#-------------------------------------------------------------------------
#
# Actual tool
@ -244,7 +247,7 @@ class ReorderIds(tool.BatchTool, ManagedWindow, UpdateCallback):
self.prim_methods, self.obj_methods = {}, {}
for prim_obj, prim_objs in self.xobjects:
iter_handles = "iter_%s_handles" % prim_obj
get_handles = "get_%s_handles" % prim_obj
get_number_obj = "get_number_of_%s" % prim_objs
prefix_fmt = "%s_prefix" % prim_obj
get_from_id = "get_%s_from_gramps_id" % prim_obj
@ -255,7 +258,7 @@ class ReorderIds(tool.BatchTool, ManagedWindow, UpdateCallback):
self.prim_methods[prim_obj] = (getattr(self.db, prefix_fmt),
getattr(self.db, get_number_obj)(),
getattr(self.db, next_from_id)())
self.obj_methods[prim_obj] = (getattr(self.db, iter_handles),
self.obj_methods[prim_obj] = (getattr(self.db, get_handles),
getattr(self.db, commit),
getattr(self.db, get_from_id),
getattr(self.db, get_from_handle),
@ -548,6 +551,9 @@ class ReorderIds(tool.BatchTool, ManagedWindow, UpdateCallback):
self.progress.set_pass(
_('Reorder %s IDs ...') % _(prim_objs.title()),
self.obj_values[prim_obj].quant_id)
# reset the db next_id index to zero so we restart new IDs
# at lowest possible position
setattr(self.db, DB_INDXES[prim_obj] + 'map_index', 0)
# Process reordering
self._reorder(prim_obj)
@ -572,7 +578,7 @@ class ReorderIds(tool.BatchTool, ManagedWindow, UpdateCallback):
dup_ids = [] # list of duplicate identifiers
new_ids = {} # list of new identifiers
iter_handles, commit, get_from_id, get_from_handle, next_from_id = \
get_handles, commit, get_from_id, get_from_handle, next_from_id = \
self.obj_methods[prim_obj]
prefix_fmt = self.obj_values[prim_obj].get_fmt()
@ -585,8 +591,12 @@ class ReorderIds(tool.BatchTool, ManagedWindow, UpdateCallback):
change = self.obj_values[prim_obj].get_change()
index_max = int("9" * self.obj_values[prim_obj].width_fmt)
do_same = False
# Process in handle order, which is in order handles were created.
# This makes renumberd IDs more consistant.
handles = get_handles()
handles.sort()
for handle in iter_handles():
for handle in handles:
# Update progress
if self.uistate:
self.progress.step()

View File

@ -196,10 +196,10 @@ class PersonBoxWidgetCairo(_PersonWidgetBase):
if tags and person:
for tag_handle in person.get_tag_list():
# For the complete tag, don't modify the default color
# which is black (#000000000000)
# which is black
tag = dbstate.db.get_tag_from_handle(tag_handle)
if tag.get_color() != "#000000000000": # only if the color
self.bgcolor = tag.get_color() # is not black
if tag.get_color() not in ("#000000", "#000000000000"):
self.bgcolor = tag.get_color()
self.bgcolor = hex_to_rgb_float(self.bgcolor)
self.bordercolor = hex_to_rgb_float(self.bordercolor)
@ -791,6 +791,7 @@ class PedigreeView(NavigationView):
self._add_db_signal('family-add', self.person_rebuild)
self._add_db_signal('family-delete', self.person_rebuild)
self._add_db_signal('family-rebuild', self.person_rebuild)
self._add_db_signal('event-update', self.person_rebuild)
def change_db(self, db):
"""

View File

@ -60,7 +60,7 @@ import logging
from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.lib import (FamilyRelType, NoteType, NameType, Person,
UrlType, Name, PlaceType, EventRoleType,
Family, Citation, Place)
Family, Citation, Place, Date)
from gramps.gen.lib.date import Today
from gramps.gen.const import PROGRAM_NAME, URL_HOMEPAGE
from gramps.version import VERSION
@ -2916,7 +2916,11 @@ class BasePage: # pylint: disable=C1001
if self.reference_sort:
role = obj[2] # name
elif len(obj[2].split('-')) > 1:
role = obj[2] # date in ISO format
dummy_cal, role = obj[2].split(':') # date in ISO format
# dummy_cal is the original calendar. remove it.
if len(role.split(' ')) == 2:
# for sort, remove the modifier before, after...
(dummy_modifier, role) = role.split(' ')
else:
role = "3"
return role
@ -2931,15 +2935,34 @@ class BasePage: # pylint: disable=C1001
if role != "":
if self.reference_sort:
role = ""
elif len(role.split('-')) > 1:
elif role[1:2] == ':':
# cal is the original calendar
cal, role = role.split(':')
# conver ISO date to Date for translation.
# all modifiers are in english, so convert them
# to the local language
if len(role.split(' - ')) > 1:
(date1, date2) = role.split(' - ')
role = self._("between") + " " + date1 + " "
role += self._("and") + " " + date2
elif len(role.split(' ')) == 2:
(pref, date) = role.split(' ')
if "aft" in pref:
role = self._("after") + " " + date
if "bef" in pref:
role = self._("before") + " " + date
if pref in ("abt", "about"):
role = self._("about") + " " + date
if "c" in pref:
role = self._("circa") + " " + date
if "around" in pref:
role = self._("around") + " " + date
# parse is done in the default language
date = _dp.parse(role)
date = self.rlocale.get_date(date)
role = " (%s) " % date
# reset the date to the original calendar
cdate = date.to_calendar(Date.calendar_names[int(cal)])
ldate = self.rlocale.get_date(cdate)
role = " (%s) " % ldate
else:
role = " (%s) " % self._(role)
ordered += list_html

View File

@ -132,7 +132,6 @@ class DrawTree(object):
"""
return self.tree.handle
def buchheim(tree, node_width, h_separation, node_height, v_separation):
"""
Calculate the position of elements of the graph given a minimum
@ -142,9 +141,30 @@ def buchheim(tree, node_width, h_separation, node_height, v_separation):
min_x = second_walk(draw_tree, 0, node_width+h_separation, 0)
if min_x < 0:
third_walk(draw_tree, 0 - min_x)
top = get_min_coord_y(draw_tree)
height = get_max_coord_y(draw_tree)
return draw_tree
return (draw_tree, top, height)
def get_min_coord_y(tree, min_value=100.0):
""" Get the minimum coord_y """
if tree.coord_y < min_value:
min_value = tree.coord_y
for child in tree.children:
min_v = get_min_coord_y(child, min_value)
if min_value > min_v:
min_value = min_v
return min_value
def get_max_coord_y(tree, max_value=0.0):
""" Get the maximum coord_y """
if tree.coord_y > max_value:
max_value = tree.coord_y
for child in tree.children:
max_v = get_max_coord_y(child, max_value)
if max_value < max_v:
max_value = max_v
return max_value
def third_walk(tree, adjust):
"""
@ -156,7 +176,6 @@ def third_walk(tree, adjust):
for child in tree.children:
third_walk(child, adjust)
def firstwalk(tree, node_height, v_separation):
"""
Determine horizontal positions.
@ -189,7 +208,6 @@ def firstwalk(tree, node_height, v_separation):
tree.height = max(tree.height, tree.coord_y)
return tree
def apportion(tree, default_ancestor, v_separation):
"""
Figure out relative positions of node in a tree.
@ -263,7 +281,6 @@ def execute_shifts(tree):
child.height = max(child.height, child.coord_y)
tree.height = max(tree.height, child.height)
def ancestor(vil, tree, default_ancestor):
"""
The relevant text is at the bottom of page 7 of

View File

@ -472,8 +472,11 @@ class MediaPages(BasePage):
if orig_image_path != newpath:
url = self.report.build_url_fname(
newpath, None, self.uplink)
s_width = 'width: %dpx;' % max_width
mediadisplay += Html("a", href=url) + (
Html("img", src=url, alt=esc_page_title)
Html("img", src=url,
style=s_width,
alt=esc_page_title)
)
else:
dirname = tempfile.mkdtemp()
@ -507,9 +510,11 @@ class MediaPages(BasePage):
url = self.report.build_url_fname(newpath,
None,
self.uplink)
s_width = 'width: 48px;'
hyper = Html("a", href=url,
title=esc_page_title) + (
Html("img", src=img_url,
style=s_width,
alt=esc_page_title)
)
mediadisplay += hyper
@ -521,7 +526,9 @@ class MediaPages(BasePage):
summaryarea += mediadisplay
url = self.report.build_url_image("document.png",
"images", self.uplink)
s_width = 'width: 48px;'
mediadisplay += Html("img", src=url,
style=s_width,
alt=esc_page_title,
title=esc_page_title)

View File

@ -846,7 +846,12 @@ class NavWebReport(Report):
if self.reference_sort:
role_or_date = name
else:
role_or_date = str(event.get_date_object())
date = event.get_date_object()
# calendar is the original date calendar
calendar = str(date.get_calendar())
# convert date to gregorian for a correct sort
_date = str(date.to_calendar("gregorian"))
role_or_date = calendar + ":" + _date
else:
role_or_date = ""
place_fname = self.build_url_fname(place_handle, "plc",

View File

@ -85,8 +85,8 @@ _ = glocale.translation.sgettext
LOG = logging.getLogger(".NarrativeWeb")
getcontext().prec = 8
_WIDTH = 160
_HEIGHT = 120
_WIDTH = 280
_HEIGHT = 140
_VGAP = 10
_HGAP = 30
_SHADOW = 5
@ -1138,15 +1138,20 @@ class PersonPages(BasePage):
death = self.rlocale.get_date(dd_event.get_date_object())
if death == "":
death = "..."
value = person_name + "<br/>*", birth, "<br/>+", death
value = person_name + "<br/>*"+ birth+ "<br/>+"+ death
tdval = Html("td", value, class_="name")
table = Html("table", class_="table")
if thumbnail_url is None:
boxbg += Html("a", href=url, class_="noThumb") + value
else:
thumb = Html("span", class_="thumbnail") + (
Html("img", src=thumbnail_url, alt="Image: " + person_name))
boxbg += Html("a", href=url) + thumb + value
trow = Html("tr")
img = Html("img", src=thumbnail_url, alt="Img: " + person_name)
trow += Html("td", img, class_="img")
trow += tdval
table += trow
boxbg += Html("a", table, href=url, class_="thumbnail")
shadow = Html(
"div", class_="shadow", inline=True,
"div", "", class_="shadow", inline=True,
style="top: %dpx; left: %dpx;" % (top + _SHADOW, xoff + _SHADOW))
return [boxbg, shadow]
@ -1293,16 +1298,18 @@ class PersonPages(BasePage):
# We now apply the Buchheim algorith to this tree, and it assigns X
# and Y positions to all elements in the tree.
l_tree = buchheim(layout_tree, _WIDTH, _HGAP, _HEIGHT, _VGAP)
l_tree, top, height = buchheim(layout_tree, _WIDTH, _HGAP,
_HEIGHT, _VGAP)
top = abs(top)
# We know the height in 'pixels' where every Ancestor will sit
# precisely on an integer unit boundary.
with Html("div", id="tree", class_="subsection") as tree:
tree += Html("h4", _('Ancestors'), inline=True)
with Html("div", id="treeContainer",
style="width:%dpx; height:%dpx;" % (
l_tree.width + _XOFFSET + _WIDTH,
l_tree.height + _HEIGHT + _VGAP)
style="width:%dpx; height:%dpx; top: %dpx" % (
l_tree.width + _XOFFSET* (generations + 1) + _WIDTH,
height + top + _HEIGHT + _VGAP, top)
) as container:
tree += container
container += self.draw_tree(l_tree, 1, None)

View File

@ -126,7 +126,7 @@ class WebCalReport(Report):
self._ = self.rlocale.translation.sgettext
self.html_dir = mgobn('target')
self.title_text = mgobn('title')
self.title_text = html_escape(mgobn('title'))
filter_option = options.menu.get_option_by_name('filter')
self.filter = filter_option.get_filter()
self.name_format = mgobn('name_format')
@ -621,7 +621,8 @@ class WebCalReport(Report):
# Note. We use '/' here because it is a URL, not a OS
# dependent pathname need to leave home link alone,
# so look for it ...
url_fname = url_fname.lower()
if nav_text != _("Home"):
url_fname = url_fname.lower()
url = url_fname
add_subdirs = False
if not (url.startswith('http:') or url.startswith('/')):
@ -1632,7 +1633,7 @@ class WebCalReport(Report):
output_file = self.create_file('index', "")
# page title
title = self._("My Family Calendar")
title = self.title_text
nr_up = 0

View File

@ -17,6 +17,7 @@ gramps/gen/db/base.py
gramps/gen/db/exceptions.py
gramps/gen/db/generic.py
gramps/gen/display/name.py
gramps/gen/display/place.py
gramps/gen/filters/_filterparser.py
gramps/gen/filters/_genericfilter.py
gramps/gen/filters/rules/_changedsincebase.py
@ -742,6 +743,7 @@ gramps/plugins/tool/rebuildgenderstat.py
gramps/plugins/tool/rebuildrefmap.py
gramps/plugins/tool/relcalc.glade
gramps/plugins/tool/relcalc.py
gramps/plugins/tool/removespaces.glade
gramps/plugins/tool/removespaces.py
gramps/plugins/tool/removeunused.glade
gramps/plugins/tool/removeunused.py

View File

@ -85,7 +85,6 @@ gramps/gen/db/utils.py
# gen.display package
#
gramps/gen/display/__init__.py
gramps/gen/display/place.py
#
# gen.filters package
#

1532
po/cs.po

File diff suppressed because it is too large Load Diff

1429
po/de.po

File diff suppressed because it is too large Load Diff

View File

@ -7406,24 +7406,24 @@ msgstr "más de como"
#, python-brace-format
msgid "{number_of} year"
msgid_plural "{number_of} years"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "{number_of} año"
msgstr[1] "{number_of} años"
#. translators: leave all/any {...} untranslated
#: ../gramps/gen/lib/date.py:443
#, python-brace-format
msgid "{number_of} month"
msgid_plural "{number_of} months"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "{number_of} mes"
msgstr[1] "{number_of} meses"
#. translators: leave all/any {...} untranslated
#: ../gramps/gen/lib/date.py:454
#, python-brace-format
msgid "{number_of} day"
msgid_plural "{number_of} days"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "{number_of} día"
msgstr[1] "{number_of} días"
#: ../gramps/gen/lib/date.py:461
msgid "0 days"

1539
po/fi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

15747
po/he.po

File diff suppressed because it is too large Load Diff

2218
po/hr.po

File diff suppressed because it is too large Load Diff

14284
po/sv.po

File diff suppressed because it is too large Load Diff

1676
po/uk.po

File diff suppressed because it is too large Load Diff