Multiple languages ​​for the narrative web and optional other additions (#1051)

* Navweb: multi-language configuration.
* Navweb: multi-language exec, navigation menu, css
* Navweb: make css responsive for multi-language
* Language menu must work with a non english lang
* Avoid to copy common files for each language
* Use cms and archive in multi-languages
* Add the default index.
* Some cleanup.
* Images: performances improvement with image_size

Need to use the magic library (python-magic, python3-magic, ...)
If this library don't exist on the system, continue to use the Gdk method.

- force archive if we use CMS
- remove some unused code
- some strings are not translatable
- stay on the same page when you change language
- add image in the ancestor tree for all levels and not for the first 5

performances:
- copy images and thumbs only for the first language
* Some minor corrections and performances test
* Update comments for methods and functions
* Narweb: add show tags option
* Try to translate tags and suppress the colon (:)
* Narweb: integrate of webcal for multilang use
For each lang, we use the related calendar if it exists
* Death string only translated for the locale lang
* set correct url for extrapage.
* Add optional toggle for html sections
* show birth and death date if close option selected
* No background in references section with Mainz css
* Remove photo from list incompatible with multilang
* Add the first photo to the place page marker
* Add associated persons.
* Solves 'undefined' in map popup.
* Calendar: Set the background for the current day
* Thumbnail align problem with long description.
* Set the contact page date to the note date
* Add a scroll to top button.
* Increase the nb of generations since we can scroll
* Difficult to see the "go to top" icon.
* Better management for the toggle switch
This commit is contained in:
Serge Noiraud 2020-11-09 12:10:25 +01:00 committed by GitHub
parent c567b9e399
commit 31b80da797
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 4077 additions and 726 deletions

View File

@ -162,6 +162,7 @@ a[href]:hover, a[href]:active {
----------------------------------------------------- */ ----------------------------------------------------- */
div#nav, #subnavigation { div#nav, #subnavigation {
border: solid 1px #EEE; /* needed by IE7 */ border: solid 1px #EEE; /* needed by IE7 */
position: relative;
} }
#subnavigation ul { #subnavigation ul {
overflow: hidden; overflow: hidden;
@ -199,6 +200,35 @@ div#nav ul li.CurrentSection a {
#subnavigation ul li.CurrentSection a { #subnavigation ul li.CurrentSection a {
background-color: white; background-color: white;
} }
div#nav li.lang {
font-size: smaller;
font-family: sans-serif;
padding-top: .4em;
padding-bottom: .2em;
font-weight: bold;
}
div#nav li.lang:hover > ul {
visibility: visible;
opacity: 1;
}
div#nav ul.lang {
position: absolute;
visibility: hidden;
opacity: 0;
z-index: 999;
background-color: #EEE;
top: -1em;
font-size: larger;
font-family: sans-serif;
}
div#nav ul.lang:hover {
float: initial;
padding-left: 0px;
}
div#nav ul.lang li {
float: none;
padding: 2px;
}
/* Alphabet Navigation /* Alphabet Navigation
----------------------------------------------------- */ ----------------------------------------------------- */
div#alphanav { div#alphanav {
@ -316,6 +346,21 @@ div#nav::after {
.content { .content {
padding: 0em 0.5em; padding: 0em 0.5em;
} }
.lang {
position: relative;
}
.lang > .lang {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.lang:hover > .lang {
display: block;
}
} }
/* Main Table /* Main Table
@ -591,11 +636,13 @@ div#SourceDetail {
/* Subsection /* Subsection
----------------------------------------------------- */ ----------------------------------------------------- */
#Home #GalleryDisplay, #Introduction #GalleryDisplay { #Home #GalleryDisplay, #Introduction #GalleryDisplay,
#Contact #GalleryDisplay {
float: right; float: right;
margin: 1em; margin: 1em;
} }
#Home #GalleryDisplay img, #Introduction #GalleryDisplay img { #Home #GalleryDisplay img, #Introduction #GalleryDisplay img,
#Contact #GalleryDisplay img {
display: block; display: block;
max-width: 950px; max-width: 950px;
height: auto; height: auto;
@ -613,7 +660,7 @@ div#SourceDetail {
} }
.subsection { .subsection {
clear: both; clear: both;
overflow: hidden; overflow-x: auto;
} }
.subsection p { .subsection p {
margin: 0px; margin: 0px;
@ -625,6 +672,10 @@ div#SourceDetail {
table.relationships tr:hover { table.relationships tr:hover {
background-color: #DDE; background-color: #DDE;
} }
div.content table.tags {
text-align: left;
width: auto;
}
div#families table.fixed_subtables table.eventlist { div#families table.fixed_subtables table.eventlist {
table-layout: fixed; table-layout: fixed;
@ -656,6 +707,12 @@ div#families table.fixed_subtables .Child table.eventlist .ColumnDate {
#indivgallery { #indivgallery {
background-color: white; background-color: white;
} }
#indivgallery a {
color: black;
text-decoration: none;
word-wrap: break-word;
display: block;
}
#gallery .gallerycell { #gallery .gallerycell {
float: left; float: left;
width: 130px; width: 130px;
@ -672,7 +729,8 @@ div#families table.fixed_subtables .Child table.eventlist .ColumnDate {
} }
#indivgallery .thumbnail { #indivgallery .thumbnail {
float: left; float: left;
width: 130px; width: 160px;
height: 220px;
font-size: smaller; font-size: smaller;
text-align: center; text-align: center;
margin: 0.8em 0.5em; margin: 0.8em 0.5em;
@ -982,3 +1040,43 @@ body#fullyearlinked #YearGlance tbody td:hover .date {
border-radius: 45px; border-radius: 45px;
border: 5px solid; border: 5px solid;
} }
h4 button.icon {
width: 0.9em;
border: 0px solid;
padding: 0;
opacity: 1;
transform: rotate(90deg);
transition: transform 200ms ease-out 0s;
background: transparent;
}
h4 button.icon-close {
transform: rotate(90deg);
transition: transform 0.2s linear;
}
h4 button.icon-open {
transform: rotate(180deg);
transition: transform 0.2s linear;
}
svg {
fill: black;
}
/* Go to the top of the page */
#gototop {
display: none;
position: fixed;
bottom: 10px;
right: 20px;
z-index: 999;
border: none;
background-color: transparent;
color: black;
cursor: pointer;
border-radius: 4px;
width: 40px;
height: 40px;
padding: 0px;
}
#gototop:hover {
background-color: #CCC;
}

View File

@ -254,6 +254,7 @@ p#user_header {
div#nav, #subnavigation { div#nav, #subnavigation {
border: solid 1px #EEE; /* needed by IE7 */ border: solid 1px #EEE; /* needed by IE7 */
background-color: #13A926; background-color: #13A926;
position: relative;
} }
#subnavigation ul { #subnavigation ul {
overflow: hidden; overflow: hidden;
@ -291,6 +292,33 @@ div#nav ul li.CurrentSection a {
#nav ul li.CurrentSection a:hover { #nav ul li.CurrentSection a:hover {
background-color: #903; background-color: #903;
} }
div#nav li.lang {
font-size: 12px;
font-weight: bold;
padding-top: .5em;
}
div#nav li.lang:hover > ul {
visibility: visible;
opacity: 1;
}
div#nav ul.lang {
position: absolute;
visibility: hidden;
opacity: 0;
z-index: 999;
background-color: #EEE;
border-bottom: solid 1px #999;
padding: 2px 1px;
top: -1em;
}
div#nav ul.lang:hover {
float: initial;
}
div#nav ul.lang li {
float: none;
font-size: larger;
padding: 0px;
}
/* Webcal /* Webcal
----------------------------------------------------- */ ----------------------------------------------------- */
@ -470,6 +498,21 @@ div#nav::after {
.content { .content {
padding: 0em 0.5em; padding: 0em 0.5em;
} }
.lang {
position: relative;
}
.lang > .lang {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.lang:hover > .lang {
display: block;
}
} }
/* Main Table /* Main Table
@ -652,6 +695,10 @@ div#RelationshipList, div#RelationshipDetail {
div#RelationshipDetail div#FamilyDetail table.infolist tbody tr td { div#RelationshipDetail div#FamilyDetail table.infolist tbody tr td {
border: none; border: none;
} }
div.content table.tags {
text-align: left;
width: auto;
}
/* Places /* Places
=================================================----- */ =================================================----- */
@ -1393,7 +1440,8 @@ div.Residence table.infolist tr td {
#indivgallery .thumbnail { #indivgallery .thumbnail {
margin: 0; margin: 0;
float: left; float: left;
width: 130px; width: 160px;
height: 220px;
text-align: center; text-align: center;
background-color: white; background-color: white;
} }
@ -1835,3 +1883,43 @@ body#fullyearlinked #YearGlance tbody td:hover .date {
border-radius: 45px; border-radius: 45px;
border: 5px solid; border: 5px solid;
} }
h4 button.icon {
width: 0.9em;
border: 0px solid;
padding: 0;
opacity: 1;
transform: rotate(90deg);
transition: transform 200ms ease-out 0s;
background: transparent;
}
h4 button.icon-close {
transform: rotate(90deg);
transition: transform 0.2s linear;
}
h4 button.icon-open {
transform: rotate(180deg);
transition: transform 0.2s linear;
}
svg {
fill: #13A926;
}
/* Go to the top of the page */
#gototop {
display: none;
position: fixed;
bottom: 10px;
right: 20px;
z-index: 999;
border: none;
background-color: transparent;
color: black;
cursor: pointer;
border-radius: 4px;
width: 40px;
height: 40px;
padding: 0px;
}
#gototop:hover {
background-color: #BCEAF6;
}

View File

@ -163,6 +163,7 @@ a[href]:hover, a[href]:active {
----------------------------------------------------- */ ----------------------------------------------------- */
div#nav, #subnavigation { div#nav, #subnavigation {
border: solid 1px #454; /* needed by IE7 */ border: solid 1px #454; /* needed by IE7 */
position: relative;
} }
#subnavigation ul { #subnavigation ul {
overflow: hidden; overflow: hidden;
@ -203,6 +204,36 @@ div#nav ul li.CurrentSection a {
color: #454; color: #454;
background-color: white; background-color: white;
} }
div#nav li.lang {
color: #E0E6E0;
font-size: smaller;
font-family: sans-serif;
padding-top: .3em;
padding-bottom: .3em;
font-weight: bold;
}
div#nav li.lang:hover > ul {
visibility: visible;
opacity: 1;
}
div#nav ul.lang {
position: absolute;
visibility: hidden;
opacity: 0;
z-index: 999;
padding: 0px;
background-color: #454;
top: -1em;
font-size: larger;
font-family: sans-serif;
}
div#nav ul.lang:hover {
float: initial;
}
div#nav ul.lang li {
float: none;
padding: 1px 2px;
}
/* Alphabet Navigation /* Alphabet Navigation
----------------------------------------------------- */ ----------------------------------------------------- */
div#alphanav { div#alphanav {
@ -326,6 +357,21 @@ div#nav::after {
.content { .content {
padding: 0em 0.5em; padding: 0em 0.5em;
} }
.lang {
position: relative;
}
.lang > .lang {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.lang:hover > .lang {
display: block;
}
} }
/* Main Table /* Main Table
@ -678,7 +724,7 @@ div#SourceDetail {
} }
.subsection { .subsection {
clear: both; clear: both;
overflow: hidden; overflow-x: auto;
} }
.subsection p { .subsection p {
margin: 0px; margin: 0px;
@ -690,6 +736,10 @@ div#SourceDetail {
table.relationships tr:hover { table.relationships tr:hover {
background-color: #9DBF9D; background-color: #9DBF9D;
} }
div.content table.tags {
text-align: left;
width: auto;
}
div#families table.fixed_subtables table.eventlist { div#families table.fixed_subtables table.eventlist {
table-layout: fixed; table-layout: fixed;
} }
@ -711,6 +761,12 @@ div#families table.attrlist td.ColumnType {
#indivgallery { #indivgallery {
background-color: white; background-color: white;
} }
#indivgallery a {
color: black;
text-decoration: none;
word-wrap: break-word;
display: block;
}
#gallery .gallerycell { #gallery .gallerycell {
float: left; float: left;
width: 130px; width: 130px;
@ -727,7 +783,8 @@ div#families table.attrlist td.ColumnType {
} }
#indivgallery .thumbnail { #indivgallery .thumbnail {
float: left; float: left;
width: 130px; width: 160px;
height: 220px;
font-size: smaller; font-size: smaller;
text-align: center; text-align: center;
margin: 0.8em 0.5em; margin: 0.8em 0.5em;
@ -1045,3 +1102,43 @@ body#fullyearlinked #YearGlance tbody td:hover .date {
border-radius: 45px; border-radius: 45px;
border: 5px solid; border: 5px solid;
} }
h4 button.icon {
width: 0.9em;
border: 0px solid;
padding: 0;
opacity: 1;
transform: rotate(90deg);
transition: transform 200ms ease-out 0s;
background: transparent;
}
h4 button.icon-close {
transform: rotate(90deg);
transition: transform 0.2s linear;
}
h4 button.icon-open {
transform: rotate(180deg);
transition: transform 0.2s linear;
}
svg {
fill: #9DBF9D;
}
/* Go to the top of the page */
#gototop {
display: none;
position: fixed;
bottom: 10px;
right: 20px;
z-index: 999;
border: none;
background-color: white;
color: black;
cursor: pointer;
border-radius: 4px;
width: 40px;
height: 40px;
padding: 0px;
}
#gototop:hover {
background-color: #E0E6E0;
}

View File

@ -164,6 +164,7 @@ a[href]:hover, a[href]:active {
----------------------------------------------------- */ ----------------------------------------------------- */
div#nav, #subnavigation { div#nav, #subnavigation {
border: solid 1px #E0E0E9; /* needed by IE7 */ border: solid 1px #E0E0E9; /* needed by IE7 */
position: relative;
} }
#subnavigation ul { #subnavigation ul {
overflow: hidden; overflow: hidden;
@ -201,6 +202,35 @@ div#nav ul li.CurrentSection a {
#subnavigation ul li.CurrentSection a { #subnavigation ul li.CurrentSection a {
background-color: #FAFAFF; background-color: #FAFAFF;
} }
div#nav li.lang {
font-size: smaller;
font-family: sans-serif;
padding-top: .3em;
padding-bottom: .3em;
font-weight: bold;
}
div#nav li.lang:hover > ul {
visibility: visible;
opacity: 1;
}
div#nav ul.lang {
position: absolute;
visibility: hidden;
opacity: 0;
z-index: 999;
padding: 2px;
background-color: #E0E0E9;
top: -1em;
font-size: larger;
font-family: sans-serif;
}
div#nav ul.lang:hover {
float: initial;
}
div#nav ul.lang li {
float: none;
padding: 1px 2px;
}
/* Alphabet Navigation /* Alphabet Navigation
----------------------------------------------------- */ ----------------------------------------------------- */
@ -319,6 +349,21 @@ div#nav::after {
.content { .content {
padding: 0em 0.5em; padding: 0em 0.5em;
} }
.lang {
position: relative;
}
.lang > .lang {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.lang:hover > .lang {
display: block;
}
} }
/* Main Table /* Main Table
@ -675,7 +720,7 @@ div#SourceDetail {
} }
.subsection { .subsection {
clear: both; clear: both;
overflow: hidden; overflow-x: auto;
} }
.subsection p { .subsection p {
margin: 0px; margin: 0px;
@ -687,6 +732,10 @@ div#SourceDetail {
table.relationships tr:hover { table.relationships tr:hover {
background-color: #B4B4CB; background-color: #B4B4CB;
} }
div.content table.tags {
text-align: left;
width: auto;
}
div#families table.fixed_subtables table.eventlist { div#families table.fixed_subtables table.eventlist {
table-layout: fixed; table-layout: fixed;
} }
@ -708,6 +757,12 @@ div#families table.attrlist td.ColumnType {
#indivgallery { #indivgallery {
background-color: white; background-color: white;
} }
#indivgallery a {
color: black;
text-decoration: none;
word-wrap: break-word;
display: block;
}
#gallery .gallerycell { #gallery .gallerycell {
float: left; float: left;
width: 130px; width: 130px;
@ -724,7 +779,8 @@ div#families table.attrlist td.ColumnType {
} }
#indivgallery .thumbnail { #indivgallery .thumbnail {
float: left; float: left;
width: 130px; width: 160px;
height: 220px;
font-size: smaller; font-size: smaller;
text-align: center; text-align: center;
margin: 0.8em 0.5em; margin: 0.8em 0.5em;
@ -1045,3 +1101,43 @@ body#fullyearlinked #YearGlance tbody td:hover .date {
border-radius: 45px; border-radius: 45px;
border: 5px solid; border: 5px solid;
} }
h4 button.icon {
width: 0.9em;
border: 0px solid;
padding: 0;
opacity: 1;
transform: rotate(90deg);
transition: transform 200ms ease-out 0s;
background: transparent;
}
h4 button.icon-close {
transform: rotate(90deg);
transition: transform 0.2s linear;
}
h4 button.icon-open {
transform: rotate(180deg);
transition: transform 0.2s linear;
}
svg {
fill: #2E2E61;
}
/* Go to the top of the page */
#gototop {
display: none;
position: fixed;
bottom: 10px;
right: 20px;
z-index: 999;
border: none;
background-color: transparent;
color: black;
cursor: pointer;
border-radius: 4px;
width: 40px;
height: 40px;
padding: 0px;
}
#gototop:hover {
background-color: #E0E0E9;
}

View File

@ -164,6 +164,7 @@ a[href]:hover, a[href]:active {
----------------------------------------------------- */ ----------------------------------------------------- */
div#nav, #subnavigation { div#nav, #subnavigation {
border: solid 1px #FFE09F; /* needed by IE7 */ border: solid 1px #FFE09F; /* needed by IE7 */
position: relative;
} }
#subnavigation ul { #subnavigation ul {
overflow: hidden; overflow: hidden;
@ -201,6 +202,35 @@ div#nav ul li.CurrentSection a {
#subnavigation ul li.CurrentSection a { #subnavigation ul li.CurrentSection a {
background-color: #FFFBE7; background-color: #FFFBE7;
} }
div#nav li.lang {
font-size: smaller;
font-family: sans-serif;
padding-top: .3em;
padding-bottom: .3em;
font-weight: bold;
}
div#nav li.lang:hover > ul {
visibility: visible;
opacity: 1;
}
div#nav ul.lang {
position: absolute;
visibility: hidden;
opacity: 0;
z-index: 999;
padding: 5px 2px;
background-color: #FFE09F;
top: -1em;
font-size: larger;
font-family: sans-serif;
}
div#nav ul.lang:hover {
float: initial;
}
div#nav ul.lang li {
float: none;
padding: 1px 2px;
}
/* Alphabet Navigation /* Alphabet Navigation
----------------------------------------------------- */ ----------------------------------------------------- */
@ -319,6 +349,21 @@ div#nav::after {
.content { .content {
padding: 0em 0.5em; padding: 0em 0.5em;
} }
.lang {
position: relative;
}
.lang > .lang {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.lang:hover > .lang {
display: block;
}
} }
/* Main Table /* Main Table
@ -676,7 +721,7 @@ div#SourceDetail {
} }
.subsection { .subsection {
clear: both; clear: both;
overflow: visible; overflow-x: auto;
} }
.subsection p { .subsection p {
margin: 0px; margin: 0px;
@ -688,6 +733,10 @@ div#SourceDetail {
table.relationships tr:hover { table.relationships tr:hover {
background-color: #FFC35E; background-color: #FFC35E;
} }
div.content table.tags {
text-align: left;
width: auto;
}
div#families table.fixed_subtables table.eventlist { div#families table.fixed_subtables table.eventlist {
table-layout: fixed; table-layout: fixed;
} }
@ -709,6 +758,12 @@ div#families table.attrlist td.ColumnType {
#indivgallery { #indivgallery {
background-color: white; background-color: white;
} }
#indivgallery a {
color: #36220B;
text-decoration: none;
word-wrap: break-word;
display: block;
}
#gallery .gallerycell { #gallery .gallerycell {
float: left; float: left;
width: 130px; width: 130px;
@ -725,7 +780,8 @@ div#families table.attrlist td.ColumnType {
} }
#indivgallery .thumbnail { #indivgallery .thumbnail {
float: left; float: left;
width: 130px; width: 160px;
height: 220px;
font-size: smaller; font-size: smaller;
text-align: center; text-align: center;
margin: 0.8em 0.5em; margin: 0.8em 0.5em;
@ -1055,3 +1111,43 @@ body#fullyearlinked #YearGlance tbody td:hover .date {
border-radius: 45px; border-radius: 45px;
border: 5px solid; border: 5px solid;
} }
h4 button.icon {
width: 0.9em;
border: 0px solid;
padding: 0;
opacity: 1;
transform: rotate(90deg);
transition: transform 200ms ease-out 0s;
background: transparent;
}
h4 button.icon-close {
transform: rotate(90deg);
transition: transform 0.2s linear;
}
h4 button.icon-open {
transform: rotate(180deg);
transition: transform 0.2s linear;
}
svg {
fill: #EA8414;
}
/* Go to the top of the page */
#gototop {
display: none;
position: fixed;
bottom: 10px;
right: 20px;
z-index: 999;
border: none;
background-color: transparent;
color: black;
cursor: pointer;
border-radius: 4px;
width: 40px;
height: 40px;
padding: 0px;
}
#gototop:hover {
background-color: #FFE09F;
}

View File

@ -165,6 +165,7 @@ a[href]:hover, a[href]:active {
----------------------------------------------------- */ ----------------------------------------------------- */
div#nav, #subnavigation { div#nav, #subnavigation {
border: solid 1px #EAEEF4; /* needed by IE7 */ border: solid 1px #EAEEF4; /* needed by IE7 */
position: relative;
} }
#subnavigation ul { #subnavigation ul {
overflow: hidden; overflow: hidden;
@ -202,6 +203,35 @@ div#nav ul li.CurrentSection a {
#subnavigation ul li.CurrentSection a { #subnavigation ul li.CurrentSection a {
background-color: #FFF; background-color: #FFF;
} }
div#nav li.lang {
font-size: smaller;
font-family: sans-serif;
padding-top: .3em;
padding-bottom: .3em;
font-weight: bold;
}
div#nav li.lang:hover > ul {
visibility: visible;
opacity: 1;
}
div#nav ul.lang {
position: absolute;
visibility: hidden;
padding: 0px;
opacity: 0;
z-index: 999;
background-color: #EAEEF4;
top: -1em;
font-size: larger;
font-family: sans-serif;
}
div#nav ul.lang:hover {
float: initial;
}
div#nav ul.lang li {
float: none;
padding: 1px 2px;
}
/* Alphabet Navigation /* Alphabet Navigation
----------------------------------------------------- */ ----------------------------------------------------- */
@ -320,6 +350,21 @@ div#nav::after {
.content { .content {
padding: 0em 0.5em; padding: 0em 0.5em;
} }
.lang {
position: relative;
}
.lang > .lang {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.lang:hover > .lang {
display: block;
}
} }
/* Main Table /* Main Table
@ -588,7 +633,7 @@ table.eventlist td.ColumnPlace {
font-weight: normal; font-weight: normal;
} }
#GalleryDisplay { #GalleryDisplay {
margin: 0px auto; margin: 10px auto;
position: relative; position: relative;
} }
#GalleryDisplay img { #GalleryDisplay img {
@ -662,6 +707,7 @@ div#SourceDetail {
#Contact #GalleryDisplay img { #Contact #GalleryDisplay img {
display: block; display: block;
max-width: 950px; max-width: 950px;
width: 100%;
height: auto; height: auto;
float: right; float: right;
} }
@ -672,12 +718,12 @@ div#SourceDetail {
max-width: 100%; max-width: 100%;
} }
} }
#Home p, #Introduction p { #Home p, #Introduction p, #Contact p {
padding-left: 15px; padding-left: 15px;
} }
.subsection { .subsection {
clear: both; clear: both;
overflow: hidden; overflow-x: auto;
} }
.subsection p { .subsection p {
margin: 0px; margin: 0px;
@ -689,6 +735,10 @@ div#SourceDetail {
table.relationships tr:hover { table.relationships tr:hover {
background-color: #BFD0EA; background-color: #BFD0EA;
} }
div.content table.tags {
text-align: left;
width: auto;
}
div#families table.fixed_subtables table.eventlist { div#families table.fixed_subtables table.eventlist {
table-layout: fixed; table-layout: fixed;
} }
@ -710,10 +760,16 @@ div#families table.attrlist td.ColumnType {
#indivgallery { #indivgallery {
background-color: white; background-color: white;
} }
#indivgallery a {
color: black;
text-decoration: none;
word-wrap: break-word;
display: block;
}
#gallery .gallerycell { #gallery .gallerycell {
float: left; float: left;
width: 130px; width: 130px;
height: 150px; height: 160px;
text-align: center; text-align: center;
margin: 0; margin: 0;
background-color: white; background-color: white;
@ -726,7 +782,8 @@ div#families table.attrlist td.ColumnType {
} }
#indivgallery .thumbnail { #indivgallery .thumbnail {
float: left; float: left;
width: 130px; width: 160px;
height: 220px;
font-size: smaller; font-size: smaller;
text-align: center; text-align: center;
margin: 0.8em 0.5em; margin: 0.8em 0.5em;
@ -1047,3 +1104,43 @@ body#fullyearlinked #YearGlance tbody td:hover .date {
border-radius: 45px; border-radius: 45px;
border: 5px solid; border: 5px solid;
} }
h4 button.icon {
width: 0.9em;
border: 0px solid;
padding: 0;
opacity: 1;
transform: rotate(90deg);
transition: transform 200ms ease-out 0s;
background: transparent;
}
h4 button.icon-close {
transform: rotate(90deg);
transition: transform 0.2s linear;
}
h4 button.icon-open {
transform: rotate(180deg);
transition: transform 0.2s linear;
}
svg {
fill: #204D91;
}
/* Go to the top of the page */
#gototop {
display: none;
position: fixed;
bottom: 10px;
right: 20px;
z-index: 999;
border: none;
background-color: transparent;
color: black;
cursor: pointer;
border-radius: 4px;
width: 40px;
height: 40px;
padding: 0px;
}
#gototop:hover {
background-color: #EAEEF4;
}

View File

@ -169,6 +169,7 @@ a[href]:hover, a[href]:active {
-----------------------------------------------------------------*/ -----------------------------------------------------------------*/
div#nav, #subnavigation { div#nav, #subnavigation {
background: url(../images/Web_Mainz_Mid.png) repeat-x top left; background: url(../images/Web_Mainz_Mid.png) repeat-x top left;
position: relative;
} }
div#nav ul, #subnavigation ul { div#nav ul, #subnavigation ul {
list-style-type: none; list-style-type: none;
@ -199,6 +200,31 @@ div#nav ul li.CurrentSection a, #subnavigation ul li.CurrentSection a {
#subnavigation ul li.CurrentSection a { #subnavigation ul li.CurrentSection a {
border-width: 0px 1px 1px 1px; border-width: 0px 1px 1px 1px;
} }
div#nav li.lang {
font-size: smaller;
padding-top: 2px;
padding-bottom: 1px;
}
div#nav li.lang:hover > ul {
visibility: visible;
opacity: 1;
}
div#nav ul.lang {
position: absolute;
visibility: hidden;
opacity: 0;
z-index: 999;
background-color: #D8C19F;
top: -1em;
font-family: sans-serif;
}
div#nav ul.lang:hover {
float: initial;
}
div#nav ul.lang li {
float: none;
font-size: larger;
}
/* Alphabet Navigation /* Alphabet Navigation
-----------------------------------------------------------------*/ -----------------------------------------------------------------*/
@ -291,7 +317,7 @@ div#nav::after {
background: url(../images/Web_Mainz_Mid.png) #FFF2C6 repeat; background: url(../images/Web_Mainz_Mid.png) #FFF2C6 repeat;
} }
.nav.responsive {position: absolute; display: block; z-index: 100;} .nav.responsive {position: relative; display: block; z-index: 100;}
.nav.responsive a.icon { .nav.responsive a.icon {
position: absolute; position: absolute;
right: 0; right: 0;
@ -311,11 +337,27 @@ div#nav::after {
div#nav ul, #subnavigation ul { div#nav ul, #subnavigation ul {
padding-left: 0px; padding-left: 0px;
position: absolute;
} }
.content { .content {
padding: 0em 0.5em; padding: 0em 0.5em;
} }
.lang {
position: relative;
}
.lang > .lang {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.lang:hover > .lang {
display: block;
}
} }
/* Main Table /* Main Table
@ -552,7 +594,7 @@ table.IndividualList tr:hover td.ColumnSurname {
position: relative; position: relative;
} }
#GalleryDisplay img { #GalleryDisplay img {
margin: 0px auto; margin: 10px auto;
display:block; display:block;
border: solid 1px #7D5925; border: solid 1px #7D5925;
height: auto; height: auto;
@ -581,11 +623,6 @@ div#SourceDetail {
padding-bottom: 0px; padding-bottom: 0px;
margin: 0px; margin: 0px;
} }
#Contact #summaryarea #GalleryDisplay img {
display: block;
margin: 0px auto 1em auto;
border: solid 1px #7D5925;
}
#Contact #researcher { #Contact #researcher {
text-align: center; text-align: center;
} }
@ -611,17 +648,19 @@ div#SourceDetail {
float: right; float: right;
margin-left: 10px; margin-left: 10px;
margin-right: 10px; margin-right: 10px;
margin: 10px auto;
} }
#Home #GalleryDisplay img, #Introduction #GalleryDisplay img, #Home #GalleryDisplay img, #Introduction #GalleryDisplay img,
#Contact #GalleryDisplay { #Contact #GalleryDisplay img {
display: block; display: block;
max-width: 950px; max-width: 950px;
width: 100%;
height: auto; height: auto;
float: right; float: right;
} }
@media only screen and (max-width: 1080px) { @media only screen and (max-width: 1080px) {
#Home #GalleryDisplay img, #Introduction #GalleryDisplay img, #Home #GalleryDisplay img, #Introduction #GalleryDisplay img,
#Contact #GalleryDisplay { #Contact #GalleryDisplay img {
margin: 0 auto; margin: 0 auto;
max-width: 100%; max-width: 100%;
} }
@ -631,7 +670,7 @@ div#SourceDetail {
} }
.subsection { .subsection {
clear: both; clear: both;
overflow: hidden; overflow-x: auto;
} }
.subsection p { .subsection p {
margin: 0px; margin: 0px;
@ -643,6 +682,10 @@ div#SourceDetail {
table.relationships tr:hover td { table.relationships tr:hover td {
background-color: #D8C19F; background-color: #D8C19F;
} }
div.content table.tags {
text-align: left;
width: auto;
}
div#families table.fixed_subtables table.eventlist { div#families table.fixed_subtables table.eventlist {
table-layout: fixed; table-layout: fixed;
} }
@ -667,7 +710,6 @@ div#families .infolist h4 {
height: 150px; height: 150px;
text-align: center; text-align: center;
margin: 0; margin: 0;
background-color: white;
border-top: solid 1px #999; border-top: solid 1px #999;
border-right: solid 1px #999; border-right: solid 1px #999;
} }
@ -679,9 +721,18 @@ div#families .infolist h4 {
/* float container stretch, see www.quirksmode.org/css/clearing.html */ /* float container stretch, see www.quirksmode.org/css/clearing.html */
overflow: hidden; overflow: hidden;
} }
div#indivgallery div.thumbnail a,
div#gallerycell div.thumbnail a {
color: #7D5925;
text-decoration: none;
word-wrap: break-word;
width: 160px;
display: block;
}
#indivgallery .thumbnail { #indivgallery .thumbnail {
float: left; float: left;
width: 130px; width: 160px;
height: 220px;
font-size: smaller; font-size: smaller;
text-align: center; text-align: center;
margin: 0.5em; margin: 0.5em;
@ -1001,3 +1052,43 @@ body#fullyearlinked #YearGlance tbody td.highlight .date:hover {
border: 5px solid; border: 5px solid;
background: url(../images/Web_Mainz_Bkgd.png) black repeat; background: url(../images/Web_Mainz_Bkgd.png) black repeat;
} }
h4 button.icon {
width: 0.9em;
border: 0px solid;
padding: 0;
opacity: 1;
transform: rotate(90deg);
transition: transform 200ms ease-out 0s;
background: transparent;
}
h4 button.icon-close {
transform: rotate(90deg);
transition: transform 0.2s linear;
}
h4 button.icon-open {
transform: rotate(180deg);
transition: transform 0.2s linear;
}
svg {
fill: #7D5925;
}
/* Go to the top of the page */
#gototop {
display: none;
position: fixed;
bottom: 10px;
right: 20px;
z-index: 999;
border: none;
background-color: transparent;
color: black;
cursor: pointer;
border-radius: 4px;
width: 40px;
height: 40px;
padding: 0px;
}
#gototop:hover {
background-color: #FFF2C6;
}

View File

@ -238,10 +238,10 @@ div#alphanav, div#nav, div#subnavigation {
width: 100%; width: 100%;
margin: 0; margin: 0;
background-color: #A97; background-color: #A97;
position: relative;
} }
div#alphanav ul, div#nav ul, div#subnavigation ul { div#alphanav ul, div#nav ul, div#subnavigation ul {
list-style: none; list-style: none;
min-width: 770px;
height: 24px; height: 24px;
margin: 0; margin: 0;
padding: 0px 0px 0px 16px; padding: 0px 0px 0px 16px;
@ -282,6 +282,43 @@ div#nav ul li.CurrentSection a:hover {
div#subnavigation ul li.CurrentSection a { div#subnavigation ul li.CurrentSection a {
border-width: 0 0 1px 0; border-width: 0 0 1px 0;
} }
div#nav li.lang {
position: relative;
padding-top: 3px;
padding-left: 8px;
font: bold .7em sans;
}
div#nav li.lang:hover > ul {
visibility: visible;
opacity: 1;
}
div#nav ul.lang {
position: absolute;
visibility: hidden;
opacity: 0;
height: auto;
width: auto;
z-index: 999;
overflow: visible;
background-color: #A97;
top: -1em;
border-width: 2px 0px 1px 0px;
padding: 0px;
}
div#nav ul.lang li:after {
content: "";
}
div#nav li.lang ul.lang li {
float: none;
background-color: #A97;
margin-left: 10px;
padding: 0px 0px;
}
div#nav li.lang ul.lang li a {
float: none;
width: auto;
font: bold .9em sans;
}
/* Responsive navigation */ /* Responsive navigation */
button.navIcon { button.navIcon {
@ -347,7 +384,6 @@ div#nav::after {
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
margin-right: 10px;
} }
.nav.responsive ::after { .nav.responsive ::after {
/* need to remove the "|" when we are in the dropdown menu. */ /* need to remove the "|" when we are in the dropdown menu. */
@ -371,6 +407,28 @@ div#nav::after {
.content { .content {
padding: 0em 0.5em; padding: 0em 0.5em;
} }
div#nav ul li.lang {
padding-top: 3px;
padding-bottom: 6px;
padding-left: 0px;
}
.lang {
position: relative;
padding-top: 3px;
padding-left: 8px;
}
.lang > .lang {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.lang:hover > .lang {
display: block;
}
} }
/* Main Table /* Main Table
@ -1113,6 +1171,10 @@ div#parents table.infolist tbody tr td.ColumnValue ol li {
table.relationships tr:hover { table.relationships tr:hover {
background-color:#C1B398; background-color:#C1B398;
} }
div.content table.tags {
text-align: left;
width: auto;
}
div#families table.infolist { div#families table.infolist {
margin-top:.5em; margin-top:.5em;
} }
@ -1185,7 +1247,8 @@ div#Addresses table.infolist tr td a, div#Addresses table.infolist tr td p a {
#indivgallery .thumbnail { #indivgallery .thumbnail {
margin:0; margin:0;
float:left; float:left;
width:130px; width:160px;
height:220px;
text-align:center; text-align:center;
background-color: #F6F2EE; background-color: #F6F2EE;
} }
@ -1632,3 +1695,43 @@ body#fullyearlinked #YearGlance tbody td:hover .date {
border-radius: 45px; border-radius: 45px;
border: 5px solid; border: 5px solid;
} }
h4 button.icon {
width: 0.9em;
border: 0px solid;
padding: 0;
opacity: 1;
transform: rotate(90deg);
transition: transform 200ms ease-out 0s;
background: transparent;
}
h4 button.icon-close {
transform: rotate(90deg);
transition: transform 0.2s linear;
}
h4 button.icon-open {
transform: rotate(180deg);
transition: transform 0.2s linear;
}
svg {
fill: #542;
}
/* Go to the top of the page */
#gototop {
display: none;
position: fixed;
bottom: 10px;
right: 20px;
z-index: 999;
border: none;
background-color: transparent;
color: black;
cursor: pointer;
border-radius: 4px;
width: 40px;
height: 40px;
padding: 0px;
}
#gototop:hover {
background-color: #696969;
}

View File

@ -36,7 +36,12 @@ Females Web_Gender_Female.png
# -------------------------------------------------------------------------- */ # -------------------------------------------------------------------------- */
/* Subsections : Ancestors Tree -------------------------------------------- */ /* Subsections : Ancestors Tree -------------------------------------------- */
#tree { #tree {
page-break-before:always; margin:0;
padding:0;
background:none;
overflow-x:auto;
}
#toggle_anc {
margin:0; margin:0;
padding:0; padding:0;
background:none; background:none;
@ -46,7 +51,6 @@ Females Web_Gender_Female.png
position:relative; position:relative;
display: table-cell; display: table-cell;
vertical-align: middle; vertical-align: middle;
overflow: visible;
z-index:1; z-index:1;
} }
#treeContainer div.boxbg { #treeContainer div.boxbg {

View File

@ -117,7 +117,15 @@ div#FamilyMapDetail div#references table.infolist tbody tr td.ColumnPlace {
font: bold 0.9em sans-serif; font: bold 0.9em sans-serif;
max-height: 200px; max-height: 200px;
overflow-y: auto; overflow-y: auto;
padding: 0 0.5em 15px 0.5em; padding: 5px 0.5em 5px 0.5em;
}
#map_canvas .thumbnail {
padding: 5px 5px;
text-align: center;
}
#map_canvas img {
max-height: 300px;
max-width: 400px;
} }
#map_canvas .ol-popup-content a { #map_canvas .ol-popup-content a {
color: #111; color: #111;

View File

@ -65,6 +65,22 @@ def add_localization_option(menu, category):
menu.add_option(category, "trans", trans) menu.add_option(category, "trans", trans)
return trans return trans
def add_extra_localization_option(menu, category, name, optname):
"""
Insert an option for localizing the report into a different locale
than the default one
"""
trans = EnumeratedListOption(_(name),
glocale.DEFAULT_TRANSLATION_STR)
trans.add_item(glocale.DEFAULT_TRANSLATION_STR, _("Default"))
languages = glocale.get_language_dict()
for language in sorted(languages, key=glocale.sort_key):
trans.add_item(languages[language], language)
trans.set_help(_("The additional translation to be used for the report."))
menu.add_option(category, optname, trans)
return trans
def add_name_format_option(menu, category): def add_name_format_option(menu, category):
""" """
Insert an option for changing the report's name format to a Insert an option for changing the report's name format to a
@ -301,6 +317,24 @@ def run_date_format_option(report, menu):
format_to_be = 0 # ISO always exists format_to_be = 0 # ISO always exists
report._ldd.set_format(format_to_be) report._ldd.set_format(format_to_be)
def add_tags_option(menu, category):
"""
Insert an option for deciding whether to include tags
in the report
:param menu: The menu the options should be added to.
:type menu: :class:`.Menu`
:param category: A label that describes the category that the option
belongs to, e.g. "Report Options"
:type category: string
"""
include_tags = EnumeratedListOption(_('Tags'), 0)
include_tags.add_item(0, _('Do not include'))
include_tags.add_item(1, _('Include'))
include_tags.set_help(_("Whether to include tags"))
menu.add_option(category, 'inc_tags', include_tags)
def add_gramps_id_option(menu, category, ownline=False): def add_gramps_id_option(menu, category, ownline=False):
""" """
Insert an option for deciding whether to include Gramps IDs Insert an option for deciding whether to include Gramps IDs

View File

@ -163,13 +163,32 @@ def image_size(source):
from gi.repository import GdkPixbuf from gi.repository import GdkPixbuf
from gi.repository import GLib from gi.repository import GLib
try: try:
img = GdkPixbuf.Pixbuf.new_from_file(source) import re
width = img.get_width() import magic
height = img.get_height() # For performance reasons, we'll try to get image size from magic.
except GLib.GError: # This avoid to load the image in memory. This is a real improvement
width = 0 # when we have many big images.
height = 0 # Used in odfdoc, rtfdoc and webreport and tested with png, gif, jpeg
return (width, height) #
# file size with magic without (Gdk) ratio
# example 1 : 256k 0.00080 0.00575 7
# example 2 : 21M 0.00171 0.55860 326
img = magic.from_file(source)
found = img.find("precision")
if found > 0:
img = img[found:]
size = re.search('(\d+)\s*x\s*(\d+)', img).groups()
return (int(size[0]), int(size[1]))
except ImportError:
# python-magic is not installed. So Trying to get image size with Gdk.
try:
img = GdkPixbuf.Pixbuf.new_from_file(source)
width = img.get_width()
height = img.get_height()
except GLib.GError:
width = 0
height = 0
return (width, height)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #

View File

@ -65,11 +65,13 @@ class AddressBookPage(BasePage):
""" """
Create one page for one Address Create one page for one Address
""" """
def __init__(self, report, title, person_handle, has_add, has_res, has_url): def __init__(self, report, the_lang, the_title, person_handle,
has_add, has_res, has_url):
""" """
@param: report -- The instance of the main report class @param: report -- The instance of the main report class
for this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: person_handle -- the url, address and residence to use @param: person_handle -- the url, address and residence to use
for the report for the report
@param: has_add -- the address to use for the report @param: has_add -- the address to use for the report
@ -77,7 +79,7 @@ class AddressBookPage(BasePage):
@param: has_url -- the url to use for the report @param: has_url -- the url to use for the report
""" """
person = report.database.get_person_from_handle(person_handle) person = report.database.get_person_from_handle(person_handle)
BasePage.__init__(self, report, title, person.gramps_id) BasePage.__init__(self, report, the_lang, the_title, person.gramps_id)
self.bibli = Bibliography() self.bibli = Bibliography()
self.uplink = True self.uplink = True

View File

@ -64,15 +64,16 @@ class AddressBookListPage(BasePage):
""" """
Create the index for addresses. Create the index for addresses.
""" """
def __init__(self, report, title, has_url_addr_res): def __init__(self, report, the_lang, the_title, has_url_addr_res):
""" """
@param: report -- The instance of the main report class @param: report -- The instance of the main report class
for this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: has_url_addr_res -- The url, address and residence to use @param: has_url_addr_res -- The url, address and residence to use
for the report for the report
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
# Name the file, and create it # Name the file, and create it
output_file, sio = self.report.create_file("addressbook") output_file, sio = self.report.create_file("addressbook")
@ -87,11 +88,11 @@ class AddressBookListPage(BasePage):
outerwrapper += addressbooklist outerwrapper += addressbooklist
# Address Book Page message # Address Book Page message
msg = _("This page contains an index of all the individuals in " msg = self._("This page contains an index of all the individuals "
"the database, sorted by their surname, with one of the " "in the database, sorted by their surname, with one "
"following: Address, Residence, or Web Links. " "of the following: Address, Residence, or Web Links. "
"Selecting the person’s name will take you " "Selecting the person’s name will take you "
"to their individual Address Book page.") "to their individual Address Book page.")
addressbooklist += Html("p", msg, id="description") addressbooklist += Html("p", msg, id="description")
# begin Address Book table # begin Address Book table

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -67,12 +67,14 @@ class CitationPages(BasePage):
database objects. It passes this information to the 'Sources' tab. It is database objects. It passes this information to the 'Sources' tab. It is
told by the 'add_instances' call which 'Citation's to display. told by the 'add_instances' call which 'Citation's to display.
""" """
def __init__(self, report): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class
this report for this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title="") BasePage.__init__(self, report, the_lang, the_title)
def display_pages(self, title): def display_pages(self, the_lang, the_title):
pass pass

View File

@ -384,6 +384,40 @@ _EVENTMAP = set([EventType.MARRIAGE, EventType.MARR_ALT,
_NARRATIVESCREEN = "narrative-screen.css" _NARRATIVESCREEN = "narrative-screen.css"
_NARRATIVEPRINT = "narrative-print.css" _NARRATIVEPRINT = "narrative-print.css"
HOLIDAYS_ASSOC = [
# LANG INDEX HOLIDAY_NAME
("be", 0, 'Bulgaria'),
("ca", 1, 'Canada'),
("cs", 2, 'Czech Republic'),
("cl", 3, 'Chile'),
("zh", 4, 'China'),
("hr", 5, 'Croatia'),
("en", 13, 'United States of America'), # must be here. should be en_US
("en_GB", 6, 'England'),
("fi", 7, 'Finland'),
("fr_FR", 8, 'France'),
("de", 9, 'Germany'),
("ja", 10, 'Japan'),
("sk", 11, 'Slovakia'),
("sv", 12, 'Sweden'),
("he", 14, 'Jewish Holidays'),
("en_NZ", 15, 'New Zealand'),
("uk", 16, 'Ukraine'),
("sr_RS", 17, 'Serbia'),
("sr_RS@latin", 18, 'Serbia (Latin)'),
]
def do_we_have_holidays(lang):
"""
Associate an index for the holidays depending on the LANG
"""
for lng, idx, dummy_name in HOLIDAYS_ASSOC:
if lng == lang: # i.e. en_US
return idx
if lng[:2] == lang: # i.e. en_US[:2] => en
return idx
return None
def sort_people(dbase, handle_list, rlocale=glocale): def sort_people(dbase, handle_list, rlocale=glocale):
""" """
will sort the database people by surname will sort the database people by surname
@ -455,12 +489,13 @@ def sort_event_types(dbase, event_types, event_handle_list, rlocale):
@param: event_types -- a dict of event types @param: event_types -- a dict of event types
@param: event_handle_list -- all event handles in this database @param: event_handle_list -- all event handles in this database
""" """
event_dict = dict((evt_type, list()) for evt_type in event_types) rts = rlocale.translation.sgettext
event_dict = dict((rts(evt_type), list()) for evt_type in event_types)
for event_handle in event_handle_list: for event_handle in event_handle_list:
event = dbase.get_event_from_handle(event_handle) event = dbase.get_event_from_handle(event_handle)
event_type = rlocale.translation.sgettext(event.get_type().xml_str()) event_type = rts(event.get_type().xml_str())
# add (gramps_id, date, handle) from this event # add (gramps_id, date, handle) from this event
if event_type in event_dict: if event_type in event_dict:
@ -670,6 +705,7 @@ def get_first_letters(dbase, handle_list, key, rlocale=glocale):
@param: handle_list -- One of a handle list for either person or @param: handle_list -- One of a handle list for either person or
place handles or an evt types list place handles or an evt types list
@param: key -- Either a person, place, or event type @param: key -- Either a person, place, or event type
@param: rlocale -- The locale to use
The first letter (or letters if there is a contraction) are extracted from The first letter (or letters if there is a contraction) are extracted from
all the objects in the handle list. There may be duplicates, and there may all the objects in the handle list. There may be duplicates, and there may
@ -721,6 +757,10 @@ def get_index_letter(letter, index_list, rlocale=glocale):
the letter provided. See the discussion in get_first_letters above. the letter provided. See the discussion in get_first_letters above.
Continuing the example, if letter is Å and index_list is A, then this would Continuing the example, if letter is Å and index_list is A, then this would
return A. return A.
@param: letter -- The letter to find in the index_list
@param: index_list -- The list of all first letters in use
@param: rlocale -- The locale to use
""" """
for index in index_list: for index in index_list:
if not primary_difference(letter, index, rlocale): if not primary_difference(letter, index, rlocale):
@ -737,6 +777,7 @@ def alphabet_navigation(index_list, rlocale=glocale):
SurnameListPage, PlaceListPage, and EventList SurnameListPage, PlaceListPage, and EventList
@param: index_list -- a dictionary of either letters or words @param: index_list -- a dictionary of either letters or words
@param: rlocale -- The locale to use
""" """
sorted_set = defaultdict(int) sorted_set = defaultdict(int)

View File

@ -66,16 +66,19 @@ class ContactPage(BasePage):
""" """
This class is responsible for displaying information about the 'Researcher' This class is responsible for displaying information about the 'Researcher'
""" """
def __init__(self, report, title): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for this report @param: report -- The instance of the main report class for
@param: title -- Is the title of the web page this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
output_file, sio = self.report.create_file("contact") output_file, sio = self.report.create_file("contact")
result = self.write_header(self._('Contact')) result = self.write_header(self._('Contact'))
contactpage, head, dummy_body, outerwrapper = result contactpage, head, dummy_body, outerwrapper = result
ldatec = 0
# begin contact division # begin contact division
with Html("div", class_="content", id="Contact") as section: with Html("div", class_="content", id="Contact") as section:
@ -132,9 +135,12 @@ class ContactPage(BasePage):
# attach note # attach note
summaryarea += note_text summaryarea += note_text
# last modification of this note
ldatec = note.get_change_time()
# add clearline for proper styling # add clearline for proper styling
# add footer section # add footer section
footer = self.write_footer(None) footer = self.write_footer(ldatec)
outerwrapper += (FULLCLEAR, footer) outerwrapper += (FULLCLEAR, footer)
# send page out for porcessing # send page out for porcessing

View File

@ -67,12 +67,14 @@ class DownloadPage(BasePage):
""" """
This class is responsible for displaying information about the Download page This class is responsible for displaying information about the Download page
""" """
def __init__(self, report, title): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for this report @param: report -- The instance of the main report class
@param: title -- Is the title of the web page for this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
# do NOT include a Download Page # do NOT include a Download Page
if not self.report.inc_download: if not self.report.inc_download:
@ -140,10 +142,10 @@ class DownloadPage(BasePage):
dwnld += 1 dwnld += 1
trow = Html("tr", id='Row01') trow = Html("tr", id='Row01')
tbody += trow tbody += trow
fname_lnk = "../" + fname if the_lang else fname
dldescrx = dldescr[fnamex] dldescrx = dldescr[fnamex]
tcell = Html("td", class_="ColumnFilename") + ( tcell = Html("td", class_="ColumnFilename") + (
Html("a", fname, href=fname, Html("a", fname, href=fname_lnk,
title=html_escape(dldescrx)) title=html_escape(dldescrx))
) )
trow += tcell trow += tcell
@ -163,20 +165,21 @@ class DownloadPage(BasePage):
last_mod = datetime.datetime.fromtimestamp( last_mod = datetime.datetime.fromtimestamp(
modified) modified)
tcell += last_mod tcell += last_mod
# copy the file # copy the file only once
self.report.copy_file(dlfname[fnamex], if not os.path.exists(fname):
fname) self.report.copy_file(dlfname[fnamex],
fname)
else: else:
tcell += self._("Cannot open file") tcell += self._("Cannot open file")
if not dwnld: if not dwnld:
# We have several files to download # We have several files to download
# but all file names are empty # but all file names are empty
dldescrx = _("No file to download") dldescrx = self._("No file to download")
trow = Html("tr", id='Row01') trow = Html("tr", id='Row01')
tbody += trow tbody += trow
tcell = Html("td", class_="ColumnFilename", tcell = Html("td", class_="ColumnFilename",
colspan=3) + Html("h2", dldescrx) colspan=3) + Html("h4", dldescrx)
trow += tcell trow += tcell
# clear line for proper styling # clear line for proper styling
# create footer section # create footer section

View File

@ -85,23 +85,27 @@ class EventPages(BasePage):
The base class 'BasePage' is initialised once for each page that is The base class 'BasePage' is initialised once for each page that is
displayed. displayed.
""" """
def __init__(self, report): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class
this report for this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title="") BasePage.__init__(self, report, the_lang, the_title)
self.event_handle_list = [] self.event_handle_list = []
self.event_types = [] self.event_types = []
self.event_dict = defaultdict(set) self.event_dict = defaultdict(set)
def display_pages(self, title): def display_pages(self, the_lang, the_title):
""" """
Generate and output the pages under the Event tab, namely the event Generate and output the pages under the Event tab, namely the event
index and the individual event pages. index and the individual event pages.
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, self.report, the_lang, the_title)
LOG.debug("obj_dict[Event]") LOG.debug("obj_dict[Event]")
for item in self.report.obj_dict[Event].items(): for item in self.report.obj_dict[Event].items():
LOG.debug(" %s", str(item)) LOG.debug(" %s", str(item))
@ -111,29 +115,32 @@ class EventPages(BasePage):
event = self.r_db.get_event_from_handle(event_handle) event = self.r_db.get_event_from_handle(event_handle)
event_types.append(self._(event.get_type().xml_str())) event_types.append(self._(event.get_type().xml_str()))
message = _("Creating event pages") message = _("Creating event pages")
with self.r_user.progress(_("Narrated Web Site Report"), message, progress_title = self.report.pgrs_title(the_lang)
with self.r_user.progress(progress_title, message,
len(event_handle_list) + 1 len(event_handle_list) + 1
) as step: ) as step:
index = 1 index = 1
for event_handle in event_handle_list: for event_handle in event_handle_list:
step() step()
index += 1 index += 1
self.eventpage(self.report, title, event_handle) self.eventpage(self.report, the_lang, the_title, event_handle)
step() step()
self.eventlistpage(self.report, title, event_types, self.eventlistpage(self.report, the_lang, the_title, event_types,
event_handle_list) event_handle_list)
def eventlistpage(self, report, title, event_types, event_handle_list): def eventlistpage(self, report, the_lang, the_title,
event_types, event_handle_list):
""" """
Will create the event list page Will create the event list page
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class for
this report this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: event_types -- A list of the type in the events database @param: event_types -- A list of the type in the events database
@param: event_handle_list -- A list of event handles @param: event_handle_list -- A list of event handles
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
ldatec = 0 ldatec = 0
prev_letter = " " prev_letter = " "
@ -185,6 +192,7 @@ class EventPages(BasePage):
table += tbody table += tbody
# separate events by their type and then thier event handles # separate events by their type and then thier event handles
savevtyp = " "
for (evt_type, for (evt_type,
data_list) in sort_event_types(self.r_db, data_list) in sort_event_types(self.r_db,
event_types, event_types,
@ -233,6 +241,10 @@ class EventPages(BasePage):
letter = get_index_letter( letter = get_index_letter(
self._(str(evt_type)[0].capitalize()), self._(str(evt_type)[0].capitalize()),
index_list, self.rlocale) index_list, self.rlocale)
if letter != savevtyp:
savevtyp = letter
else:
letter = " "
else: else:
letter = " " letter = " "
@ -339,17 +351,19 @@ class EventPages(BasePage):
# return hyperlink to its caller # return hyperlink to its caller
return Html("a", grampsid, href=url, title=grampsid, inline=True) return Html("a", grampsid, href=url, title=grampsid, inline=True)
def eventpage(self, report, title, event_handle): def eventpage(self, report, the_lang, the_title, event_handle):
""" """
Creates the individual event page Creates the individual event page
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class for
this report this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: event_handle -- The event handle for the database @param: event_handle -- The event handle for the database
""" """
event = report.database.get_event_from_handle(event_handle) event = report.database.get_event_from_handle(event_handle)
BasePage.__init__(self, report, title, event.get_gramps_id()) BasePage.__init__(self, report, the_lang, the_title,
event.get_gramps_id())
if not event: if not event:
return return
@ -411,6 +425,17 @@ class EventPages(BasePage):
) )
tbody += trow tbody += trow
# Tags
tags = self.show_tags(event)
if tags and self.report.inc_tags:
trow = Html("tr") + (
Html("td", self._("Tags"),
class_="ColumnAttribute", inline=True),
Html("td", tags,
class_="ColumnValue", inline=True)
)
table += trow
# Narrative subsection # Narrative subsection
notelist = event.get_note_list() notelist = event.get_note_list()
notelist = self.display_note_list(notelist, Event) notelist = self.display_note_list(notelist, Event)

View File

@ -85,21 +85,24 @@ class FamilyPages(BasePage):
The base class 'BasePage' is initialised once for each page that is The base class 'BasePage' is initialised once for each page that is
displayed. displayed.
""" """
def __init__(self, report): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class
this report for this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title="") BasePage.__init__(self, report, the_lang, the_title)
self.family_dict = defaultdict(set) self.family_dict = defaultdict(set)
self.familymappages = None self.familymappages = None
def display_pages(self, title): def display_pages(self, the_lang, the_title):
""" """
Generate and output the pages under the Family tab, namely the family Generate and output the pages under the Family tab, namely the family
index and the individual family pages. index and the individual family pages.
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
LOG.debug("obj_dict[Family]") LOG.debug("obj_dict[Family]")
for item in self.report.obj_dict[Family].items(): for item in self.report.obj_dict[Family].items():
@ -107,27 +110,29 @@ class FamilyPages(BasePage):
message = _("Creating family pages...") message = _("Creating family pages...")
index = 1 index = 1
with self.r_user.progress(_("Narrated Web Site Report"), message, progress_title = self.report.pgrs_title(the_lang)
with self.r_user.progress(progress_title, message,
len(self.report.obj_dict[Family]) + 1 len(self.report.obj_dict[Family]) + 1
) as step: ) as step:
for family_handle in self.report.obj_dict[Family]: for family_handle in self.report.obj_dict[Family]:
step() step()
index += 1 index += 1
self.familypage(self.report, title, family_handle) self.familypage(self.report, the_lang, the_title, family_handle)
step() step()
self.familylistpage(self.report, title, self.familylistpage(self.report, the_lang, the_title,
self.report.obj_dict[Family].keys()) self.report.obj_dict[Family].keys())
def familylistpage(self, report, title, fam_list): def familylistpage(self, report, the_lang, the_title, fam_list):
""" """
Create a family index Create a family index
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class for
this report this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: fam_list -- The handle for the place to add @param: the_title -- The title page related to the language
@param: fam_list -- The handle for the place to add
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
output_file, sio = self.report.create_file("families") output_file, sio = self.report.create_file("families")
result = self.write_header(self._("Families")) result = self.write_header(self._("Families"))
@ -308,19 +313,21 @@ class FamilyPages(BasePage):
# and close the file # and close the file
self.xhtml_writer(familieslistpage, output_file, sio, ldatec) self.xhtml_writer(familieslistpage, output_file, sio, ldatec)
def familypage(self, report, title, family_handle): def familypage(self, report, the_lang, the_title, family_handle):
""" """
Create a family page Create a family page
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class for
this report this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: family_handle -- The handle for the family to add @param: family_handle -- The handle for the family to add
""" """
family = report.database.get_family_from_handle(family_handle) family = report.database.get_family_from_handle(family_handle)
if not family: if not family:
return return
BasePage.__init__(self, report, title, family.get_gramps_id()) BasePage.__init__(self, report, the_lang, the_title,
family.get_gramps_id())
ldatec = family.get_change_time() ldatec = family.get_change_time()
self.bibli = Bibliography() self.bibli = Bibliography()
@ -354,6 +361,16 @@ class FamilyPages(BasePage):
Html('sup') + (Html('small') + Html('sup') + (Html('small') +
self.get_citation_links( self.get_citation_links(
family.get_citation_list()))) family.get_citation_list())))
# Tags
tags = self.show_tags(family)
if tags and self.report.inc_tags:
trow = Html("table", class_='tags') + (Html("tr") + (
Html("td", self._("Tags") + self._(":"),
class_="ColumnAttribute", inline=True),
Html("td", tags,
class_="ColumnValue", inline=True),
))
relationshipdetail += trow
# display relationships # display relationships
families = self.display_family_relationships(family, None) families = self.display_family_relationships(family, None)
@ -386,33 +403,41 @@ class FamilyPages(BasePage):
# for use in family map pages... # for use in family map pages...
if self.report.options["familymappages"]: if self.report.options["familymappages"]:
name_format = self.report.options['name_format'] name_format = self.report.options['name_format']
fhandle = mhandle = father = mother = None father = mother = None
relationshipdetail += Html("h4", _("Family map"), inline=True) with self.create_toggle("map") as h4_head:
mapdetail = Html("br") relationshipdetail += h4_head
fhandle = family.get_father_handle() h4_head += self._("Family Map")
for handle, dummy_url in self.report.fam_link.items(): disp = "none" if self.report.options['toggle'] else "block"
if fhandle == handle: with Html("div", style="display:%s" % disp,
father = self.r_db.get_person_from_handle(fhandle) id="toggle_map") as toggle:
break relationshipdetail += toggle
if father: mapdetail = Html("br")
primary_name = father.get_primary_name() fhdle = family.get_father_handle()
name = Name(primary_name) for handle, dummy_url in self.report.fam_link.items():
name.set_display_as(name_format) if fhdle == handle:
fname = html_escape(_nd.display_name(name)) father = self.r_db.get_person_from_handle(fhdle)
mapdetail += self.family_map_link_for_parent(fhandle, fname) break
mapdetail += Html("br") if father:
mhandle = family.get_mother_handle() primary_name = father.get_primary_name()
for handle, dummy_url in self.report.fam_link.items(): name = Name(primary_name)
if mhandle == handle: name.set_display_as(name_format)
mother = self.r_db.get_person_from_handle(mhandle) fname = html_escape(_nd.display_name(name))
break mapdetail += self.family_map_link_for_parent(fhdle,
if mother: fname)
primary_name = mother.get_primary_name() mapdetail += Html("br")
name = Name(primary_name) mhdle = family.get_mother_handle()
name.set_display_as(name_format) for handle, dummy_url in self.report.fam_link.items():
mname = html_escape(_nd.display_name(name)) if mhdle == handle:
mapdetail += self.family_map_link_for_parent(mhandle, mname) mother = self.r_db.get_person_from_handle(mhdle)
relationshipdetail += mapdetail break
if mother:
primary_name = mother.get_primary_name()
name = Name(primary_name)
name.set_display_as(name_format)
mname = html_escape(_nd.display_name(name))
mapdetail += self.family_map_link_for_parent(mhdle,
mname)
toggle += mapdetail
# source references # source references
srcrefs = self.display_ind_sources(family) srcrefs = self.display_ind_sources(family)

View File

@ -65,13 +65,14 @@ class HomePage(BasePage):
""" """
This class is responsible for displaying information about the Home page. This class is responsible for displaying information about the Home page.
""" """
def __init__(self, report, title): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class for
this report this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
ldatec = 0 ldatec = 0
output_file, sio = self.report.create_file("index") output_file, sio = self.report.create_file("index")

View File

@ -65,13 +65,14 @@ class IntroductionPage(BasePage):
This class is responsible for displaying information This class is responsible for displaying information
about the introduction page. about the introduction page.
""" """
def __init__(self, report, title): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class for
this report this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
ldatec = 0 ldatec = 0
output_file, sio = self.report.create_file(report.intro_fname) output_file, sio = self.report.create_file(report.intro_fname)

View File

@ -58,7 +58,7 @@ from gramps.gen.lib import (Date, Media)
from gramps.gen.plug.report import Bibliography from gramps.gen.plug.report import Bibliography
from gramps.gen.utils.file import media_path_full from gramps.gen.utils.file import media_path_full
from gramps.gen.utils.thumbnails import run_thumbnailer from gramps.gen.utils.thumbnails import run_thumbnailer
from gramps.gen.utils.image import image_size # , resize_to_jpeg_buffer from gramps.gen.utils.image import image_size
from gramps.plugins.lib.libhtml import Html from gramps.plugins.lib.libhtml import Html
#------------------------------------------------ #------------------------------------------------
@ -89,22 +89,26 @@ class MediaPages(BasePage):
The base class 'BasePage' is initialised once for each page that is The base class 'BasePage' is initialised once for each page that is
displayed. displayed.
""" """
def __init__(self, report): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for this report @param: report -- The instance of the main report class
for this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title="") BasePage.__init__(self, report, the_lang, the_title)
self.media_dict = defaultdict(set) self.media_dict = defaultdict(set)
self.unused_media_handles = [] self.unused_media_handles = []
self.cur_fname = None self.cur_fname = None
self.create_images_index = self.report.options['create_images_index'] self.create_images_index = self.report.options['create_images_index']
def display_pages(self, title): def display_pages(self, the_lang, the_title):
""" """
Generate and output the pages under the Media tab, namely the media Generate and output the pages under the Media tab, namely the media
index and the individual media pages. index and the individual media pages.
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
LOG.debug("obj_dict[Media]") LOG.debug("obj_dict[Media]")
for item in self.report.obj_dict[Media].items(): for item in self.report.obj_dict[Media].items():
@ -114,7 +118,8 @@ class MediaPages(BasePage):
else: else:
media_count = len(self.report.obj_dict[Media]) media_count = len(self.report.obj_dict[Media])
message = _("Creating media pages") message = _("Creating media pages")
with self.r_user.progress(_("Narrated Web Site Report"), message, progress_title = self.report.pgrs_title(the_lang)
with self.r_user.progress(progress_title, message,
media_count + 1 media_count + 1
) as step: ) as step:
# bug 8950 : it seems it's better to sort on desc + gid. # bug 8950 : it seems it's better to sort on desc + gid.
@ -153,7 +158,7 @@ class MediaPages(BasePage):
next_ = self.unused_media_handles[0] next_ = self.unused_media_handles[0]
else: else:
next_ = None next_ = None
self.mediapage(self.report, title, self.mediapage(self.report, the_lang, the_title,
handle, (prev, next_, index, media_count)) handle, (prev, next_, index, media_count))
prev = handle prev = handle
step() step()
@ -170,26 +175,29 @@ class MediaPages(BasePage):
next_ = None next_ = None
else: else:
next_ = self.unused_media_handles[idx] next_ = self.unused_media_handles[idx]
self.mediapage(self.report, title, media_handle, self.mediapage(self.report, the_lang, the_title,
media_handle,
(prev, next_, index, media_count)) (prev, next_, index, media_count))
prev = media_handle prev = media_handle
step() step()
index += 1 index += 1
idx += 1 idx += 1
self.medialistpage(self.report, title, sorted_media_handles) self.medialistpage(self.report, the_lang, the_title,
sorted_media_handles)
def medialistpage(self, report, title, sorted_media_handles): def medialistpage(self, report, the_lang, the_title, sorted_media_handles):
""" """
Generate and output the Media index page. Generate and output the Media index page.
@param: report -- The instance of the main report class @param: report -- The instance of the main report class
for this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: sorted_media_handles -- A list of the handles of the media to be @param: sorted_media_handles -- A list of the handles of the media to be
displayed sorted by the media title displayed sorted by the media title
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
if self.create_images_index: if self.create_images_index:
output_file, sio = self.report.create_file("media") output_file, sio = self.report.create_file("media")
@ -289,8 +297,6 @@ class MediaPages(BasePage):
gmfh = self.r_db.get_media_from_handle gmfh = self.r_db.get_media_from_handle
media = gmfh(media_handle) media = gmfh(media_handle)
gc.collect() # Reduce memory usage when many images. gc.collect() # Reduce memory usage when many images.
if idx != total:
self.unused_media_handles[idx]
trow += Html("tr") trow += Html("tr")
media_data_row = [ media_data_row = [
[index, "ColumnRowLabel"], [index, "ColumnRowLabel"],
@ -340,20 +346,21 @@ class MediaPages(BasePage):
# return hyperlink to its callers # return hyperlink to its callers
return hyper return hyper
def mediapage(self, report, title, media_handle, info): def mediapage(self, report, the_lang, the_title, media_handle, info):
""" """
Generate and output an individual Media page. Generate and output an individual Media page.
@param: report -- The instance of the main report class @param: report -- The instance of the main report class
for this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: media_handle -- The media handle to use @param: media_handle -- The media handle to use
@param: info -- A tuple containing the media handle for the @param: info -- A tuple containing the media handle for the
next and previous media, the current page next and previous media, the current page
number, and the total number of media pages number, and the total number of media pages
""" """
media = report.database.get_media_from_handle(media_handle) media = report.database.get_media_from_handle(media_handle)
BasePage.__init__(self, report, title, media.gramps_id) BasePage.__init__(self, report, the_lang, the_title, media.gramps_id)
(prev, next_, page_number, total_pages) = info (prev, next_, page_number, total_pages) = info
ldatec = media.get_change_time() ldatec = media.get_change_time()
@ -385,7 +392,10 @@ class MediaPages(BasePage):
# if there are media rectangle regions, attach behaviour style sheet # if there are media rectangle regions, attach behaviour style sheet
if _region_items: if _region_items:
fname = "/".join(["css", "behaviour.css"]) if self.the_lang and not self.usecms:
fname = "/".join(["..", "css", "behaviour.css"])
else:
fname = "/".join(["css", "behaviour.css"])
url = self.report.build_url_fname(fname, None, self.uplink) url = self.report.build_url_fname(fname, None, self.uplink)
head += Html("link", href=url, type="text/css", head += Html("link", href=url, type="text/css",
media="screen", rel="stylesheet") media="screen", rel="stylesheet")
@ -474,7 +484,7 @@ class MediaPages(BasePage):
# display the image # display the image
if orig_image_path != newpath: if orig_image_path != newpath:
url = self.report.build_url_fname( url = self.report.build_url_fname(
newpath, None, self.uplink) newpath, None, self.uplink, image=True)
s_width = 'width: %dpx;' % max_width s_width = 'width: %dpx;' % max_width
mediadisplay += Html("a", href=url) + ( mediadisplay += Html("a", href=url) + (
Html("img", src=url, Html("img", src=url,
@ -507,12 +517,14 @@ class MediaPages(BasePage):
img_url = self.report.build_url_fname(path, img_url = self.report.build_url_fname(path,
None, None,
self.uplink) self.uplink,
image=True)
if target_exists: if target_exists:
# TODO. Convert disk path to URL # TODO. Convert disk path to URL
url = self.report.build_url_fname(newpath, url = self.report.build_url_fname(newpath,
None, None,
self.uplink) self.uplink,
image=True)
s_width = 'width: 48px;' s_width = 'width: 48px;'
hyper = Html("a", href=url, hyper = Html("a", href=url,
title=esc_page_title) + ( title=esc_page_title) + (
@ -579,6 +591,17 @@ class MediaPages(BasePage):
) )
table += trow table += trow
# Tags
tags = self.show_tags(media)
if tags and self.report.inc_tags:
trow = Html("tr") + (
Html("td", self._("Tags"),
class_="ColumnAttribute", inline=True),
Html("td", tags,
class_="ColumnValue", inline=True)
)
table += trow
# get media notes # get media notes
notelist = self.display_note_list(media.get_note_list(), Media) notelist = self.display_note_list(media.get_note_list(), Media)
if notelist is not None: if notelist is not None:
@ -613,6 +636,11 @@ class MediaPages(BasePage):
def media_nav_link(self, handle, name, uplink=False): def media_nav_link(self, handle, name, uplink=False):
""" """
Creates the Media Page Navigation hyperlinks for Next and Prev Creates the Media Page Navigation hyperlinks for Next and Prev
@param: handle -- The media handle
@param: name -- The name to use for the link
@param: uplink -- If True, then "../../../" is inserted in front of the
result.
""" """
url = self.report.build_url_fname_html(handle, "img", uplink) url = self.report.build_url_fname_html(handle, "img", uplink)
name = html_escape(name) name = html_escape(name)
@ -642,8 +670,12 @@ class MediaPages(BasePage):
@param: photo -- The source object (image, pdf, ...) @param: photo -- The source object (image, pdf, ...)
""" """
ext = os.path.splitext(photo.get_path())[1] ext = os.path.splitext(photo.get_path())[1]
to_dir = self.report.build_path('images', handle) to_dir = self.report.build_path('images', handle, image=True)
newpath = os.path.join(to_dir, handle) + ext newpath = os.path.join(to_dir, handle) + ext
if (self.the_lang is not None and
self.the_lang != self.report.languages[0][0]):
# if multi languages, copy the image only for the first language.
return newpath
fullpath = media_path_full(self.r_db, photo.get_path()) fullpath = media_path_full(self.r_db, photo.get_path())
if not os.path.isfile(fullpath): if not os.path.isfile(fullpath):
@ -660,8 +692,9 @@ class MediaPages(BasePage):
if not os.path.isdir(to_dir): if not os.path.isdir(to_dir):
os.makedirs(to_dir) os.makedirs(to_dir)
new_file = os.path.join(self.html_dir, newpath) new_file = os.path.join(self.html_dir, newpath)
shutil.copyfile(fullpath, new_file) if not os.path.exists(newpath):
os.utime(new_file, (mtime, mtime)) shutil.copyfile(fullpath, new_file)
os.utime(new_file, (mtime, mtime))
return newpath return newpath
except (IOError, OSError) as msg: except (IOError, OSError) as msg:
error = _("Missing media object:" error = _("Missing media object:"

View File

@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
#!/usr/bin/env python
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2020- Serge Noiraud
#
# 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.
#
"""
Narrative Web index for multi languages
"""
#------------------------------------------------
# python modules
#------------------------------------------------
import logging
#------------------------------------------------
# Gramps module
#------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.plugins.lib.libhtml import Html
#------------------------------------------------
# specific narrative web import
#------------------------------------------------
from gramps.plugins.webreport.basepage import BasePage
_ = glocale.translation.sgettext
LOG = logging.getLogger(".multilang")
REDIRECT = """
function lang() {
var langs = %s;
var lang = navigator.languages || navigator.userLanguages || window.navigator.userLanguage;
var found = langs[0];
for (i=0; i < lang.length; i++) {
for (j=0; j < langs.length; j++) {
if (lang[i] == langs[j]) {
found = lang[i];
break;
};
};
};
location.replace("./"+found+"/index%s");
}
"""
class IndexPage(BasePage):
"""
This class is responsible for redirecting the user to the good page
"""
def __init__(self, report, langs):
"""
Create an index for multi language.
We will be redirected to the good page depending of the browser
language. If the browser language is unknown, we use the first
defined in the display tab of the narrative web configuration.
@param: report -- The instance of the main report class
for this report
@param: langs -- The languages to process
"""
BasePage.__init__(self, report, None, "index")
output_file, sio = report.create_file("index", ext="index")
page, head, body = Html.page('index',
self.report.encoding,
langs[0][0])
body.attr = ' onload="lang();"'
my_langs = "["
for lang in langs:
my_langs += "'" + lang[0].replace('_', '-')
my_langs += "', "
my_langs += "]"
with Html("script", type="text/javascript") as jsc:
head += jsc
jsc += REDIRECT % (my_langs, self.ext)
# send page out for processing
# and close the file
self.xhtml_writer(page, output_file, sio, 0)
self.report.close_file(output_file, sio, 0)

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,7 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.lib import (ChildRefType, Date, Name, Person, EventRoleType, from gramps.gen.lib import (ChildRefType, Date, Name, Person, EventRoleType,
Family, Event, EventType) Family, Event, EventType)
from gramps.gen.lib.date import Today from gramps.gen.lib.date import Today
from gramps.gen.mime import is_image_type
from gramps.gen.plug.report import Bibliography from gramps.gen.plug.report import Bibliography
from gramps.gen.plug.report import utils from gramps.gen.plug.report import utils
from gramps.gen.utils.alive import probably_alive from gramps.gen.utils.alive import probably_alive
@ -63,6 +64,7 @@ from gramps.gen.utils.db import get_birth_or_fallback, get_death_or_fallback
from gramps.plugins.lib.libhtml import Html from gramps.plugins.lib.libhtml import Html
from gramps.gen.utils.place import conv_lat_lon from gramps.gen.utils.place import conv_lat_lon
from gramps.gen.proxy import LivingProxyDb from gramps.gen.proxy import LivingProxyDb
from gramps.gen.relationship import get_relationship_calculator
#------------------------------------------------ #------------------------------------------------
# specific narrative web import # specific narrative web import
@ -111,11 +113,14 @@ class PersonPages(BasePage):
The base class 'BasePage' is initialised once for each page that is The base class 'BasePage' is initialised once for each page that is
displayed. displayed.
""" """
def __init__(self, report): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for this report @param: report -- The instance of the main report class
for this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title="") BasePage.__init__(self, report, the_lang, the_title)
self.ind_dict = defaultdict(set) self.ind_dict = defaultdict(set)
self.mapservice = None self.mapservice = None
self.sort_name = None self.sort_name = None
@ -128,19 +133,22 @@ class PersonPages(BasePage):
self.rel_class = None self.rel_class = None
self.placemappages = None self.placemappages = None
self.name = None self.name = None
self.gender_map = None
def display_pages(self, title): def display_pages(self, the_lang, the_title):
""" """
Generate and output the pages under the Individuals tab, namely the Generate and output the pages under the Individuals tab, namely the
individual index and the individual pages. individual index and the individual pages.
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
LOG.debug("obj_dict[Person]") LOG.debug("obj_dict[Person]")
for item in self.report.obj_dict[Person].items(): for item in self.report.obj_dict[Person].items():
LOG.debug(" %s", str(item)) LOG.debug(" %s", str(item))
message = _('Creating individual pages') message = _('Creating individual pages')
with self.r_user.progress(_("Narrated Web Site Report"), message, progress_title = self.report.pgrs_title(the_lang)
with self.r_user.progress(progress_title, message,
len(self.report.obj_dict[Person]) + 1 len(self.report.obj_dict[Person]) + 1
) as step: ) as step:
index = 1 index = 1
@ -148,9 +156,9 @@ class PersonPages(BasePage):
step() step()
index += 1 index += 1
person = self.r_db.get_person_from_handle(person_handle) person = self.r_db.get_person_from_handle(person_handle)
self.individualpage(self.report, title, person) self.individualpage(self.report, the_lang, the_title, person)
step() step()
self.individuallistpage(self.report, title, self.individuallistpage(self.report, the_lang, the_title,
self.report.obj_dict[Person].keys()) self.report.obj_dict[Person].keys())
################################################# #################################################
@ -158,17 +166,18 @@ class PersonPages(BasePage):
# creates the Individual List Page # creates the Individual List Page
# #
################################################# #################################################
def individuallistpage(self, report, title, ppl_handle_list): def individuallistpage(self, report, the_lang, the_title, ppl_handle_list):
""" """
Creates an individual page Creates an individual page
@param: report -- The instance of the main report class @param: report -- The instance of the main report class
for this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: ppl_handle_list -- The list of people for whom we need @param: ppl_handle_list -- The list of people for whom we need
to create a page. to create a page.
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
prev_letter = " " prev_letter = " "
# plugin variables for this module # plugin variables for this module
@ -426,23 +435,26 @@ class PersonPages(BasePage):
# creates an Individual Page # creates an Individual Page
# #
################################################# #################################################
gender_map = { def individualpage(self, report, the_lang, the_title, person):
Person.MALE : _('male'),
Person.FEMALE : _('female'),
Person.UNKNOWN : _('unknown'),
}
def individualpage(self, report, title, person):
""" """
Creates an individual page Creates an individual page
@param: report -- The instance of the main report class for this report @param: report -- The instance of the main report class
@param: title -- Is the title of the web page for this report
@param: person -- The person to use for this page. @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: person -- The person to use for this page.
""" """
BasePage.__init__(self, report, title, person.get_gramps_id()) BasePage.__init__(self, report, the_lang, the_title,
person.get_gramps_id())
place_lat_long = [] place_lat_long = []
self.gender_map = {
Person.MALE : self._('male'),
Person.FEMALE : self._('female'),
Person.UNKNOWN : self._('unknown'),
}
self.person = person self.person = person
self.bibli = Bibliography() self.bibli = Bibliography()
self.sort_name = self.get_name(person) self.sort_name = self.get_name(person)
@ -463,7 +475,8 @@ class PersonPages(BasePage):
# get the Relationship Calculator so that we can determine # get the Relationship Calculator so that we can determine
# bio, half, step- siblings for use in display_ind_parents() ... # bio, half, step- siblings for use in display_ind_parents() ...
self.rel_class = self.report.rel_class self.rel_class = get_relationship_calculator(reinit=True,
clocale=self.rlocale)
output_file, sio = self.report.create_file(person.get_handle(), "ppl") output_file, sio = self.report.create_file(person.get_handle(), "ppl")
self.uplink = True self.uplink = True
@ -619,8 +632,12 @@ class PersonPages(BasePage):
""" """
creates individual family tracelife map events creates individual family tracelife map events
@param: person -- person from database @param: tracelife -- The family event list
@param: links -- used to add links in the popup html page @param: placetitle -- The place title to add to the event list
@param: latitude -- The latitude for this place
@param: longitude -- The longitude for this place
@param: seq_ -- The sequence number for this event (googlemap)
@param: links -- Used to add links in the popup html page
""" """
# are we using Google? # are we using Google?
if self.mapservice == "Google": if self.mapservice == "Google":
@ -715,8 +732,8 @@ class PersonPages(BasePage):
# call_(report, up, head) # call_(report, up, head)
# add narrative-maps style sheet # add narrative-maps style sheet
if self.usecms: if self.the_lang and not self.usecms:
fname = "/".join([self.target_uri, "css", "narrative-maps.css"]) fname = "/".join(["..", "css", "narrative-maps.css"])
else: else:
fname = "/".join(["css", "narrative-maps.css"]) fname = "/".join(["css", "narrative-maps.css"])
url = self.report.build_url_fname(fname, None, self.uplink) url = self.report.build_url_fname(fname, None, self.uplink)
@ -731,11 +748,6 @@ class PersonPages(BasePage):
head += Html("script", type="text/javascript", head += Html("script", type="text/javascript",
src=src_js, inline=True) src=src_js, inline=True)
else: # OpenStreetMap, Stamen... else: # OpenStreetMap, Stamen...
url = self.secure_mode
url += ("maxcdn.bootstrapcdn.com/bootstrap/3.3.7/"
"css/bootstrap.min.css")
head += Html("link", href=url, type="text/javascript",
rel="stylesheet")
src_js = self.secure_mode src_js = self.secure_mode
src_js += "ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" src_js += "ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"
head += Html("script", type="text/javascript", head += Html("script", type="text/javascript",
@ -746,17 +758,12 @@ class PersonPages(BasePage):
url = "https://openlayers.org/en/latest/css/ol.css" url = "https://openlayers.org/en/latest/css/ol.css"
head += Html("link", href=url, type="text/css", head += Html("link", href=url, type="text/css",
rel="stylesheet") rel="stylesheet")
src_js = self.secure_mode
src_js += ("maxcdn.bootstrapcdn.com/bootstrap/3.3.7/"
"js/bootstrap.min.js")
head += Html("script", type="text/javascript",
src=src_js, inline=True)
if number_markers > 0: if number_markers > 0:
tracelife = "[" tracelife = "["
seq_ = 0 seq_ = 0
old_place_title = "" old_place_title = ""
links = "" links = "''"
ln_str = "<a href='%s' title='%s' target='_self'>%s</a>" ln_str = "<a href='%s' title='%s' target='_self'>%s</a>"
ppl_lnk = "" ppl_lnk = ""
for index in range(0, number_markers): for index in range(0, number_markers):
@ -789,12 +796,12 @@ class PersonPages(BasePage):
self.get_name(pers)) self.get_name(pers))
url = self.report.build_url_fname_html(event.get_handle(), url = self.report.build_url_fname_html(event.get_handle(),
"evt", self.uplink) "evt", self.uplink)
evt_type = self._(str(event.get_type())) evt_type = self._(event.get_type().xml_str())
evt_date = self.rlocale.get_date(event.get_date_object()) evt_date = self.rlocale.get_date(event.get_date_object())
evt_lnk = ln_str % (url, evt_date, evt_type) evt_lnk = ln_str % (url, evt_date, evt_type)
evt_lnk += " (" + evt_date + ")" evt_lnk += " (" + evt_date + ")"
links += ' + "</br>%s"' % (ppl_lnk + self._(":") + evt_lnk) links += ' + "<br>%s"' % (ppl_lnk + self._(":") + evt_lnk)
if index == number_markers - 1: if index == number_markers - 1:
tracelife = self._create_family_tracelife(tracelife, tracelife = self._create_family_tracelife(tracelife,
placetitle, placetitle,
@ -841,12 +848,12 @@ class PersonPages(BasePage):
url = self.report.build_url_fname_html(event.handle, url = self.report.build_url_fname_html(event.handle,
"evt", "evt",
self.uplink) self.uplink)
evt_type = self._(str(event.get_type())) evt_type = self._(event.get_type().xml_str())
date = self.rlocale.get_date(event.get_date_object()) date = self.rlocale.get_date(event.get_date_object())
evt_lnk = ln_str % (url, date, evt_type) evt_lnk = ln_str % (url, date, evt_type)
evt_lnk += " (" + date + ")" evt_lnk += " (" + date + ")"
links = '"</br>%s"' % (ppl_lnk + self._(":") + evt_lnk) links = '"<br>%s"' % (ppl_lnk + self._(":") + evt_lnk)
elif index == number_markers-1: elif index == number_markers-1:
tracelife = self._create_family_tracelife(tracelife, tracelife = self._create_family_tracelife(tracelife,
placetitle, placetitle,
@ -881,12 +888,12 @@ class PersonPages(BasePage):
url = self.report.build_url_fname_html(event.handle, url = self.report.build_url_fname_html(event.handle,
"evt", "evt",
self.uplink) self.uplink)
evt_type = self._(str(event.get_type())) evt_type = self._(event.get_type().xml_str())
date = self.rlocale.get_date(event.get_date_object()) date = self.rlocale.get_date(event.get_date_object())
evt_lnk = ln_str % (url, evt_type, evt_type) evt_lnk = ln_str % (url, evt_type, evt_type)
evt_lnk += " (" + date + ")" evt_lnk += " (" + date + ")"
if "<p>" in links: if "<p>" in links:
links += '"</br>%s"' % (ppl_lnk+self._(":") + evt_lnk) links += '"<br>%s"' % (ppl_lnk+self._(":") + evt_lnk)
else: else:
links = '"<p>%s"' % (ppl_lnk + self._(":") + evt_lnk) links = '"<p>%s"' % (ppl_lnk + self._(":") + evt_lnk)
old_place_title = placetitle old_place_title = placetitle
@ -963,9 +970,9 @@ class PersonPages(BasePage):
trow.extend( trow.extend(
Html("th", label, class_=colclass, inline=True) Html("th", label, class_=colclass, inline=True)
for (label, colclass) in [ for (label, colclass) in [
(_("Date"), "ColumnDate"), (self._("Date"), "ColumnDate"),
(_("Place Title"), "ColumnPlace"), (self._("Place Title"), "ColumnPlace"),
(_("Event Type"), "ColumnType") (self._("Event Type"), "ColumnType")
] ]
) )
@ -982,6 +989,7 @@ class PersonPages(BasePage):
tbody += trow tbody += trow
date = event.get_date_object() date = event.get_date_object()
evt_name = self._(event.get_type().xml_str())
trow.extend( trow.extend(
Html("td", data, class_=colclass, inline=True) Html("td", data, class_=colclass, inline=True)
for data, colclass in [ for data, colclass in [
@ -989,7 +997,7 @@ class PersonPages(BasePage):
(self.place_link(handle, placetitle, (self.place_link(handle, placetitle,
uplink=True), uplink=True),
"ColumnPlace"), "ColumnPlace"),
(self._(str(event.get_type())), "ColumnType") (evt_name, "ColumnType")
] ]
) )
@ -1066,7 +1074,7 @@ class PersonPages(BasePage):
# if Google and Drop Markers are selected, # if Google and Drop Markers are selected,
# then add "Drop Markers" button? # then add "Drop Markers" button?
if self.mapservice == "Google" and self.googleopts == "Drop": if self.mapservice == "Google" and self.googleopts == "Drop":
mapdetail += Html("button", _("Drop Markers"), mapdetail += Html("button", self._("Drop Markers"),
id="drop", onclick="drop()", inline=True) id="drop", onclick="drop()", inline=True)
# add body id for this page... # add body id for this page...
@ -1093,12 +1101,20 @@ class PersonPages(BasePage):
# begin family map division plus section title # begin family map division plus section title
with Html("div", class_="subsection", id="familymap") as familymap: with Html("div", class_="subsection", id="familymap") as familymap:
familymap += Html("h4", self._("Family Map"), inline=True) with self.create_toggle("map") as h4_head:
familymap += h4_head
h4_head += self._("Family Map")
# add family map link disp = "none" if self.report.options['toggle'] else "block"
person_handle = person.get_handle() with Html("div", style="display:%s" % disp,
url = self.report.build_url_fname_html(person_handle, "maps", True) id="toggle_map") as toggle:
familymap += self.family_map_link(person_handle, url)
familymap += toggle
# add family map link
person_handle = person.get_handle()
url = self.report.build_url_fname_html(person_handle,
"maps", True)
toggle += self.family_map_link(person_handle, url)
# return family map link to its caller # return family map link to its caller
return familymap return familymap
@ -1106,6 +1122,7 @@ class PersonPages(BasePage):
def draw_box(self, node, col, person): def draw_box(self, node, col, person):
""" """
Draw the box around the AncestorTree Individual name box... Draw the box around the AncestorTree Individual name box...
@param: node -- The node defining the box location @param: node -- The node defining the box location
@param: col -- The generation number @param: col -- The generation number
@param: person -- The person to set in the box @param: person -- The person to set in the box
@ -1135,28 +1152,30 @@ class PersonPages(BasePage):
boxbg += Html("span", person_name, class_="unlinked", inline=True) boxbg += Html("span", person_name, class_="unlinked", inline=True)
else: else:
thumbnail_url = None thumbnail_url = None
if self.create_media and col < 5: if self.create_media:
photolist = person.get_media_list() photolist = person.get_media_list()
if photolist: if photolist:
photo_handle = photolist[0].get_reference_handle() photo_handle = photolist[0].get_reference_handle()
photo = self.r_db.get_media_from_handle(photo_handle) photo = self.r_db.get_media_from_handle(photo_handle)
mime_type = photo.get_mime_type() mime_type = photo.get_mime_type()
if mime_type: if mime_type and is_image_type(mime_type):
region = self.media_ref_region_to_object(photo_handle, region = self.media_ref_region_to_object(photo_handle,
person) person)
rbuf = self.report.build_url_fname
if region: if region:
# make a thumbnail of this region # make a thumbnail of this region
newpath = self.copy_thumbnail( newpath = self.copy_thumbnail(
photo_handle, photo, region) photo_handle, photo, region)
# TODO. Check if build_url_fname can be used. newpath = rbuf(newpath, None, self.uplink,
newpath = "/".join(['..']*3 + [newpath]) image=True)
if win(): if win():
newpath = newpath.replace('\\', "/") newpath = newpath.replace('\\', "/")
thumbnail_url = newpath thumbnail_url = newpath
else: else:
(dummy_photo_url, thumbnail_url) = \ (dummy_photo_url, thumbnail_url) = \
self.report.prepare_copy_media(photo) self.report.prepare_copy_media(photo)
thumbnail_url = "/".join(['..']*3 + [thumbnail_url]) thumbnail_url = rbuf(thumbnail_url, None,
self.uplink, image=True)
if win(): if win():
thumbnail_url = thumbnail_url.replace('\\', "/") thumbnail_url = thumbnail_url.replace('\\', "/")
url = self.report.build_url_fname_html(person.handle, "ppl", True) url = self.report.build_url_fname_html(person.handle, "ppl", True)
@ -1169,7 +1188,7 @@ class PersonPages(BasePage):
death = self.rlocale.get_date(dd_event.get_date_object()) death = self.rlocale.get_date(dd_event.get_date_object())
if death == "": if death == "":
death = "..." death = "..."
value = person_name + "<br/>*"+ birth+ "<br/>+"+ death value = person_name + "<br>*"+ birth+ "<br>+"+ death
tdval = Html("td", value, class_="name") tdval = Html("td", value, class_="name")
table = Html("table", class_="table") table = Html("table", class_="table")
if thumbnail_url is None: if thumbnail_url is None:
@ -1333,19 +1352,26 @@ class PersonPages(BasePage):
_HEIGHT, _VGAP) _HEIGHT, _VGAP)
top = abs(top) top = abs(top)
# We know the height in 'pixels' where every Ancestor will sit tree_width = l_tree.width + _XOFFSET* (generations + 1) + _WIDTH
# precisely on an integer unit boundary. tree_height = height + top + _HEIGHT + _VGAP
with Html("div", id="tree", class_="subsection") as tree: with Html("div", id="tree", class_="subsection") as treecont:
tree += Html("h4", _('Ancestors'), inline=True) with self.create_toggle("anc") as h4_head:
with Html("div", id="treeContainer", treecont += h4_head
style="width:%dpx; height:%dpx; top: %dpx" % ( h4_head += self._("Ancestors")
l_tree.width + _XOFFSET* (generations + 1) + _WIDTH, # We know the height in 'pixels' where every Ancestor will sit
height + top + _HEIGHT + _VGAP, top) # precisely on an integer unit boundary.
) as container: disp = "none" if self.report.options['toggle'] else "block"
tree += container with Html("div", id="toggle_anc", class_="tree",
container += self.draw_tree(l_tree, 1, None) style="display:%s" % disp) as tree:
treecont += tree
with Html("div", id="treeContainer",
style="width:%dpx; height:%dpx; top: %dpx" % (
tree_width, tree_height, top)
) as container:
tree += container
container += self.draw_tree(l_tree, 1, None)
return tree return treecont
def draw_tree(self, l_node, gen_nr, c_node): def draw_tree(self, l_node, gen_nr, c_node):
""" """
@ -1387,9 +1413,13 @@ class PersonPages(BasePage):
""" """
# begin Associations division # begin Associations division
with Html("div", class_="subsection", id="Associations") as section: with Html("div", class_="subsection", id="Associations") as section:
section += Html("h4", self._('Associations'), inline=True) with self.create_toggle("assoc") as h4_head:
section += h4_head
h4_head += self._("Associations")
with Html("table", class_="infolist assoclist") as table: disp = "none" if self.report.options['toggle'] else "block"
with Html("table", class_="infolist assoclist",
id="toggle_assoc", style="display:%s" % disp) as table:
section += table section += table
thead = Html("thead") thead = Html("thead")
@ -1505,8 +1535,12 @@ class PersonPages(BasePage):
mother = None mother = None
with Html("div", id="pedigree", class_="subsection") as ped: with Html("div", id="pedigree", class_="subsection") as ped:
ped += Html("h4", self._('Pedigree'), inline=True) with self.create_toggle("pedigree") as h4_head:
with Html("ol", class_="pedigreegen") as pedol: ped += h4_head
h4_head += self._("Pedigree")
disp = "none" if self.report.options['toggle'] else "block"
with Html("ol", class_="pedigreegen", style="display:%s" % disp,
id="toggle_pedigree") as pedol:
ped += pedol ped += pedol
if father and mother: if father and mother:
pedfa = Html("li") + self.pedigree_person(father) pedfa = Html("li") + self.pedigree_person(father)
@ -1599,8 +1633,8 @@ class PersonPages(BasePage):
call_name = name.get_call_name() call_name = name.get_call_name()
if call_name and call_name != first_name: if call_name and call_name != first_name:
trow = Html("tr") + ( trow = Html("tr") + (
Html("td", _("Call Name"), class_="ColumnAttribute", Html("td", self._("Call Name"),
inline=True), class_="ColumnAttribute", inline=True),
Html("td", call_name, class_="ColumnValue", Html("td", call_name, class_="ColumnValue",
inline=True) inline=True)
) )
@ -1613,7 +1647,7 @@ class PersonPages(BasePage):
# (see http://gramps.1791082.n4.nabble.com/Where-is- # (see http://gramps.1791082.n4.nabble.com/Where-is-
# nickname-stored-tp4469779p4484272.html), and also because # nickname-stored-tp4469779p4484272.html), and also because
# the attribute is (normally) displayed lower down the # the attribute is (normally) displayed lower down the
# wNarrative Web report. # Narrative Web report.
nick_name = name.get_nick_name() nick_name = name.get_nick_name()
if nick_name and nick_name != first_name: if nick_name and nick_name != first_name:
trow = Html("tr") + ( trow = Html("tr") + (
@ -1654,10 +1688,10 @@ class PersonPages(BasePage):
if birth: if birth:
birth_date = birth.get_date_object() birth_date = birth.get_date_object()
death_date = _find_death_date(self.r_db, self.person)
if birth_date and birth_date is not Date.EMPTY: if birth_date and birth_date is not Date.EMPTY:
alive = probably_alive(self.person, self.r_db, Today()) alive = probably_alive(self.person, self.r_db, Today())
death_date = _find_death_date(self.r_db, self.person)
if not alive and death_date is not None: if not alive and death_date is not None:
nyears = death_date - birth_date nyears = death_date - birth_date
nyears = nyears.format(precision=3, nyears = nyears.format(precision=3,
@ -1669,6 +1703,35 @@ class PersonPages(BasePage):
class_="ColumnValue", inline=True) class_="ColumnValue", inline=True)
) )
table += trow table += trow
if self.report.options['toggle']:
# Show birth and/or death date if we use the close button.
if birth_date and birth_date is not Date.EMPTY:
trow = Html("tr") + (
Html("td", self._("Birth date"),
class_="ColumnAttribute", inline=True),
Html("td", self.rlocale.get_date(birth_date),
class_="ColumnValue", inline=True)
)
table += trow
if death_date and death_date is not Date.EMPTY:
trow = Html("tr") + (
Html("td", self._("Death date"),
class_="ColumnAttribute", inline=True),
Html("td", self.rlocale.get_date(death_date),
class_="ColumnValue", inline=True)
)
table += trow
# Tags
tags = self.show_tags(self.person)
if tags and self.report.inc_tags:
trow = Html("tr") + (
Html("td", self._("Tags"),
class_="ColumnAttribute", inline=True),
Html("td", tags,
class_="ColumnValue", inline=True)
)
table += trow
# return all three pieces to its caller # return all three pieces to its caller
# do NOT combine before returning # do NOT combine before returning
@ -1688,10 +1751,15 @@ class PersonPages(BasePage):
# begin events division and section title # begin events division and section title
with Html("div", id="events", class_="subsection") as section: with Html("div", id="events", class_="subsection") as section:
section += Html("h4", self._("Events"), inline=True) with self.create_toggle("event") as h4_head:
section += h4_head
h4_head += self._("Events")
# begin events table # begin events table
with Html("table", class_="infolist eventlist") as table: classe = "infolist eventlist toggle_event"
disp = "none" if self.report.options['toggle'] else "block"
with Html("table", class_=classe, id="toggle_event",
style="display:%s" % disp) as table:
section += table section += table
thead = Html("thead") thead = Html("thead")
@ -1829,9 +1897,6 @@ class PersonPages(BasePage):
reln = self.rel_class.get_sibling_relationship_string( reln = self.rel_class.get_sibling_relationship_string(
sibling_type, self.person.gender, child.gender) sibling_type, self.person.gender, child.gender)
# We have a problem here : reln is never in the choosen
# language but in the default language.
# Does get_sibling_relationship_string work ?
reln = reln[0].upper() + reln[1:] reln = reln[0].upper() + reln[1:]
except Exception: except Exception:
reln = self._("Not siblings") reln = self._("Not siblings")
@ -1998,10 +2063,14 @@ class PersonPages(BasePage):
# begin parents division # begin parents division
with Html("div", class_="subsection", id="parents") as section: with Html("div", class_="subsection", id="parents") as section:
section += Html("h4", self._("Parents"), inline=True) with self.create_toggle("parent") as h4_head:
section += h4_head
h4_head += self._("Parents")
# begin parents table # begin parents table
with Html("table", class_="infolist") as table: disp = "none" if self.report.options['toggle'] else "block"
with Html("table", class_="infolist toggle_parent",
id="toggle_parent", style="display:%s" % disp) as table:
section += table section += table
thead = Html("thead") thead = Html("thead")

View File

@ -51,6 +51,7 @@ import logging
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.lib import (PlaceType, Place, PlaceName) from gramps.gen.lib import (PlaceType, Place, PlaceName)
from gramps.gen.plug.report import Bibliography from gramps.gen.plug.report import Bibliography
from gramps.gen.mime import is_image_type
from gramps.plugins.lib.libhtml import Html from gramps.plugins.lib.libhtml import Html
from gramps.gen.utils.place import conv_lat_lon from gramps.gen.utils.place import conv_lat_lon
from gramps.gen.utils.location import get_main_location from gramps.gen.utils.location import get_main_location
@ -90,12 +91,14 @@ class PlacePages(BasePage):
The base class 'BasePage' is initialised once for each page that is The base class 'BasePage' is initialised once for each page that is
displayed. displayed.
""" """
def __init__(self, report): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class
this report for this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title="") BasePage.__init__(self, report, the_lang, the_title)
self.place_dict = defaultdict(set) self.place_dict = defaultdict(set)
self.placemappages = None self.placemappages = None
self.mapservice = None self.mapservice = None
@ -107,18 +110,20 @@ class PlacePages(BasePage):
# Place needs to display coordinates? # Place needs to display coordinates?
self.display_coordinates = report.options["coordinates"] self.display_coordinates = report.options["coordinates"]
def display_pages(self, title): def display_pages(self, the_lang, the_title):
""" """
Generate and output the pages under the Place tab, namely the place Generate and output the pages under the Place tab, namely the place
index and the individual place pages. index and the individual place pages.
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
LOG.debug("obj_dict[Place]") LOG.debug("obj_dict[Place]")
for item in self.report.obj_dict[Place].items(): for item in self.report.obj_dict[Place].items():
LOG.debug(" %s", str(item)) LOG.debug(" %s", str(item))
message = _("Creating place pages") message = _("Creating place pages")
with self.r_user.progress(_("Narrated Web Site Report"), message, progress_title = self.report.pgrs_title(the_lang)
with self.r_user.progress(progress_title, message,
len(self.report.obj_dict[Place]) + 1 len(self.report.obj_dict[Place]) + 1
) as step: ) as step:
index = 1 index = 1
@ -126,19 +131,21 @@ class PlacePages(BasePage):
step() step()
p_handle = self.report.obj_dict[PlaceName][place_name] p_handle = self.report.obj_dict[PlaceName][place_name]
index += 1 index += 1
self.placepage(self.report, title, p_handle[0], place_name) self.placepage(self.report, the_lang, the_title, p_handle[0],
place_name)
step() step()
self.placelistpage(self.report, title) self.placelistpage(self.report, the_lang, the_title)
def placelistpage(self, report, title): def placelistpage(self, report, the_lang, the_title):
""" """
Create a place index Create a place index
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class
this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
output_file, sio = self.report.create_file("places") output_file, sio = self.report.create_file("places")
result = self.write_header(self._("Places")) result = self.write_header(self._("Places"))
@ -283,19 +290,22 @@ class PlacePages(BasePage):
# and close the file # and close the file
self.xhtml_writer(placelistpage, output_file, sio, ldatec) self.xhtml_writer(placelistpage, output_file, sio, ldatec)
def placepage(self, report, title, place_handle, place_name): def placepage(self, report, the_lang, the_title, place_handle, place_name):
""" """
Create a place page Create a place page
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class
this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: place_handle -- The handle for the place to add @param: place_handle -- The handle for the place to add
@param: place_name -- The alternate place name
""" """
place = report.database.get_place_from_handle(place_handle) place = report.database.get_place_from_handle(place_handle)
if not place: if not place:
return None return
BasePage.__init__(self, report, title, place.get_gramps_id()) BasePage.__init__(self, report, the_lang, the_title,
place.get_gramps_id())
self.bibli = Bibliography() self.bibli = Bibliography()
ldatec = place.get_change_time() ldatec = place.get_change_time()
apname = _pd.display(self.r_db, place) apname = _pd.display(self.r_db, place)
@ -365,7 +375,10 @@ class PlacePages(BasePage):
placetitle = place_name placetitle = place_name
# add narrative-maps CSS... # add narrative-maps CSS...
fname = "/".join(["css", "narrative-maps.css"]) if the_lang and not self.usecms:
fname = "/".join(["..", "css", "narrative-maps.css"])
else:
fname = "/".join(["css", "narrative-maps.css"])
url = self.report.build_url_fname(fname, None, self.uplink) url = self.report.build_url_fname(fname, None, self.uplink)
head += Html("link", href=url, type="text/css", head += Html("link", href=url, type="text/css",
media="screen", rel="stylesheet") media="screen", rel="stylesheet")
@ -378,11 +391,6 @@ class PlacePages(BasePage):
head += Html("script", type="text/javascript", head += Html("script", type="text/javascript",
src=src_js, inline=True) src=src_js, inline=True)
else: # OpenStreetMap, Stamen... else: # OpenStreetMap, Stamen...
url = self.secure_mode
url += ("maxcdn.bootstrapcdn.com/bootstrap/3.3.7/"
"css/bootstrap.min.css")
head += Html("link", href=url, type="text/javascript",
rel="stylesheet")
src_js = self.secure_mode src_js = self.secure_mode
src_js += ("ajax.googleapis.com/ajax/libs/jquery/1.9.1/" src_js += ("ajax.googleapis.com/ajax/libs/jquery/1.9.1/"
"jquery.min.js") "jquery.min.js")
@ -394,11 +402,6 @@ class PlacePages(BasePage):
url = "https://openlayers.org/en/latest/css/ol.css" url = "https://openlayers.org/en/latest/css/ol.css"
head += Html("link", href=url, type="text/css", head += Html("link", href=url, type="text/css",
rel="stylesheet") rel="stylesheet")
src_js = self.secure_mode
src_js += ("maxcdn.bootstrapcdn.com/bootstrap/3.3.7/"
"js/bootstrap.min.js")
head += Html("script", type="text/javascript",
src=src_js, inline=True)
# section title # section title
placedetail += Html("h4", self._("Place Map"), inline=True) placedetail += Html("h4", self._("Place Map"), inline=True)
@ -442,6 +445,25 @@ class PlacePages(BasePage):
latitude, longitude = conv_lat_lon(place.get_latitude(), latitude, longitude = conv_lat_lon(place.get_latitude(),
place.get_longitude(), place.get_longitude(),
"D.D8") "D.D8")
tracelife = " "
if self.create_media and media_list:
for fmedia in media_list:
photo_hdle = fmedia.get_reference_handle()
photo = self.r_db.get_media_from_handle(photo_hdle)
mime_type = photo.get_mime_type()
descr = photo.get_description()
if mime_type and is_image_type(mime_type):
uplnk = self.uplink
(pth,
dummy_) = self.report.prepare_copy_media(photo)
srbuf = self.report.build_url_fname
newpath = srbuf(pth, image=True, uplink=uplnk)
imglnk = self.media_link(photo_hdle, newpath,
descr, uplink=uplnk,
usedescr=False)
tracelife += str(imglnk)
break # We show only the first image
scripts = Html() scripts = Html()
if self.mapservice == "Google": if self.mapservice == "Google":
with Html("script", type="text/javascript", with Html("script", type="text/javascript",
@ -453,7 +475,7 @@ class PlacePages(BasePage):
jsc += MARKERS % ([[plce, jsc += MARKERS % ([[plce,
latitude, latitude,
longitude, longitude,
1, ""]], 1, tracelife]],
latitude, longitude, latitude, longitude,
10) 10)
elif self.mapservice == "OpenStreetMap": elif self.mapservice == "OpenStreetMap":
@ -462,7 +484,7 @@ class PlacePages(BasePage):
jsc += MARKER_PATH % marker_path jsc += MARKER_PATH % marker_path
jsc += OSM_MARKERS % ([[float(longitude), jsc += OSM_MARKERS % ([[float(longitude),
float(latitude), float(latitude),
placetitle, ""]], placetitle, tracelife]],
longitude, latitude, 10) longitude, latitude, 10)
jsc += OPENLAYER jsc += OPENLAYER
else: # STAMEN else: # STAMEN
@ -471,7 +493,7 @@ class PlacePages(BasePage):
jsc += MARKER_PATH % marker_path jsc += MARKER_PATH % marker_path
jsc += STAMEN_MARKERS % ([[float(longitude), jsc += STAMEN_MARKERS % ([[float(longitude),
float(latitude), float(latitude),
placetitle, ""]], placetitle, tracelife]],
self.stamenopts, self.stamenopts,
longitude, latitude, 10) longitude, latitude, 10)
jsc += OPENLAYER jsc += OPENLAYER
@ -485,10 +507,6 @@ class PlacePages(BasePage):
# send page out for processing # send page out for processing
# and close the file # and close the file
if place_name == apname: # store only the primary named page if place_name == apname: # store only the primary named page
if place in self.report.visited: # only the first time
self.report.close_file(output_file, sio, None)
return None
self.report.visited.append(place)
self.xhtml_writer(placepage, output_file, sio, ldatec) self.xhtml_writer(placepage, output_file, sio, ldatec)
def get_first_letters(place_list, rlocale=glocale): def get_first_letters(place_list, rlocale=glocale):

View File

@ -79,19 +79,23 @@ class RepositoryPages(BasePage):
The base class 'BasePage' is initialised once for each page that is The base class 'BasePage' is initialised once for each page that is
displayed. displayed.
""" """
def __init__(self, report): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for this report @param: report -- The instance of the main report class
for this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title="") BasePage.__init__(self, report, the_lang, the_title)
self.repos_dict = defaultdict(set) self.repos_dict = defaultdict(set)
def display_pages(self, title): def display_pages(self, the_lang, the_title):
""" """
Generate and output the pages under the Repository tab, namely the Generate and output the pages under the Repository tab, namely the
repository index and the individual repository pages. repository index and the individual repository pages.
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
LOG.debug("obj_dict[Person]") LOG.debug("obj_dict[Person]")
for item in self.report.obj_dict[Repository].items(): for item in self.report.obj_dict[Repository].items():
@ -99,7 +103,8 @@ class RepositoryPages(BasePage):
# set progress bar pass for Repositories # set progress bar pass for Repositories
message = _('Creating repository pages') message = _('Creating repository pages')
with self.r_user.progress(_("Narrated Web Site Report"), message, progress_title = self.report.pgrs_title(the_lang)
with self.r_user.progress(progress_title, message,
len(self.report.obj_dict[Repository]) + 1 len(self.report.obj_dict[Repository]) + 1
) as step: ) as step:
# Sort the repositories # Sort the repositories
@ -112,26 +117,29 @@ class RepositoryPages(BasePage):
keys = sorted(repos_dict, key=self.rlocale.sort_key) keys = sorted(repos_dict, key=self.rlocale.sort_key)
# RepositoryListPage Class # RepositoryListPage Class
self.repositorylistpage(self.report, title, repos_dict, keys) self.repositorylistpage(self.report, the_lang, the_title,
repos_dict, keys)
idx = 1 idx = 1
for dummy_index, key in enumerate(keys): for dummy_index, key in enumerate(keys):
(repo, handle) = repos_dict[key] (repo, handle) = repos_dict[key]
step() step()
idx += 1 idx += 1
self.repositorypage(self.report, title, repo, handle) self.repositorypage(self.report, the_lang, the_title,
repo, handle)
def repositorylistpage(self, report, title, repos_dict, keys): def repositorylistpage(self, report, the_lang, the_title, repos_dict, keys):
""" """
Create Index for repositories Create Index for repositories
@param: report -- The instance of the main report class @param: report -- The instance of the main report class
for this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: repos_dict -- The dictionary for all repositories @param: repos_dict -- The dictionary for all repositories
@param: keys -- The keys used to access repositories @param: keys -- The keys used to access repositories
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
#inc_repos = self.report.options["inc_repository"] #inc_repos = self.report.options["inc_repository"]
output_file, sio = self.report.create_file("repositories") output_file, sio = self.report.create_file("repositories")
@ -207,17 +215,19 @@ class RepositoryPages(BasePage):
# and close the file # and close the file
self.xhtml_writer(repolistpage, output_file, sio, ldatec) self.xhtml_writer(repolistpage, output_file, sio, ldatec)
def repositorypage(self, report, title, repo, handle): def repositorypage(self, report, the_lang, the_title, repo, handle):
""" """
Create one page for one repository. Create one page for one repository.
@param: report -- The instance of the main report class for this report @param: report -- The instance of the main report class
@param: title -- Is the title of the web page for this report
@param: repo -- the repository to use @param: the_lang -- The lang to process
@param: handle -- the handle to use @param: the_title -- The title page related to the language
@param: repo -- the repository to use
@param: handle -- the handle to use
""" """
gid = repo.get_gramps_id() gid = repo.get_gramps_id()
BasePage.__init__(self, report, title, gid) BasePage.__init__(self, report, the_lang, the_title, gid)
ldatec = repo.get_change_time() ldatec = repo.get_change_time()
output_file, sio = self.report.create_file(handle, 'repo') output_file, sio = self.report.create_file(handle, 'repo')
@ -259,6 +269,17 @@ class RepositoryPages(BasePage):
) )
tbody += trow tbody += trow
# Tags
tags = self.show_tags(repo)
if tags and self.report.inc_tags:
trow = Html("tr") + (
Html("td", self._("Tags"),
class_="ColumnAttribute", inline=True),
Html("td", tags,
class_="ColumnValue", inline=True)
)
tbody += trow
# repository: address(es)... # repository: address(es)...
# repository addresses do NOT have Sources # repository addresses do NOT have Sources
repo_address = self.display_addr_list(repo.get_address_list(), repo_address = self.display_addr_list(repo.get_address_list(),

View File

@ -79,50 +79,55 @@ class SourcePages(BasePage):
The base class 'BasePage' is initialised once for each page that is The base class 'BasePage' is initialised once for each page that is
displayed. displayed.
""" """
def __init__(self, report): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class
this report for this report
@param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title="") BasePage.__init__(self, report, the_lang, the_title)
self.source_dict = defaultdict(set) self.source_dict = defaultdict(set)
self.navigation = None self.navigation = None
self.citationreferents = None self.citationreferents = None
def display_pages(self, title): def display_pages(self, the_lang, the_title):
""" """
Generate and output the pages under the Sources tab, namely the sources Generate and output the pages under the Sources tab, namely the sources
index and the individual sources pages. index and the individual sources pages.
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
LOG.debug("obj_dict[Source]") LOG.debug("obj_dict[Source]")
for item in self.report.obj_dict[Source].items(): for item in self.report.obj_dict[Source].items():
LOG.debug(" %s", str(item)) LOG.debug(" %s", str(item))
message = _("Creating source pages") message = _("Creating source pages")
with self.r_user.progress(_("Narrated Web Site Report"), message, progress_title = self.report.pgrs_title(the_lang)
with self.r_user.progress(progress_title, message,
len(self.report.obj_dict[Source]) + 1 len(self.report.obj_dict[Source]) + 1
) as step: ) as step:
self.sourcelistpage(self.report, title, self.sourcelistpage(self.report, the_lang, the_title,
self.report.obj_dict[Source].keys()) self.report.obj_dict[Source].keys())
index = 1 index = 1
for source_handle in self.report.obj_dict[Source]: for source_handle in self.report.obj_dict[Source]:
step() step()
index += 1 index += 1
self.sourcepage(self.report, title, source_handle) self.sourcepage(self.report, the_lang, the_title, source_handle)
def sourcelistpage(self, report, title, source_handles): def sourcelistpage(self, report, the_lang, the_title, source_handles):
""" """
Generate and output the Sources index page. Generate and output the Sources index page.
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class for
this report this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: source_handles -- A list of the handles of the sources to be @param: source_handles -- A list of the handles of the sources to be
displayed displayed
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
source_dict = {} source_dict = {}
@ -202,17 +207,19 @@ class SourcePages(BasePage):
# and close the file # and close the file
self.xhtml_writer(sourcelistpage, output_file, sio, 0) self.xhtml_writer(sourcelistpage, output_file, sio, 0)
def sourcepage(self, report, title, source_handle): def sourcepage(self, report, the_lang, the_title, source_handle):
""" """
Generate and output an individual Source page. Generate and output an individual Source page.
@param: report -- The instance of the main report class @param: report -- The instance of the main report class
for this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: source_handle -- The handle of the source to be output @param: source_handle -- The handle of the source to be output
""" """
source = report.database.get_source_from_handle(source_handle) source = report.database.get_source_from_handle(source_handle)
BasePage.__init__(self, report, title, source.get_gramps_id()) BasePage.__init__(self, report, the_lang, the_title,
source.get_gramps_id())
if not source: if not source:
return return
@ -272,6 +279,17 @@ class SourcePages(BasePage):
) )
tbody += trow tbody += trow
# Tags
tags = self.show_tags(source)
if tags and self.report.inc_tags:
trow = Html("tr") + (
Html("td", self._("Tags"),
class_="ColumnAttribute", inline=True),
Html("td", tags,
class_="ColumnValue", inline=True)
)
tbody += trow
# Source notes # Source notes
notelist = self.display_note_list(source.get_note_list(), Source) notelist = self.display_note_list(source.get_note_list(), Source)
if notelist is not None: if notelist is not None:

View File

@ -68,14 +68,16 @@ class StatisticsPage(BasePage):
""" """
Create one page for statistics Create one page for statistics
""" """
def __init__(self, report, title, step): def __init__(self, report, the_lang, the_title, step):
""" """
@param: report -- The instance of the main report class @param: report -- The instance of the main report class
for this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: step -- Use to continue the progess bar
""" """
import os import os
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
self.bibli = Bibliography() self.bibli = Bibliography()
self.uplink = False self.uplink = False
self.report = report self.report = report
@ -103,7 +105,7 @@ class StatisticsPage(BasePage):
chars += os.path.getsize(fullname) chars += os.path.getsize(fullname)
length = len(str(chars)) length = len(str(chars))
if chars <= 999999: if chars <= 999999:
mbytes = _("less than 1") mbytes = self._("less than 1")
else: else:
mbytes = str(chars)[:(length-6)] mbytes = str(chars)[:(length-6)]
except OSError: except OSError:
@ -229,6 +231,8 @@ class StatisticsPage(BasePage):
""" """
This function return the number of males, females and unknown gender This function return the number of males, females and unknown gender
from a person list. from a person list.
@param: person_list -- The list to process
""" """
males = 0 males = 0
females = 0 females = 0

View File

@ -73,16 +73,17 @@ class SurnamePage(BasePage):
""" """
This will create a list of individuals with the same surname This will create a list of individuals with the same surname
""" """
def __init__(self, report, title, surname, ppl_handle_list): def __init__(self, report, the_lang, the_title, surname, ppl_handle_list):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class for
this report this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: surname -- The surname to use @param: surname -- The surname to use
@param: ppl_handle_list -- The list of people for whom we need to create @param: ppl_handle_list -- The list of people for whom we need to create
a page. a page.
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
# module variables # module variables
showbirth = report.options['showbirth'] showbirth = report.options['showbirth']

View File

@ -77,19 +77,20 @@ class SurnameListPage(BasePage):
ORDER_BY_NAME = 0 ORDER_BY_NAME = 0
ORDER_BY_COUNT = 1 ORDER_BY_COUNT = 1
def __init__(self, report, title, ppl_handle_list, def __init__(self, report, the_lang, the_title, ppl_handle_list,
order_by=ORDER_BY_NAME, filename="surnames"): order_by=ORDER_BY_NAME, filename="surnames"):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class for
this report this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
@param: ppl_handle_list -- The list of people for whom we need to create @param: ppl_handle_list -- The list of people for whom we need to create
a page. a page.
@param: order_by -- The way to sort surnames : @param: order_by -- The way to sort surnames :
Surnames or Surnames count Surnames or Surnames count
@param: filename -- The name to use for the Surnames page @param: filename -- The name to use for the Surnames page
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
prev_surname = "" prev_surname = ""
prev_letter = " " prev_letter = " "

View File

@ -67,14 +67,15 @@ class ThumbnailPreviewPage(BasePage):
This class is responsible for displaying information about This class is responsible for displaying information about
the Thumbnails page. the Thumbnails page.
""" """
def __init__(self, report, title, cb_progress): def __init__(self, report, the_lang, the_title, cb_progress):
""" """
@param: report -- The instance of the main report class @param: report -- The instance of the main report class
for this report for this report
@param: the_lang -- Is the lang to process.
@param: title -- Is the title of the web page @param: title -- Is the title of the web page
@param: cb_progress -- The step used for the progress bar. @param: cb_progress -- The step used for the progress bar.
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
self.create_thumbs_only = report.options['create_thumbs_only'] self.create_thumbs_only = report.options['create_thumbs_only']
self.create_thumbs_index = self.report.options['create_thumbs_index'] self.create_thumbs_index = self.report.options['create_thumbs_index']
# bug 8950 : it seems it's better to sort on desc + gid. # bug 8950 : it seems it's better to sort on desc + gid.
@ -151,17 +152,18 @@ class ThumbnailPreviewPage(BasePage):
# create thumbnail # create thumbnail
(dummy_real_path, (dummy_real_path,
newpath) = self.report.prepare_copy_media(photo) newpath) = self.report.prepare_copy_media(photo)
newpath = self.report.build_url_fname(newpath) newpath = self.report.build_url_fname(newpath, image=True)
newpathc = newpath
# attach thumbnail to list... # attach thumbnail to list...
gallerycell += self.thumb_hyper_image(newpath, "img", gallerycell += self.thumb_hyper_image(newpathc, "img",
person_handle, ptitle) person_handle, ptitle)
index += 1 index += 1
indexpos += 1 indexpos += 1
# begin Thumbnail Reference section... # begin Thumbnail Reference section...
with Html("div", class_="subsection", id="references") as section: with Html("div", class_="content", id="references") as section:
outerwrapper += section outerwrapper += section
section += Html("h4", self._("References"), inline=True) section += Html("h4", self._("References"), inline=True)
@ -206,18 +208,25 @@ class ThumbnailPreviewPage(BasePage):
def thumbnail_link(self, name, index): def thumbnail_link(self, name, index):
""" """
creates a hyperlink for Thumbnail Preview Reference... creates a hyperlink for Thumbnail Preview Reference...
@param: name -- The image description
@param: index -- The image index
""" """
return Html("a", index, title=html_escape(name), return Html("a", index, title=html_escape(name),
href="#%d" % index) href="#%d" % index)
def thumb_hyper_image(self, thumbnail_url, subdir, fname, name): def thumb_hyper_image(self, thumbnail_url, subdir, fname, name):
""" """
eplaces media_link() because it doesn't work for this instance replaces media_link() because it doesn't work for this instance
@param: thumnail_url -- The url for this thumbnail
@param: subdir -- The subdir prefix to add
@param: fname -- The file name for this image
@param: name -- The image description
""" """
name = html_escape(name) name = html_escape(name)
url = "/".join(self.report.build_subdirs(subdir, url = "/".join(self.report.build_subdirs(subdir,
fname) + [fname]) + self.ext fname) + [fname]) + self.ext
with Html("div", class_="thumbnail") as thumbnail: with Html("div", class_="thumbnail") as thumbnail:
#snapshot += thumbnail #snapshot += thumbnail

View File

@ -58,13 +58,14 @@ class UpdatesPage(BasePage):
""" """
This class is responsible for displaying information about the Home page. This class is responsible for displaying information about the Home page.
""" """
def __init__(self, report, title): def __init__(self, report, the_lang, the_title):
""" """
@param: report -- The instance of the main report class for @param: report -- The instance of the main report class
this report for this report
@param: title -- Is the title of the web page @param: the_lang -- The lang to process
@param: the_title -- The title page related to the language
""" """
BasePage.__init__(self, report, title) BasePage.__init__(self, report, the_lang, the_title)
ldatec = 0 ldatec = 0
self.inc_repository = self.report.options['inc_repository'] self.inc_repository = self.report.options['inc_repository']
self.inc_families = self.report.options['inc_families'] self.inc_families = self.report.options['inc_families']