Compare commits
161 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fe0f125ad6 | |||
| e8b63987ac | |||
| 461ee4fe5c | |||
| d571516212 | |||
| 9208b8a3a8 | |||
| 9e013f6781 | |||
| c460506e4f | |||
| 3fcb9411dc | |||
| f7a50a0e74 | |||
| 6709d37526 | |||
| fc9e5c2a4a | |||
| e3eedb2219 | |||
| b7487330a7 | |||
| 1025a38caa | |||
| 2054c467db | |||
| 789b72289c | |||
| 2e1132bec0 | |||
| 8ccfa43e56 | |||
| 40140859af | |||
| e69e6ca338 | |||
| fb29a77f83 | |||
| 06cca96ad0 | |||
| 2c49461529 | |||
| 73d19851ef | |||
| 16c8e61944 | |||
| 2fbf945309 | |||
| cf184e72e8 | |||
| 1c27b785f4 | |||
| da7e4cc763 | |||
| 5d2fd8cbda | |||
| 005beac33f | |||
| ae53b401ce | |||
| 79c54aaedc | |||
| 4360976d73 | |||
| 5e9d79ac6f | |||
| ee1d9be898 | |||
| 75b0b66269 | |||
| c54f381737 | |||
| 2aa6b54de4 | |||
| 49bad564ae | |||
| 03ab64c4d5 | |||
| f7bd062bdb | |||
| c312c96987 | |||
| 6b2066c797 | |||
| 5d15ccb2a2 | |||
| 0095a07f12 | |||
| bb5b03dd78 | |||
| 26351c18c9 | |||
| f5861169fe | |||
| 4e2f98da02 | |||
| 95a0216287 | |||
| 03fb2ff1c2 | |||
| 17141a0536 | |||
| 528852b9b3 | |||
| 0de286e7a8 | |||
| 7979bf79fd | |||
| 7100c51a31 | |||
| 57f7502105 | |||
| 0f925a86f5 | |||
| 17f4d93363 | |||
| cea48b618f | |||
| 290d6f7287 | |||
| 4d0e86a2e8 | |||
| 831c7f9c66 | |||
| 702e51dd47 | |||
| f3555d0168 | |||
| ecd6da40dd | |||
| bedc4b8e74 | |||
| 8a8a21f85d | |||
| c7350c53e2 | |||
| 52e76b506a | |||
| ab52d0988e | |||
| 5935a315b2 | |||
| 793b13be67 | |||
| 48dfca57e2 | |||
| a07aae2e30 | |||
| 8f5daac4a7 | |||
| 0cd6394b72 | |||
| 57d8dcd574 | |||
| d5bb4da5a1 | |||
| 5c44d925e1 | |||
| c7e2e09b42 | |||
| 669e4af0b7 | |||
| 88f7a701a3 | |||
| 52c087154f | |||
| 1eaa609058 | |||
| 5f0c2c1c54 | |||
| 6d39920e6f | |||
| 2b62729f52 | |||
| 1c856bb93b | |||
| 710e40425f | |||
| bb3eecb365 | |||
| 8de8c69686 | |||
| 4379a09fd3 | |||
| 0dc2be6dd5 | |||
| daa845492d | |||
| cc28935b15 | |||
| 3d1ef5e595 | |||
| 44bdd14609 | |||
| bec5a41829 | |||
| c3206121df | |||
| 1e52204d94 | |||
| 82cd211d29 | |||
| 4244d70312 | |||
| 98cc9b3740 | |||
| efcf0d1b83 | |||
| c1024aa61d | |||
| fe3efc57ab | |||
| 52f2d7b4ba | |||
| 9e0e256fd2 | |||
| 50625c654b | |||
| 1e10eabb15 | |||
| a7b934003b | |||
| 1b2e91d365 | |||
| ff17f57ba3 | |||
| a206503a9b | |||
| 846a4d1a32 | |||
| d75d9797c0 | |||
| 5767b9c3c8 | |||
| d397b83dc8 | |||
| 7617891faf | |||
| d096d269c7 | |||
| e983578fff | |||
| e10df9eb6d | |||
| 14acaca0b5 | |||
| 6ba958cc41 | |||
| efbec440fd | |||
| 578daa825d | |||
| 29994242c7 | |||
| 69261509ee | |||
| d3d51677f9 | |||
| 6602843f5a | |||
| 7ec4a429a4 | |||
| 16d40189c6 | |||
| 4b9dba0c53 | |||
| dd80e4b80e | |||
| e39e59c795 | |||
| 590a5cf59a | |||
| f5b6389042 | |||
| a06478f8ed | |||
| a88ae843e3 | |||
| 71931e2e2e | |||
| e817b3cc4e | |||
| 7519561027 | |||
| 54944968cc | |||
| 6689ebd133 | |||
| e92a89e90f | |||
| 9d167aa0e4 | |||
| 3e54390047 | |||
| 40a81ae8eb | |||
| ff6d9a0936 | |||
| 6d4e4bd12d | |||
| 77d533f930 | |||
| 90dcc9b9ea | |||
| f823e4f126 | |||
| 4859c14aaa | |||
| f4a8f21032 | |||
| e894c4478f | |||
| 56afb5bca9 | |||
| 9da8f705f6 | |||
| ce4cd33139 |
@@ -1,5 +1,40 @@
|
||||
2018-08-08
|
||||
Version 5.0.2
|
||||
2019-09-14
|
||||
Version 5.1.1
|
||||
* Update translations: cs, de, fi, fr, he, hr, pt_PT, ru, sv
|
||||
* Disable development warning message
|
||||
* Add options to sandclock in tree document generator
|
||||
* Using regex in the sidebar gives different result from previous gramps release
|
||||
* Fix odt output when db owner has XML unfriendly chars
|
||||
* Update README
|
||||
- Bump required Python version to 3.3
|
||||
- Add optional fontconfig package
|
||||
* Fix CLI crash when generating reports
|
||||
* Fix Statusbar HandleError on merge families
|
||||
* Fix missing tooltip translations in the Note editor toolbar
|
||||
* Fix bugs in withinarea filter rule
|
||||
- Avoid bad coordinates in the ref place
|
||||
- Avoid alphabetic characters in filter rules
|
||||
- Could not convert string to float by using withinarea filter rule
|
||||
- Difference between sidebar filter and filter rule
|
||||
* Fix Graph outputs for multiple page PDF Postscript
|
||||
* Fix to make Gtk 'action names' always valid
|
||||
* Fix missing menus/buttons when operating in non-English languages
|
||||
* Fix ursor position error in lat and long fields
|
||||
* Avoid all characters looking like a dash in 'Clean input data' tool
|
||||
* Mainz Style sheet weird looking
|
||||
* Fix bugs in relationship view
|
||||
- Set symbols for the active person
|
||||
- Set good symbols for marriage, baptism, cremation and burial
|
||||
- Reduce the size of the sexuality symbol
|
||||
* Fix exception when editing Note with italics/bold etc. in non English
|
||||
* Restore keybindings for gramplet bars
|
||||
* Fix bug in web connection menu launching incorrect web site
|
||||
* Fix translation problem when creating event filter
|
||||
* Error when checking option to add Quit to Taskbar
|
||||
* Make the narratives notes placement an option
|
||||
|
||||
2019-08-21
|
||||
Version 5.1.0
|
||||
* Bump required Python version to 3.3, Gtk version 3.12
|
||||
* Update translations: ca, cs, da, de, en_GB, eo, fi, fr, hr, hu, is, it,
|
||||
nb, nn, pl, po, pt_BR, ru, sl, sv, uk, vi
|
||||
@@ -10,7 +45,7 @@ Version 5.0.2
|
||||
* New: On restart after crash, offer to run Check & Repair
|
||||
* New CLI commands; 'safe' mode and 'default' to help user with debugging
|
||||
Gramps
|
||||
* Narrative web fix:
|
||||
* Narrative web fix:
|
||||
- some strings not translated
|
||||
- The confidence and the date are not translated in the family map page.
|
||||
- The date doesn't use the specified date format.
|
||||
@@ -26,7 +61,7 @@ Version 5.0.2
|
||||
- OSM forward all http resquest to https.
|
||||
- When we are on a mobile phone or a small device, we suppress the
|
||||
navigation tab. In place, we have a new icon on the upper left
|
||||
which is used to show the dropdown menu.
|
||||
which is used to show the dropdown menu.
|
||||
- For Home, Introduction and Contact, If we have an image and this image
|
||||
contains regions, show the regions. We can go directly to the person page
|
||||
associated to this region. If we click on the image, we go directly to
|
||||
@@ -34,8 +69,8 @@ Version 5.0.2
|
||||
"include images and media objects" and "create and only use thumbnail"
|
||||
is unselected
|
||||
- The first line identifying a family will be more legible.
|
||||
The link is not useful in the parents and pedigree section for the
|
||||
current person.
|
||||
The link is not useful in the parents and pedigree section for the
|
||||
current person.
|
||||
- Adapt some css files.
|
||||
- sort the place references either by date or by name.
|
||||
- Add extra page to narrativeweb.
|
||||
@@ -177,7 +212,7 @@ Version 5.0.2
|
||||
* Add support for GEDCOM import _FREL/_MREL tags in INDI/FAMC
|
||||
* Improve support for GEDCOM export of _FREL/_MREL in INDI/FAMC
|
||||
|
||||
2018-08-08
|
||||
2019-08-08
|
||||
Version 5.0.2
|
||||
Update translations: cs, da, de, fi, fr, hr, it, ru, sl, sv
|
||||
* Fix some Gramplets not updating during tree changes after db change.
|
||||
@@ -251,7 +286,7 @@ Version 5.0.1
|
||||
* Fix help URLs when they contain illegal characters and to match
|
||||
wiki section targetID algorithm Issue
|
||||
* Update translations: hu, hr, de, ru, fi, pt_PT, fr, sv, sl
|
||||
* Fix contents of enclosed_by secondary dbapi column
|
||||
* Fix contents of enclosed_by secondary dbapi column
|
||||
(fixes scrambled places in tree view)
|
||||
* Google maps URL problem
|
||||
* Fix ODT reports with links when run in non-English languages
|
||||
@@ -403,7 +438,7 @@ Version 5.0.0-rc1
|
||||
* Fix Tag editor for multiple tag removes
|
||||
* In Narweb, Relationship to Center person reversed
|
||||
* Fix Citation Tree view for crash after plugin reload
|
||||
* Fix 'References' Gramplet for issue when activated during an import
|
||||
* Fix 'References' Gramplet for issue when activated during an import
|
||||
* disable Application Menu during import
|
||||
* Fix Person/Family/Event view updates on various associated changes
|
||||
* Fix Event view for changes in Main Participants
|
||||
@@ -432,11 +467,11 @@ Version 5.0.0-rc1
|
||||
* Fix confidence level sort in list views -based on the date-sort code.
|
||||
* Fix confidence level tooltip -Stop run on text.
|
||||
* Fix error in place displayer when offset is outside valid range
|
||||
* Fix places in example.gramps
|
||||
* Fix places in example.gramps
|
||||
- Moved Greek places into top level Greece entry & added English names.
|
||||
- Removed Puerto Rico as a country as part of USA
|
||||
* Use sgettext for Name Format dialog
|
||||
* Enable copying the birth & death fields for relationship view
|
||||
* Enable copying the birth & death fields for relationship view
|
||||
* Allow Copying of text fields for Details tabs in selected views with
|
||||
Details gramplets.
|
||||
- Person Details
|
||||
@@ -1170,8 +1205,8 @@ Version 3.4.4 of Gramps! "The Ministry of Silly Names", a maintenance release.
|
||||
* fix annoying errors on navigation related to citations gramplet and tag object.
|
||||
* listing the Family Trees can corrupt them.
|
||||
* various fix around handling Gedcom file format
|
||||
* fix citations and sources import on ProGen format
|
||||
* better date handling and better alternate translation support on some textual reports according to locale under windows
|
||||
* fix citations and sources import on ProGen format
|
||||
* better date handling and better alternate translation support on some textual reports according to locale under windows
|
||||
* avoid Errors when setting wrong value as markup for invalid dates (Preferences)
|
||||
* fix paragraph layout on PDF format or print output
|
||||
* New: New-Zealand holidays
|
||||
@@ -1189,7 +1224,7 @@ Version 3.4.3 of Gramps! "Whenever life gets you down, Mrs. Brown", a maintenanc
|
||||
* Sorting (both in the main display window, and particularly in Narrative Web output) now uses PyICU (if that module is available). Inclusion of PyICU is 'strongly recommended'. This resolves a number of bugs particularly related to sorting of non-Latin characters, and sorting on MS Windows and Mac OS X. Some changes have been made in Narrative Web to support contractions for alphabetic indices.
|
||||
* The automatic Addon checking and download now works once again (the location used in Gramps 3.4.2 and before had been changed, so the the automatic process was no longer working).
|
||||
* Import from Pro-Gen has been updated (at last) to take account of the change to Citations (in 3.4.0)
|
||||
* Import and Export of address fields in GEDCOM has been improved so that the round-trip works properly.
|
||||
* Import and Export of address fields in GEDCOM has been improved so that the round-trip works properly.
|
||||
* GEDCOM Repositories not imported correctly from FTM for Windows and Heredis.
|
||||
* Fixes to a number of errors in filtering notes.
|
||||
* Fix some errors in determining whether someone is alive (e.g. for filtering out alive people).
|
||||
@@ -1198,7 +1233,7 @@ Version 3.4.3 of Gramps! "Whenever life gets you down, Mrs. Brown", a maintenanc
|
||||
* Fixed update problems with citation bottombar gramplet (bug #6336)
|
||||
* Fixed Open Document Text output in Book report (bug #6457)
|
||||
* A number of changes to Narrative Web:
|
||||
** Media objects attached to Marriage events and Sources are not included in Narrative Web Site
|
||||
** Media objects attached to Marriage events and Sources are not included in Narrative Web Site
|
||||
** restructure the families index so families are indexed under both spouses, and the family name is normalised
|
||||
** separate out Families section in individual and families pages so individual page links to the family page and family page links to both people
|
||||
** normalise links to families so the link is only displayed if the family page is present, and the gid is included when appropriate
|
||||
@@ -1216,7 +1251,7 @@ Version 3.4.3 of Gramps! "Whenever life gets you down, Mrs. Brown", a maintenanc
|
||||
** Implemented a generalised back reference function to display the 'References' section of all pages. This recursively displays references till one is found for which a page exists.
|
||||
** Removed list of people and families from heading of the event pages as these are now in the 'References' section.
|
||||
** Fixed bug "0005968: Narrated Web Site not copying Source Citations files such as jpg or pdf docs to web site
|
||||
** Fixed bug "0005946 GRAMPS failed to insert jpeg image into proper place for an event" by displaying a thumbnail for citation media in the 'Source References' section (with a link to the media page)
|
||||
** Fixed bug "0005946 GRAMPS failed to insert jpeg image into proper place for an event" by displaying a thumbnail for citation media in the 'Source References' section (with a link to the media page)
|
||||
** Tidy up media pages - remove unused parameters, use list of media items generated in first pass. Should fix bugs 2365, 5905 and 6009.
|
||||
** Tidy up sources pages - fix numbering of repositories, remove unused parameters, fix title of individual source pages
|
||||
** Bug: reset NarrWeb navigation menu layout when style sheet doesn't support it
|
||||
@@ -1224,7 +1259,7 @@ Version 3.4.3 of Gramps! "Whenever life gets you down, Mrs. Brown", a maintenanc
|
||||
** Fix option to suppress Gramps ID (bug #6237)
|
||||
* a number of technical changes to Narrative Web
|
||||
** Removed a lot of redundant code and parameters (mainly connected with the old way of determining the objects to be included in the report).
|
||||
** Movement of some large chunks of code within the source file and some initial work towards GEPS 022: Narrative Website Refactor. Functionality should be unchanged.
|
||||
** Movement of some large chunks of code within the source file and some initial work towards GEPS 022: Narrative Website Refactor. Functionality should be unchanged.
|
||||
** Moved routines for calculating objects to be output so they can be part of default list building classes.
|
||||
* Various updated translations: da, de, es, fr, it, nb, nl, pt_BR, pt_PT, sv, uk
|
||||
|
||||
@@ -1416,7 +1451,7 @@ Version 3.1.3 -- the "What name?" release.
|
||||
2009-06-06
|
||||
Version 3.1.2 -- the "Skip the impersonations" release.
|
||||
* Contains translation updates and small bug fixes. No new features.
|
||||
* ca, cs, de, fr, he, it, nb, nl, pl, pt_br, ru, sk, sv,
|
||||
* ca, cs, de, fr, he, it, nb, nl, pl, pt_br, ru, sk, sv,
|
||||
* fixes a failure in 'Check & Repair Database'
|
||||
* fixes to Gramplets
|
||||
* fixes to CLI regressions
|
||||
@@ -1529,7 +1564,7 @@ Version 2.2.5 -- the "Now go away or I shall taunt you a second time" release
|
||||
|
||||
Version 2.2.4 -- the "When you're chewing on life's gristle, Don't grumble, give a whistle" release
|
||||
* Improved handling of readonly files
|
||||
* Enhanced parsing of longitute and latitude and mapping
|
||||
* Enhanced parsing of longitute and latitude and mapping
|
||||
(Benny Malengier/Zsolt Foldvari)
|
||||
* Check and repair improvements
|
||||
* Reference map rebuild tool
|
||||
|
||||
@@ -10,7 +10,7 @@ Requirements
|
||||
============
|
||||
The following packages **MUST** be installed in order for Gramps to work:
|
||||
|
||||
* **Python** 3.2 or greater - The programming language used by Gramps. https://www.python.org/
|
||||
* **Python** 3.3 or greater - The programming language used by Gramps. https://www.python.org/
|
||||
* **GTK** 3.12 or greater - A cross-platform widget toolkit for creating graphical user interfaces. http://www.gtk.org/
|
||||
* **pygobject** 3.12 or greater - Python Bindings for GLib/GObject/GIO/GTK+ https://wiki.gnome.org/Projects/PyGObject
|
||||
|
||||
@@ -115,6 +115,11 @@ The following packages are optional:
|
||||
ArchLinux : geocode-glib
|
||||
...
|
||||
|
||||
* **fontconfig**
|
||||
|
||||
Python bindings of fontconfig are required for displaying
|
||||
genealogical symbols
|
||||
|
||||
Optional packages required by Third-party Addons
|
||||
------------------------------------------------
|
||||
|
||||
|
||||
@@ -473,11 +473,10 @@ table.eventlist tbody tr td.ColumnSources {
|
||||
margin: 0px auto;
|
||||
display: block;
|
||||
border: solid 1px #999;
|
||||
max-width: 800px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
@media only screen and (max-width: 1600px) {
|
||||
#GalleryDisplay img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@@ -838,11 +838,10 @@ div#EventDetail table.eventlist tbody tr td.ColumnDate {
|
||||
}
|
||||
#GalleryDisplay img {
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
@media only screen and (max-width: 1600px) {
|
||||
#GalleryDisplay img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@@ -524,11 +524,10 @@ table.eventlist tbody tr td.ColumnSources {
|
||||
margin: 0px auto;
|
||||
display: block;
|
||||
border: solid 1px #7C8F7C;
|
||||
max-width: 800px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
@media only screen and (max-width: 1600px) {
|
||||
#GalleryDisplay img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@@ -512,15 +512,15 @@ table.eventlist tbody tr td.ColumnSources {
|
||||
margin: 0px auto;
|
||||
display: block;
|
||||
border: solid 1px #669;
|
||||
max-width: 800px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
@media only screen and (max-width: 1600px) {
|
||||
#GalleryDisplay img {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#GalleryDetail h3 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -512,11 +512,10 @@ table.eventlist tbody tr td.ColumnSources {
|
||||
margin: 0px auto;
|
||||
display: block;
|
||||
border: solid 1px #EA8414;
|
||||
max-width: 800px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
@media only screen and (max-width: 1600px) {
|
||||
#GalleryDisplay img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@@ -513,11 +513,10 @@ table.eventlist tbody tr td.ColumnSources {
|
||||
margin: 0px auto;
|
||||
display: block;
|
||||
border: solid 1px #7CA3DD;
|
||||
max-width: 800px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
@media only screen and (max-width: 1600px) {
|
||||
#GalleryDisplay img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
+13
-5
@@ -71,9 +71,7 @@ body {
|
||||
body > div {
|
||||
width: 85%;
|
||||
margin: 0px auto;
|
||||
background: url(../images/Web_Mainz_Mid.png) #FFF2C6 repeat;
|
||||
overflow: hidden;
|
||||
padding: 0px 1.5em;
|
||||
}
|
||||
#outerwrapper {
|
||||
margin: 5px auto;
|
||||
@@ -84,6 +82,8 @@ body > div {
|
||||
}
|
||||
.content {
|
||||
padding: 1.5em 1.5em;
|
||||
overflow: auto;
|
||||
background: url(../images/Web_Mainz_Mid.png) #FFF2C6 repeat;
|
||||
}
|
||||
#ThumbnailPreview div.snapshot {
|
||||
float: right;
|
||||
@@ -468,11 +468,10 @@ table.eventlist tbody tr td.ColumnSources {
|
||||
margin: 0px auto;
|
||||
display:block;
|
||||
border: solid 1px #7D5925;
|
||||
max-width: 800px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
@media only screen and (max-width: 1600px) {
|
||||
#GalleryDisplay img {
|
||||
max-width: 100%;
|
||||
}
|
||||
@@ -692,22 +691,31 @@ div.grampsstylednote p {
|
||||
-----------------------------------------------------------------*/
|
||||
#footer {
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
background: url(../images/Web_Mainz_MidLight.png) #FFF2C6;
|
||||
border-top: dashed 1px #7D5925;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
#footer p#createdate {
|
||||
float: left;
|
||||
width: 50%;
|
||||
text-align: left;
|
||||
margin-left: 10px;
|
||||
}
|
||||
#footer p#copyright {
|
||||
float: right;
|
||||
width: 40%;
|
||||
text-align: right;
|
||||
}
|
||||
#footer p#copyright img {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#footer > * {
|
||||
font-size: 80%;
|
||||
background: url(../images/Web_Mainz_MidLight.png) #FFF2C6;
|
||||
}
|
||||
|
||||
/* Overwritten
|
||||
|
||||
@@ -747,11 +747,10 @@ table.eventlist tbody tr td.ColumnSources {
|
||||
}
|
||||
#GalleryDisplay img {
|
||||
margin:0 auto;
|
||||
max-width: 800px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
@media only screen and (max-width: 1600px) {
|
||||
#GalleryDisplay img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
+66
-41
@@ -9,7 +9,7 @@
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
@@ -20,10 +20,10 @@
|
||||
#
|
||||
# $Id: $
|
||||
#
|
||||
**************************************************************************************************
|
||||
*******************************************************************************
|
||||
GRAMPS Cascading Style Sheet
|
||||
Style Name: Combined Ancestor Tree Style Sheet
|
||||
***************************************************************************************************
|
||||
*******************************************************************************
|
||||
#
|
||||
===== Ancestor Graph Color Scheme =====
|
||||
Males #BCEAF6
|
||||
@@ -33,10 +33,8 @@ Unknown #000
|
||||
===== Web Graphics =====
|
||||
Males Web_Gender_Male.png
|
||||
Females Web_Gender_Female.png
|
||||
# ------------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* Subsections : Ancestors Tree
|
||||
----------------------------------------------------- */
|
||||
# -------------------------------------------------------------------------- #
|
||||
/* Subsections : Ancestors Tree -------------------------------------------- */
|
||||
#tree {
|
||||
page-break-before:always;
|
||||
margin:0;
|
||||
@@ -52,8 +50,8 @@ Females Web_Gender_Female.png
|
||||
}
|
||||
#treeContainer div.boxbg {
|
||||
position:absolute;
|
||||
margin:0;
|
||||
padding:0;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
background:none;
|
||||
}
|
||||
#treeContainer div.boxbg a,
|
||||
@@ -61,41 +59,43 @@ Females Web_Gender_Female.png
|
||||
position:relative;
|
||||
z-index:10;
|
||||
display:block;
|
||||
font:normal .7em/1.4em sans-serif;
|
||||
font:normal 1.1em/1.4em sans-serif;
|
||||
text-align:center;
|
||||
word-break:break-word;
|
||||
word-wrap:break-word;
|
||||
text-decoration:none;
|
||||
color: #00029D;
|
||||
width:118px;
|
||||
padding:5px 20px 7px 20px;
|
||||
width:280px;
|
||||
min-height: 70px;
|
||||
margin-left:16px;
|
||||
background-color: #FFF;
|
||||
border: solid 1px #000;
|
||||
border: solid 2px #000;
|
||||
border-radius: 10px;
|
||||
}
|
||||
#treeContainer div.boxbg a.noThumb,
|
||||
#treeContainer div.AncCol3 a,
|
||||
#treeContainer div.AncCol4 a,
|
||||
#treeContainer div.AncCol3 span.unlinked,
|
||||
#treeContainer div.AncCol4 a,
|
||||
#treeContainer div.AncCol4 span.unlinked {
|
||||
margin-top:10px;
|
||||
float: right;
|
||||
}
|
||||
#treeContainer div.boxbg a:hover {
|
||||
position:relative;
|
||||
z-index:999;
|
||||
font-size:1em;
|
||||
font-size:1.3em;
|
||||
word-break:break-word;
|
||||
word-wrap:break-word;
|
||||
text-decoration:none;
|
||||
color: #00029D;
|
||||
width:190px;
|
||||
width:400px;
|
||||
margin-left:-20px;
|
||||
padding:10px 25px 12px 25px;
|
||||
border: solid 2px #000;
|
||||
padding: 0px 0px 0px 40px;
|
||||
}
|
||||
#treeContainer div.boxbg a:hover,
|
||||
#treeContainer div.AncCol3 a:hover,
|
||||
#treeContainer div.boxbg a:hover,
|
||||
#treeContainer div.AncCol4 a:hover {
|
||||
margin-top:-44px;
|
||||
}
|
||||
#treeContainer div.boxbg a.noThumb:hover {
|
||||
margin-top:0;
|
||||
padding-left: 10px;
|
||||
}
|
||||
#treeContainer div.AncCol0 a:hover {
|
||||
margin-left:12px;
|
||||
@@ -105,48 +105,73 @@ Females Web_Gender_Female.png
|
||||
}
|
||||
#treeContainer div.boxbg span.thumbnail {
|
||||
display:block;
|
||||
max-width:80px;
|
||||
max-height:65px;
|
||||
margin:0 auto;
|
||||
padding:4px 0;
|
||||
position: absolute;
|
||||
max-width:85px;
|
||||
max-height:75px;
|
||||
left: 3px;
|
||||
top: 3px;
|
||||
}
|
||||
#treeContainer div.boxbg span.thumbnail img {
|
||||
max-width:80px;
|
||||
max-height:65px;
|
||||
margin:0 auto;
|
||||
#treeContainer div.boxbg a.thumbnail table td.img {
|
||||
padding-right: 5px;
|
||||
}
|
||||
#treeContainer div.boxbg a:hover span.thumbnail, #treeContainer div.boxbg a:hover span.thumbnail img {
|
||||
height:80px;
|
||||
#treeContainer div.boxbg a.thumbnail:hover table td.img {
|
||||
padding-right: 9px;
|
||||
}
|
||||
#treeContainer div.AncCol3 span.thumbnail, #treeContainer div.AncCol4 span.thumbnail {
|
||||
#treeContainer div.boxbg a.thumbnail table td.name {
|
||||
padding-top:3px;
|
||||
padding-left: 2px;
|
||||
padding-right: 23px;
|
||||
width: 90%;
|
||||
}
|
||||
#treeContainer div.boxbg a.thumbnail img {
|
||||
margin-left:0px;
|
||||
padding-left: 0px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
#treeContainer div.boxbg a.thumbnail:hover img {
|
||||
max-height:90%;
|
||||
margin-left:5px;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 4px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
#treeContainer div.boxbg table td:first-child, table th:first-child {
|
||||
padding-left: 5px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
#IndividualDetail div.subsection table tr td:first-child {
|
||||
padding-left: 5px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
#treeContainer #treeContainer div.AncCol4 span.thumbnail {
|
||||
display:none;
|
||||
}
|
||||
#treeContainer div.boxbg a:hover span.thumbnail {
|
||||
display:block;
|
||||
}
|
||||
|
||||
#treeContainer div.boxbg span.fullname {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#treeContainer div.boxbg span.shortname {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#treeContainer div.boxbg a:hover span.fullname {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#treeContainer div.boxbg a:hover span.shortname {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
#treeContainer div.boxbg a:hover {
|
||||
float: right;
|
||||
margin-top: 10px;
|
||||
border: solid 4px #000;
|
||||
}
|
||||
#treeContainer div.male a,
|
||||
#treeContainer div.male span.unlinked {
|
||||
background:url(../images/Web_Gender_Male.png) #BCEAF6 no-repeat top right;
|
||||
}
|
||||
#treeContainer div.female a,
|
||||
#treeContainer div.female a,
|
||||
#treeContainer div.female span.unlinked {
|
||||
background:url(../images/Web_Gender_Female.png) #FFC0CB no-repeat top right;
|
||||
}
|
||||
|
||||
@@ -66,3 +66,48 @@ div#FamilyMapDetail div#references table.infolist {
|
||||
div#FamilyMapDetail div#references table.infolist tbody tr td.ColumnPlace {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
|
||||
/* Subsection: popup
|
||||
------------------------------------------------------ */
|
||||
.ol-popup {
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
-webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
|
||||
filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
border: 2px solid #111111;
|
||||
bottom: 12px;
|
||||
left: -50px;
|
||||
min-width: 450px;
|
||||
}
|
||||
.ol-popup:after, .ol-popup:before {
|
||||
top: 100%;
|
||||
border: solid transparent;
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
.ol-popup:after {
|
||||
border-top-color: white;
|
||||
border-width: 10px;
|
||||
left: 48px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
.ol-popup:before {
|
||||
border-top-color: #cccccc;
|
||||
border-width: 11px;
|
||||
left: 48px;
|
||||
margin-left: -11px;
|
||||
}
|
||||
.ol-popup-closer {
|
||||
text-decoration: none;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 8px;
|
||||
}
|
||||
.ol-popup-closer:after {
|
||||
content: "✖";
|
||||
}
|
||||
|
||||
@@ -9,6 +9,12 @@ beg
|
||||
- h Hans_Peter.8 17/4/1904 #bp Rønne,_Bornholm,_Denmark 29/1/1977 #dp San_Francisco,_San_Francisco_Co.,_CA
|
||||
end
|
||||
|
||||
notes Hansdotter Anna.1
|
||||
beg
|
||||
******************************************************************890123456789
|
||||
******************************************************************89 123456789
|
||||
end notes
|
||||
|
||||
notes Smith Hjalmar.5
|
||||
beg
|
||||
BIOGRAPHY
|
||||
@@ -61,7 +67,7 @@ Some Bold Unicode Characters: ࣶǼЀج⿄㑝㵋
|
||||
Some Italic Unicode Characters: ࣶǼЀج⿄㑝㵋圛墉幵聟聦𐅉🚶🛈
|
||||
end notes
|
||||
|
||||
fam Smith Gus.6 +~1920 Michaels Evelyn.25 ~1897
|
||||
fam Smith Gus.6 +~1920 Michaels Evelyn.25 ~1897 0
|
||||
|
||||
fam Smith Hjalmar.5 +31/10/1927 #mp Reno,_Washoe_Co.,_NV Ohman Marjorie.26 3/6/1903 #bp Denver,_Denver_Co.,_CO,_Denver_Co.,_Colorado,_USA 22/6/1980 #dp Reno,_Washoe_Co.,_NV
|
||||
beg
|
||||
@@ -98,13 +104,18 @@ beg
|
||||
- h Martin.17 1794..1796 #bp Tommarp,_Kristianstad_Län,_Sweden #dp Sweden
|
||||
end
|
||||
|
||||
fam Willard Edwin.42 ~1886 +~1910 Smith Kirsti_Marie.2
|
||||
fam Willard Edwin.42 ~1886 0 +~1910 Smith Kirsti_Marie.2
|
||||
|
||||
fam Smith Magnes.38 +24/8/1884 #mp Rønne,_Bornholm,_Denmark Streiffert Anna.43 23/9/1860 #bp Hoya/Jona/Hoia,_Sweden 2/2/1927 #dp Rønne,_Bornholm,_Denmark
|
||||
|
||||
fam Tester The.14 + Tester Mrs.44 0
|
||||
beg
|
||||
- h Tom.45 0
|
||||
- h Tom.45 Von_Tester_y_tested 0
|
||||
- Fake.46 von_Person 1954 #bp Fremont,_Alameda_Co.,_CA
|
||||
- f Mary.47 0
|
||||
- f Martha.48 0
|
||||
- h John.49 0
|
||||
- h Mark.50 0
|
||||
end
|
||||
|
||||
notes Tester Mrs.44
|
||||
|
||||
+315
-655
File diff suppressed because it is too large
Load Diff
+52
-47
@@ -1,47 +1,52 @@
|
||||
Anna Hansdotter;;;;;2/10/1864-29/9/1945
|
||||
Keith Lloyd Smith;Lloyd Smith;Janis Green;;;11/8/1966
|
||||
Hans Peter Smith;Gustaf Smith;Anna Hansdotter;;;17/4/1904-29/1/1977
|
||||
Hanna Smith;Martin Smith0;Elna Jefferson;;;29/1/1821
|
||||
Herman Julius Nielsen;;;;;31/8/1889-1945
|
||||
Evelyn Michaels;;;;;1897
|
||||
Marjorie Lee Smith;Hjalmar Smith0;Marjorie Ohman;;;4/11/1934
|
||||
Gus Smith;Gustaf Smith;Anna Hansdotter;;;11/9/1897-21/10/1963
|
||||
Jennifer Anderson;;;;;5/11/1907-29/5/1985
|
||||
Lillie Harriet Jones;;;;;2/5/1910-26/6/1990
|
||||
John Hjalmar Smith;Hjalmar Smith0;Marjorie Ohman;;;30/1/1932
|
||||
Eric Lloyd Smith;Lloyd Smith;Janis Green;;;28/8/1963
|
||||
Amber Marie Smith;Edwin Smith;Janice Adams;;;12/4/1998
|
||||
Carl Emil Smith;Gustaf Smith;Anna Hansdotter;;;20/12/1899-28/1/1959
|
||||
Hjalmar Smith;Gustaf Smith;Anna Hansdotter;;;31/1/1893-25/9/1894
|
||||
Martin Smith;Martin Smith0;Elna Jefferson;;;19/11/1830-1899
|
||||
Astrid Shermanna Augusta Smith;Gustaf Smith;Anna Hansdotter;;;31/1/1889-21/12/1963
|
||||
Gustaf Smith, Sr.;Martin Smith;Kerstina Hansdotter;;;28/11/1862-23/7/1930
|
||||
Marta Ericsdotter;;;;;1775
|
||||
Kirsti Marie Smith;Gustaf Smith;Anna Hansdotter;;;15/12/1886-18/7/1966
|
||||
Ingeman Smith;;;;;1770
|
||||
Anna Streiffert;;;;;23/9/1860-2/2/1927
|
||||
Craig Peter Smith;Lloyd Smith;Janis Green;;;1966
|
||||
Magnes Smith;Martin Smith;Kerstina Hansdotter;;;6/10/1858-20/2/1910
|
||||
Janice Ann Adams;;;;;26/8/1965
|
||||
Marjorie Ohman;;;;;3/6/1903-22/6/1980
|
||||
Darcy Horne;;;;;2/7/1966
|
||||
Alice Paula Perkins;;;;;22/11/1933
|
||||
Lars Peter Smith;Eric Smith;Darcy Horne;;;16/9/1991
|
||||
Ingeman Smith0;Martin Smith0;Elna Jefferson;;;29/1/1826
|
||||
Lloyd Smith;Hans Smith;Lillie Jones;;;13/3/1935
|
||||
Elna Jefferson;;;;;14/9/1800-
|
||||
Edwin Michael Smith;John Smith;Alice Perkins;;;24/5/1961
|
||||
Kerstina Hansdotter;;;;;29/11/1832-1908
|
||||
Martin Smith0;Ingeman Smith;Marta Ericsdotter;;;1794-
|
||||
Marjorie Alice Smith0;John Smith;Alice Perkins;;;5/2/1960
|
||||
Janis Elaine Green;;;;;2/12/1935
|
||||
Mason Michael Smith;Edwin Smith;Janice Adams;;;26/6/1996
|
||||
Edwin Willard;;;;;1886
|
||||
Ingar Smith;Martin Smith0;Elna Jefferson;;;1823
|
||||
Hjalmar Smith0;Gustaf Smith;Anna Hansdotter;;;7/4/1895-26/6/1975
|
||||
Emil Smith;Martin Smith;Kerstina Hansdotter;;;27/9/1860
|
||||
雪 Ke 柯;Herman Nielsen;Astrid Smith;;;
|
||||
The Tester;Lloyd Smith;Janis Green;;;29/12/1954
|
||||
Mrs Tester;;;;;
|
||||
ピーター リチミシキスイミ;;;;;
|
||||
Tom Tester;The Tester;Mrs Tester;;;
|
||||
Anna Hansdotter;;;;;2/10/1864-29/9/1945
|
||||
Keith Lloyd Smith;Lloyd Smith;Janis Green;;;11/8/1966
|
||||
Hans Peter Smith;Gustaf Smith;Anna Hansdotter;;;17/4/1904-29/1/1977
|
||||
Hanna Smith;Martin Smith0;Elna Jefferson;;;29/1/1821
|
||||
Herman Julius Nielsen;;;;;31/8/1889-1945
|
||||
Evelyn Michaels;;;;;1897
|
||||
Marjorie Lee Smith;Hjalmar Smith0;Marjorie Ohman;;;4/11/1934
|
||||
Gus Smith;Gustaf Smith;Anna Hansdotter;;;11/9/1897-21/10/1963
|
||||
Jennifer Anderson;;;;;5/11/1907-29/5/1985
|
||||
Lillie Harriet Jones;;;;;2/5/1910-26/6/1990
|
||||
John Hjalmar Smith;Hjalmar Smith0;Marjorie Ohman;;;30/1/1932
|
||||
Eric Lloyd Smith;Lloyd Smith;Janis Green;;;28/8/1963
|
||||
Amber Marie Smith;Edwin Smith;Janice Adams;;;12/4/1998
|
||||
Carl Emil Smith;Gustaf Smith;Anna Hansdotter;;;20/12/1899-28/1/1959
|
||||
Hjalmar Smith;Gustaf Smith;Anna Hansdotter;;;31/1/1893-25/9/1894
|
||||
Martin Smith;Martin Smith0;Elna Jefferson;;;19/11/1830-1899
|
||||
Astrid Shermanna Augusta Smith;Gustaf Smith;Anna Hansdotter;;;31/1/1889-21/12/1963
|
||||
Gustaf Smith, Sr.;Martin Smith;Kerstina Hansdotter;;;28/11/1862-23/7/1930
|
||||
Marta Ericsdotter;;;;;1775
|
||||
Kirsti Marie Smith;Gustaf Smith;Anna Hansdotter;;;15/12/1886-18/7/1966
|
||||
Ingeman Smith;;;;;1770
|
||||
Anna Streiffert;;;;;23/9/1860-2/2/1927
|
||||
Craig Peter Smith;Lloyd Smith;Janis Green;;;1966
|
||||
Magnes Smith;Martin Smith;Kerstina Hansdotter;;;6/10/1858-20/2/1910
|
||||
Janice Ann Adams;;;;;26/8/1965
|
||||
Marjorie Ohman;;;;;3/6/1903-22/6/1980
|
||||
Darcy Horne;;;;;2/7/1966
|
||||
Lloyd Smith;Hans Smith;Lillie Jones;;;13/3/1935
|
||||
Alice Paula Perkins;;;;;22/11/1933
|
||||
Lars Peter Smith;Eric Smith;Darcy Horne;;;16/9/1991
|
||||
Elna Jefferson;;;;;14/9/1800-
|
||||
Edwin Michael Smith;John Smith;Alice Perkins;;;24/5/1961
|
||||
Kerstina Hansdotter;;;;;29/11/1832-1908
|
||||
Martin Smith0;Ingeman Smith;Marta Ericsdotter;;;1794-
|
||||
Ingeman Smith0;Martin Smith0;Elna Jefferson;;;29/1/1826
|
||||
Marjorie Alice Smith0;John Smith;Alice Perkins;;;5/2/1960
|
||||
Janis Elaine Green;;;;;2/12/1935
|
||||
Mason Michael Smith;Edwin Smith;Janice Adams;;;26/6/1996
|
||||
Edwin Willard;;;;;1886
|
||||
Ingar Smith;Martin Smith0;Elna Jefferson;;;1823
|
||||
Hjalmar Smith0;Gustaf Smith;Anna Hansdotter;;;7/4/1895-26/6/1975
|
||||
Emil Smith;Martin Smith;Kerstina Hansdotter;;;27/9/1860
|
||||
雪 Ke 柯;Herman Nielsen;Astrid Smith;;;
|
||||
ピーター リチミシキスイミ;;;;;
|
||||
The Tester;Lloyd Smith;Janis Green;;;29/12/1954
|
||||
Mrs Tester;;;;;
|
||||
Tom Von Tester y tested;The Tester;Mrs Tester;;;
|
||||
Fake von Person, I;The Tester;Mrs Tester;;;1954-
|
||||
Mary Tester;The Tester;Mrs Tester;;;
|
||||
Martha Tester;The Tester;Mrs Tester;;;
|
||||
John Tester;The Tester;Mrs Tester;;;
|
||||
Mark Tester;The Tester;Mrs Tester;;;
|
||||
|
||||
@@ -30,66 +30,65 @@
|
||||
[P0014],"Denver, Denver Co., CO","Denver, Denver Co., CO",City,39.7392,104.9903 W,,[P0024],
|
||||
|
||||
Person,Surname,Given,Call,Suffix,Prefix,Title,Gender,Birth date,Birth place,Birth source,Baptism date,Baptism place,Baptism source,Death date,Death place,Death source,Burial date,Burial place,Burial source,Note
|
||||
[I0030],Adams,Janice Ann,,,,,female,26 Aug 1965,"Fremont, Alameda Co., CA",,,,,,,,,,,
|
||||
[I0016],Anderson,Jennifer,,,,,female,5 Nov 1907,"Rønne, Bornholm, Denmark",,,,,29 May 1985,"San Francisco, San Francisco Co., CA",,,,,
|
||||
[I0025],Ericsdotter,Marta,,,,,female,about 1775,Sweden,,,,,,,,,,,
|
||||
[I0041],Green,Janis Elaine,,,,,female,2 Dec 1935,,,,,,,,,,,,
|
||||
[I0000],Hansdotter,Anna,,,,,female,2 Oct 1864,"Löderup, Malmöhus Län, Sweden",,,,,29 Sep 1945,"Sparks, Washoe Co., NV",,,,,
|
||||
[I0038],Hansdotter,Kerstina,,,,,female,29 Nov 1832,"Smestorp, Kristianstad Län, Sweden",,,,,before 1908,Sweden,,,,,
|
||||
[I0032],Horne,Darcy,,,,,female,2 Jul 1966,"Sacramento, Sacramento Co., CA",,,,,,,,,,,
|
||||
[I0036],Jefferson,Elna,,,,,female,14 Sep 1800,"Gladsax, Kristianstad Län, Sweden",,,,,,Sweden,,,,,
|
||||
[I0017],Jones,Lillie Harriet,,,,,female,2 May 1910,"Rønne, Bornholm, Denmark",,,,,26 Jun 1990,,,,,,
|
||||
[I0030],Adams,Janice Ann,,,,,female,1965-08-26,[P0013],,,,,,,,,,,
|
||||
[I0016],Anderson,Jennifer,,,,,female,1907-11-05,[P0003],,,,,1985-05-29,[P0002],,,,,
|
||||
[I0025],Ericsdotter,Marta,,,,,female,about 1775,[P0008],,,,,,,,,,,
|
||||
[I0041],Green,Janis Elaine,,,,,female,1935-12-02,,,,,,,,,,,,
|
||||
[I0000],Hansdotter,Anna,,,,,female,1864-10-02,[P0000],,,,,1945-09-29,[P0001],,,,,
|
||||
[I0038],Hansdotter,Kerstina,,,,,female,1832-11-29,[P0019],,,,,before 1908,[P0008],,,,,
|
||||
[I0032],Horne,Darcy,,,,,female,1966-07-02,[P0015],,,,,,,,,,,
|
||||
[I0036],Jefferson,Elna,,,,,female,1800-09-14,[P0004],,,,,,[P0008],,,,,
|
||||
[I0017],Jones,Lillie Harriet,,,,,female,1910-05-02,[P0003],,,,,1990-06-26,,,,,,
|
||||
[I0042],Ke 柯,雪,,,,,male,,,,,,,,,,,,,
|
||||
[I0013],Michaels,Evelyn,,,,,female,about 1897,,,,,,,,,,,,
|
||||
[I0012],Nielsen,Herman Julius,,,,,male,31 Aug 1889,"Rønne, Bornholm, Denmark",,,,,1945,,,,,,
|
||||
[I0031],Ohman,Marjorie,,,,,female,3 Jun 1903,"Denver, Denver Co., CO, Denver Co., Colorado, USA",,,,,22 Jun 1980,"Reno, Washoe Co., NV",,,,,
|
||||
[I0034],Perkins,Alice Paula,,,,,female,22 Nov 1933,"Sparks, Washoe Co., NV",,,,,,,,,,,
|
||||
[I0002],Smith,Amber Marie,,,,,female,12 Apr 1998,"Hayward, Alameda Co., CA",,,,,,,,,,,
|
||||
[I0023],Smith,Astrid Shermanna Augusta,,,,,female,31 Jan 1889,"Rønne, Bornholm, Denmark",,,,,21 Dec 1963,"San Francisco, San Francisco Co., CA",,,,,
|
||||
[I0020],Smith,Carl Emil,,,,,male,20 Dec 1899,"Rønne, Bornholm, Denmark",,,,,28 Jan 1959,"Reno, Washoe Co., NV",,,,,
|
||||
[I0029],Smith,Craig Peter,,,,,male,after 1966,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
|
||||
[I0037],Smith,Edwin Michael,,,,,male,24 May 1961,"San Jose, Santa Clara Co., CA","Birth, Death and Marriage Records",,,,,,,,,,
|
||||
[I0009],Smith,Emil,,,,,male,27 Sep 1860,"Simrishamn, Kristianstad Län, Sweden",,,,,,,,,,,
|
||||
[I0019],Smith,Eric Lloyd,,,,Dr.,male,28 Aug 1963,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
|
||||
[I0015],Smith,Gus,,,,,male,11 Sep 1897,"Rønne, Bornholm, Denmark",,,,,21 Oct 1963,"San Francisco, San Francisco Co., CA",,,,,
|
||||
[I0024],Smith,Gustaf,,Sr.,,,male,28 Nov 1862,"Grostorp, Kristianstad Län, Sweden",,,,,before 23 Jul 1930,"Sparks, Washoe Co., NV",,,,,
|
||||
[I0011],Smith,Hanna,,,,,female,29 Jan 1821,"Gladsax, Kristianstad Län, Sweden",,,,,,,,,,,
|
||||
[I0010],Smith,Hans Peter,,,,,male,17 Apr 1904,"Rønne, Bornholm, Denmark",Birth Records,,,,29 Jan 1977,"San Francisco, San Francisco Co., CA",,5 Feb 1977,"San Francisco, San Francisco Co., CA",findagrave.com,
|
||||
[I0021],Smith,Hjalmar,,,,,male,31 Jan 1893,"Rønne, Bornholm, Denmark",,,,,25 Sep 1894,"Rønne, Bornholm, Denmark",,,,,
|
||||
[I0008],Smith,Hjalmar,,,,,male,7 Apr 1895,"Rønne, Bornholm, Denmark",,3 Jun 1895,"Rønne Bornholm, Denmark",,26 Jun 1975,"Reno, Washoe Co., NV",,,,,
|
||||
[I0007],Smith,Ingar,,,,,female,after 1823,"Gladsax, Kristianstad Län, Sweden",,,,,,,,,,,
|
||||
[I0027],Smith,Ingeman,,,,,male,about 1770,Sweden,,,,,,,,,,,
|
||||
[I0004],Smith,Ingeman,,,,,male,29 Jan 1826,"Gladsax, Kristianstad Län, Sweden",,,,,,,,,,,
|
||||
[I0018],Smith,John Hjalmar,,,,,male,30 Jan 1932,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
|
||||
[I0001],Smith,Keith Lloyd,,,,,male,11 Aug 1966,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
|
||||
[I0026],Smith,Kirsti Marie,,,,,female,15 Dec 1886,"Rønne, Bornholm, Denmark",,,,,18 Jul 1966,"San Francisco, San Francisco Co., CA",,,,,
|
||||
[I0035],Smith,Lars Peter,,,,,male,16 Sep 1991,"Santa Rosa, Sonoma Co., CA",,,,,,,,,,,
|
||||
[I0033],Smith,Lloyd,,,,,male,13 Mar 1935,"San Francisco, San Francisco Co., CA",,,,,,,,,,,
|
||||
[I0003],Smith,Magnes,,,,,male,6 Oct 1858,"Simrishamn, Kristianstad Län, Sweden",,,,,20 Feb 1910,"Rønne, Bornholm, Denmark",,,,,
|
||||
[I0040],Smith,Marjorie Alice,,,,,female,5 Feb 1960,"San Jose, Santa Clara Co., CA",,,,,,,,,,,
|
||||
[I0014],Smith,Marjorie Lee,,,,,female,4 Nov 1934,"Reno, Washoe Co., NV",,,,,,,,,,,
|
||||
[I0022],Smith,Martin,,,,,male,19 Nov 1830,"Gladsax, Kristianstad Län, Sweden",,23 Nov 1830,"Gladsax, Kristianstad Län, Sweden",,between 1899 and 1905,Sweden,,,,,
|
||||
[I0039],Smith,Martin,,,,,male,between 1794 and 1796,"Tommarp, Kristianstad Län, Sweden",,,,,,Sweden,,,,,
|
||||
[I0005],Smith,Mason Michael,,,,,male,26 Jun 1996,"Hayward, Alameda Co., CA",,,,,,,,,,,
|
||||
[I0028],Streiffert,Anna,,,,,female,23 Sep 1860,"Hoya/Jona/Hoia, Sweden",,,,,2 Feb 1927,"Rønne, Bornholm, Denmark",,,,,
|
||||
[I0012],Nielsen,Herman Julius,,,,,male,1889-08-31,[P0003],,,,,1945,,,,,,
|
||||
[I0031],Ohman,Marjorie,,,,,female,1903-06-03,[P0014],,,,,1980-06-22,[P0005],,,,,
|
||||
[I0034],Perkins,Alice Paula,,,,,female,1933-11-22,[P0001],,,,,,,,,,,
|
||||
[I0002],Smith,Amber Marie,,,,,female,1998-04-12,[P0006],,,,,,,,,,,
|
||||
[I0023],Smith,Astrid Shermanna Augusta,,,,,female,1889-01-31,[P0003],,,,,1963-12-21,[P0002],,,,,
|
||||
[I0020],Smith,Carl Emil,,,,,male,1899-12-20,[P0003],,,,,1959-01-28,[P0005],,,,,
|
||||
[I0029],Smith,Craig Peter,,,,,male,after 1966,[P0002],,,,,,,,,,,
|
||||
[I0037],Smith,Edwin Michael,,,,,male,1961-05-24,[P0017],"Birth, Death and Marriage Records",,,,,,,,,,
|
||||
[I0009],Smith,Emil,,,,,male,1860-09-27,[P0012],,,,,,,,,,,
|
||||
[I0019],Smith,Eric Lloyd,,,,Dr.,male,1963-08-28,[P0002],,,,,,,,,,,
|
||||
[I0015],Smith,Gus,,,,,male,1897-09-11,[P0003],,,,,1963-10-21,[P0002],,,,,
|
||||
[I0024],Smith,Gustaf,,Sr.,,,male,1862-11-28,[P0009],,,,,before 1930-07-23,[P0001],,,,,
|
||||
[I0011],Smith,Hanna,,,,,female,1821-01-29,[P0004],,,,,,,,,,,
|
||||
[I0010],Smith,Hans Peter,,,,,male,1904-04-17,[P0003],Birth Records,,,,1977-01-29,[P0002],,1977-02-05,[P0002],findagrave.com,
|
||||
[I0021],Smith,Hjalmar,,,,,male,1893-01-31,[P0003],,,,,1894-09-25,[P0003],,,,,
|
||||
[I0008],Smith,Hjalmar,,,,,male,1895-04-07,[P0003],,1895-06-03,[P0021],,1975-06-26,[P0005],,,,,
|
||||
[I0007],Smith,Ingar,,,,,female,after 1823,[P0004],,,,,,,,,,,
|
||||
[I0027],Smith,Ingeman,,,,,male,about 1770,[P0008],,,,,,,,,,,
|
||||
[I0004],Smith,Ingeman,,,,,male,1826-01-29,[P0004],,,,,,,,,,,
|
||||
[I0018],Smith,John Hjalmar,,,,,male,1932-01-30,[P0002],,,,,,,,,,,
|
||||
[I0001],Smith,Keith Lloyd,,,,,male,1966-08-11,[P0002],,,,,,,,,,,
|
||||
[I0026],Smith,Kirsti Marie,,,,,female,1886-12-15,[P0003],,,,,1966-07-18,[P0002],,,,,
|
||||
[I0035],Smith,Lars Peter,,,,,male,1991-09-16,[P0016],,,,,,,,,,,
|
||||
[I0033],Smith,Lloyd,,,,,male,1935-03-13,[P0002],,,,,,,,,,,
|
||||
[I0003],Smith,Magnes,,,,,male,1858-10-06,[P0012],,,,,1910-02-20,[P0003],,,,,
|
||||
[I0040],Smith,Marjorie Alice,,,,,female,1960-02-05,[P0017],,,,,,,,,,,
|
||||
[I0014],Smith,Marjorie Lee,,,,,female,1934-11-04,[P0005],,,,,,,,,,,
|
||||
[I0022],Smith,Martin,,,,,male,1830-11-19,[P0004],,1830-11-23,[P0004],,between 1899 and 1905,[P0008],,,,,
|
||||
[I0039],Smith,Martin,,,,,male,between 1794 and 1796,[P0020],,,,,,[P0008],,,,,
|
||||
[I0005],Smith,Mason Michael,,,,,male,1996-06-26,[P0006],,,,,,,,,,,
|
||||
[I0028],Streiffert,Anna,,,,,female,1860-09-23,[P0011],,,,,1927-02-02,[P0003],,,,,
|
||||
[I0006],Willard,Edwin,,,,,male,about 1886,,,,,,,,,,,,
|
||||
[I0043],リチミシキスイミ,ピーター,,,,,male,,,,,,,,,,,,,
|
||||
|
||||
Marriage,Husband,Wife,Date,Place,Source,Note
|
||||
[F0000],[I0039],[I0036],about 1816,"Gladsax, Kristianstad Län, Sweden",,
|
||||
[F0001],[I0027],[I0025],about 1790,Sweden,,
|
||||
[F0000],[I0039],[I0036],about 1816,[P0004],,
|
||||
[F0001],[I0027],[I0025],about 1790,[P0008],,
|
||||
[F0002],[I0022],[I0038],about 1856,,,
|
||||
[F0003],[I0024],[I0000],27 Nov 1885,"Rønne, Bornholm, Denmark",,
|
||||
[F0003],[I0024],[I0000],1885-11-27,[P0003],,
|
||||
[F0004],[I0006],[I0026],about 1910,,,
|
||||
[F0005],[I0012],[I0023],30 Nov 1912,"Rønne, Bornholm, Denmark",,
|
||||
[F0006],[I0008],[I0031],31 Oct 1927,"Reno, Washoe Co., NV",,
|
||||
[F0005],[I0012],[I0023],1912-11-30,[P0003],,
|
||||
[F0006],[I0008],[I0031],1927-10-31,[P0005],,
|
||||
[F0007],[I0015],[I0013],about 1920,,,
|
||||
[F0008],[I0033],[I0041],10 Aug 1958,"San Francisco, San Francisco Co., CA",,
|
||||
[F0008],[I0033],[I0041],1958-08-10,[P0002],,
|
||||
[F0009],[I0010],[I0017],,,,
|
||||
[F0010],[I0019],[I0032],12 Jul 1986,"Woodland, Yolo Co., CA",,
|
||||
[F0011],[I0003],[I0028],24 Aug 1884,"Rønne, Bornholm, Denmark",,
|
||||
[F0012],[I0018],[I0034],4 Jun 1954,"Sparks, Washoe Co., NV",Marriage Certificae,
|
||||
[F0013],[I0037],[I0030],27 May 1995,"San Ramon, Conta Costa Co., CA",,
|
||||
[F0010],[I0019],[I0032],1986-07-12,[P0022],,
|
||||
[F0011],[I0003],[I0028],1884-08-24,[P0003],,
|
||||
[F0012],[I0018],[I0034],1954-06-04,[P0001],Marriage Certificae,
|
||||
[F0013],[I0037],[I0030],1995-05-27,[P0023],,
|
||||
[F0014],[I0010],[I0016],,,,
|
||||
|
||||
Family,Child
|
||||
|
||||
|
Vendored
+24
@@ -1,3 +1,27 @@
|
||||
gramps (5.1.1-1) unstable; urgency=medium
|
||||
|
||||
* New release
|
||||
* Add python3-fontconfig to recommends
|
||||
|
||||
-- Ross Gammon <rossgammon@debian.org> Tue, 17 Sep 2019 15:21:43 +0200
|
||||
|
||||
gramps (5.1.0-1) unstable; urgency=medium
|
||||
|
||||
* New release
|
||||
* Update copyrights
|
||||
* Bump gtk+ version to 3.12
|
||||
* Add new geocode-glib dependency
|
||||
|
||||
-- Ross Gammon <rossgammon@debian.org> Sat, 24 Aug 2019 19:49:27 +0200
|
||||
|
||||
gramps (5.0.2-1) unstable; urgency=medium
|
||||
|
||||
* New release
|
||||
* Remove ancient python version field from debian/control
|
||||
* Bump standards version, no changes required
|
||||
|
||||
-- Ross Gammon <rossgammon@debian.org> Sun, 11 Aug 2019 14:11:35 +0200
|
||||
|
||||
gramps (5.0.1-1) unstable; urgency=medium
|
||||
|
||||
* New release
|
||||
|
||||
Vendored
+5
-4
@@ -10,7 +10,7 @@ Build-Depends-Indep:
|
||||
python3-all,
|
||||
python3-setuptools,
|
||||
python3-nose,
|
||||
gir1.2-gtk-3.0 (>= 3.10.0),
|
||||
gir1.2-gtk-3.0 (>= 3.12.0),
|
||||
python3-gi (>= 3.12.0),
|
||||
python3-gi-cairo,
|
||||
python3-bsddb3,
|
||||
@@ -21,11 +21,10 @@ Build-Depends-Indep:
|
||||
python3-nose-exclude
|
||||
Build-Depends:
|
||||
debhelper (>= 11)
|
||||
Standards-Version: 4.1.3
|
||||
Standards-Version: 4.4.0
|
||||
Vcs-Git: https://github.com/gramps-project/gramps.git
|
||||
Vcs-browser: https://github.com/gramps-project/gramps/tree/maintenance/gramps50
|
||||
Homepage: https://www.gramps-project.org/
|
||||
X-Python3-Version: >= 3.2
|
||||
|
||||
Package: gramps
|
||||
Architecture: all
|
||||
@@ -42,7 +41,9 @@ Recommends:
|
||||
graphviz,
|
||||
gir1.2-gexiv2-0.10,
|
||||
gir1.2-osmgpsmap-1.0,
|
||||
python3-icu
|
||||
python3-icu,
|
||||
gir1.2-geocodeglib-1.0,
|
||||
python3-fontconfig
|
||||
Suggests:
|
||||
fonts-freefont-ttf,
|
||||
gir1.2-goocanvas-2.0,
|
||||
|
||||
Vendored
+8
-3
@@ -12,12 +12,12 @@ Copyright: 2000-2007, Alex Roitman
|
||||
2001-2017, Free Software Foundation, Inc.
|
||||
2001, Graham J. Williams
|
||||
2001, Jesper Zedlitz
|
||||
2001-2018, The Gramps Project
|
||||
2001-2019, The Gramps Project
|
||||
2002, Gary Shao
|
||||
2003-2006, Josiah Carlson
|
||||
2004-2006, Eero Tamminen
|
||||
2004-2013, Julio Sánchez
|
||||
2005-2017, Serge Noiraud
|
||||
2005-2019, Serge Noiraud
|
||||
2006-2012, Brian G. Matherly
|
||||
2006, 2008-2011, Kees Bakker
|
||||
2006-2008, Steve Hall
|
||||
@@ -81,12 +81,17 @@ Copyright: 2000-2007, Alex Roitman
|
||||
2015, Detlef Wolz
|
||||
2016, Allen Crider
|
||||
2016, DaAwesomeP
|
||||
2016-2017, Paul Culley
|
||||
2016-2018, Paul Culley
|
||||
2016, QuLogic
|
||||
2016, Tom Samstag
|
||||
2017, Jonathan Biegert
|
||||
2017, Mindaugas Baranauskas
|
||||
2017, Robert Carnell
|
||||
2018, Christophe aka khrys63
|
||||
2018, Paul D.Smith
|
||||
2018, Robin van der Vliet
|
||||
2018, Theo van Rijn
|
||||
2019, Matthias Kemmer
|
||||
License: GPL-2+
|
||||
|
||||
Files: debian/*
|
||||
|
||||
@@ -64,6 +64,7 @@ from gramps.gen.db.exceptions import (DbUpgradeRequiredError,
|
||||
from gramps.gen.plug import BasePluginManager
|
||||
from gramps.gen.utils.config import get_researcher
|
||||
from gramps.gen.recentfiles import recent_files
|
||||
from gramps.gen.filters import reload_custom_filters
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -279,7 +280,7 @@ class CLIManager:
|
||||
# Attempt to figure out the database title
|
||||
path = os.path.join(filename, "name.txt")
|
||||
try:
|
||||
with open(path) as ifile:
|
||||
with open(path, encoding='utf8') as ifile:
|
||||
title = ifile.readline().strip()
|
||||
except:
|
||||
title = filename
|
||||
@@ -373,6 +374,7 @@ def startcli(errors, argparser):
|
||||
|
||||
#load the plugins
|
||||
climanager.do_reg_plugins(dbstate, uistate=None)
|
||||
reload_custom_filters()
|
||||
# handle the arguments
|
||||
from .arghandler import ArgHandler
|
||||
handler = ArgHandler(dbstate, argparser, climanager)
|
||||
|
||||
@@ -88,9 +88,9 @@ def _convert_str_to_match_type(str_val, type_val):
|
||||
return str(str_val)
|
||||
|
||||
elif ret_type == int:
|
||||
if str_val.isdigit():
|
||||
try:
|
||||
return int(str_val)
|
||||
else:
|
||||
except ValueError:
|
||||
print("'%s' is not an integer number" % str_val)
|
||||
return 0
|
||||
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ sys.path.insert(0, ROOT_DIR)
|
||||
git_revision = get_git_revision(ROOT_DIR).replace('\n', '')
|
||||
if sys.platform == 'win32' and git_revision == "":
|
||||
git_revision = get_git_revision(os.path.split(ROOT_DIR)[1])
|
||||
#VERSION += git_revision
|
||||
VERSION += git_revision
|
||||
#VERSION += "-1"
|
||||
|
||||
#
|
||||
|
||||
@@ -290,7 +290,8 @@ class DateDisplayDE(DateDisplay):
|
||||
|
||||
formats = (
|
||||
"JJJJ-MM-DD (ISO)", "Numerisch", "Monat Tag Jahr",
|
||||
"MONAT Tag Jahr", "Tag. Monat Jahr", "Tag. MONAT Jahr"
|
||||
"MONAT Tag Jahr", "Tag. Monat Jahr", "Tag. MONAT Jahr",
|
||||
"Numerisch mit führenden Nullen"
|
||||
)
|
||||
# this definition must agree with its "_display_gregorian" method
|
||||
|
||||
@@ -343,6 +344,18 @@ class DateDisplayDE(DateDisplay):
|
||||
else:
|
||||
value = "%d. %s %s" % (date_val[0],
|
||||
self.long_months[date_val[1]], year)
|
||||
elif self.format == 6:
|
||||
# day.month_number.year with leading zeros
|
||||
if date_val[3]:
|
||||
return self.display_iso(date_val)
|
||||
else:
|
||||
if date_val[0] == date_val[1] == 0:
|
||||
value = str(date_val[2])
|
||||
else:
|
||||
value = self.dhformat.replace('%m', str(date_val[1])
|
||||
.zfill(2))
|
||||
value = value.replace('%d', str(date_val[0]).zfill(2))
|
||||
value = value.replace('%Y', str(date_val[2]))
|
||||
else:
|
||||
# day. month_abbreviation year
|
||||
if date_val[0] == 0:
|
||||
|
||||
@@ -32,7 +32,7 @@ database to fetch data from). Thus, dbstate.db cannot be left as 'None' because
|
||||
None has no 'is_open' attribute. Therefore this database class is provided so
|
||||
that it can be instantiated for dbstate.db.
|
||||
|
||||
FIXME: Ideally, only is_open() needs to be implemented here, bacause that is the
|
||||
FIXME: Ideally, only is_open() needs to be implemented here, because that is the
|
||||
only method that should really be called, but the Gramps code is not perfect,
|
||||
and many other methods are called. Calls of other methods could be considered
|
||||
bugs, so when these are fixed, this class could be reduced.
|
||||
@@ -757,6 +757,14 @@ class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})):
|
||||
LOG.warning("database is closed")
|
||||
return 0
|
||||
|
||||
def get_number_of_citations(self):
|
||||
"""
|
||||
Return the number of citations currently in the database.
|
||||
"""
|
||||
if not self.db_is_open:
|
||||
LOG.warning("database is closed")
|
||||
return 0
|
||||
|
||||
def get_number_of_tags(self):
|
||||
"""
|
||||
Return the number of tags currently in the database.
|
||||
|
||||
@@ -757,7 +757,7 @@ class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback):
|
||||
if self._directory:
|
||||
filepath = os.path.join(self._directory, "name.txt")
|
||||
try:
|
||||
with open(filepath, "r") as name_file:
|
||||
with open(filepath, "r", encoding='utf8') as name_file:
|
||||
name = name_file.readline().strip()
|
||||
except (OSError, IOError) as msg:
|
||||
LOG.error(str(msg))
|
||||
|
||||
@@ -28,6 +28,7 @@ from ._hascitation import HasCitation
|
||||
from ._allcitations import AllCitations
|
||||
from ._changedsince import ChangedSince
|
||||
from ._citationprivate import CitationPrivate
|
||||
from ._hasattribute import HasAttribute
|
||||
from ._hasgallery import HasGallery
|
||||
from ._hasidof import HasIdOf
|
||||
from ._hasnote import HasNote
|
||||
@@ -50,6 +51,7 @@ editor_rule_list = [
|
||||
AllCitations,
|
||||
ChangedSince,
|
||||
CitationPrivate,
|
||||
HasAttribute,
|
||||
HasGallery,
|
||||
HasIdOf,
|
||||
HasNote,
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
# Copyright (C) 2019 Matthias Kemmer
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Standard Python modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from ....const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from .._hasattributebase import HasAttributeBase
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# HasAttribute
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
class HasAttribute(HasAttributeBase):
|
||||
"""Rule that checks for a citation with a particular attribute"""
|
||||
|
||||
labels = [_('Citation attribute:'), _('Value:')]
|
||||
name = _('Citations with the attribute <attribute>')
|
||||
description = _("Matches citations with the attribute "
|
||||
"of a particular value")
|
||||
@@ -29,6 +29,7 @@ from ._disconnected import Disconnected
|
||||
from ._everyone import Everyone
|
||||
from ._familywithincompleteevent import FamilyWithIncompleteEvent
|
||||
from ._hasaddress import HasAddress
|
||||
from ._hasaddresstext import HasAddressText
|
||||
from ._hasalternatename import HasAlternateName
|
||||
from ._hasassociation import HasAssociation
|
||||
from ._hasattribute import HasAttribute
|
||||
@@ -125,6 +126,7 @@ editor_rule_list = [
|
||||
IsBookmarked,
|
||||
HasAlternateName,
|
||||
HasAddress,
|
||||
HasAddressText,
|
||||
HasAssociation,
|
||||
HasIdOf,
|
||||
HasLDS,
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2008 Brian G. Matherly
|
||||
# Copyright (C) 2008 Jerome Rapinat
|
||||
# Copyright (C) 2008 Benny Malengier
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from .. import Rule
|
||||
from ....const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# HasAddressText
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
class HasAddressText(Rule):
|
||||
"""Rule that checks for text in personal addresses"""
|
||||
|
||||
labels = [_('Text:')]
|
||||
name = _('People with an address containing <text>')
|
||||
description = _("Matches people with a personal address containing "
|
||||
"the given text")
|
||||
category = _('General filters')
|
||||
allow_regex = True
|
||||
|
||||
def apply(self, db, person):
|
||||
for address in person.get_address_list():
|
||||
for string in address.get_text_data_list():
|
||||
if self.match_substring(0, string):
|
||||
return True
|
||||
return False
|
||||
@@ -1,3 +1,6 @@
|
||||
"""
|
||||
WithinArea : used to verify if a place is contained in a specific area
|
||||
"""
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
@@ -25,17 +28,21 @@
|
||||
# Standard Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
from math import pi, cos, hypot
|
||||
from ....const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.sgettext
|
||||
import re
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.errors import FilterError
|
||||
from ....const import GRAMPS_LOCALE as glocale
|
||||
from .. import Rule
|
||||
from ....utils.location import located_in
|
||||
from ....utils.place import conv_lat_lon
|
||||
|
||||
_ = glocale.translation.sgettext
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -51,6 +58,10 @@ class WithinArea(Rule):
|
||||
name = _('Places within an area')
|
||||
description = _('Matches places within a given distance of another place')
|
||||
category = _('Position filters')
|
||||
handle = None
|
||||
radius = None
|
||||
latitude = None
|
||||
longitude = None
|
||||
|
||||
def prepare(self, db, user):
|
||||
ref_place = db.get_place_from_gramps_id(self.list[0])
|
||||
@@ -60,13 +71,25 @@ class WithinArea(Rule):
|
||||
self.longitude = None
|
||||
if ref_place:
|
||||
self.handle = ref_place.handle
|
||||
self.latitude = ref_place.get_latitude()
|
||||
if self.latitude == "":
|
||||
self.latitude = None
|
||||
latitude = ref_place.get_latitude()
|
||||
if latitude == "":
|
||||
latitude = None
|
||||
return
|
||||
self.longitude = ref_place.get_longitude()
|
||||
value = self.list[1]
|
||||
unit = self.list[2]
|
||||
longitude = ref_place.get_longitude()
|
||||
self.latitude, self.longitude = conv_lat_lon(latitude,
|
||||
longitude,
|
||||
"D.D8")
|
||||
if self.latitude is None or self.longitude is None:
|
||||
raise FilterError(_("Cannot use the filter 'within area'"),
|
||||
_("The place you selected contains bad"
|
||||
" coordinates. Please, run the tool "
|
||||
"'clean input data'"))
|
||||
|
||||
val = self.list[1]
|
||||
if isinstance(val, str):
|
||||
val = re.sub(r"\D", "", val) # suppress all alpha characters
|
||||
value = int(val)
|
||||
unit = int(self.list[2])
|
||||
# earth perimeter in kilometers for latitude
|
||||
# 2 * pi * (6371 * cos(latitude/180*pi))
|
||||
# so 1 degree correspond to the result above / 360
|
||||
@@ -79,7 +102,7 @@ class WithinArea(Rule):
|
||||
self.radius = float(value)
|
||||
self.radius = self.radius/2
|
||||
|
||||
def apply(self, db, place):
|
||||
def apply(self, dummy_db, place):
|
||||
if self.handle is None:
|
||||
return False
|
||||
if self.latitude is None:
|
||||
@@ -90,7 +113,11 @@ class WithinArea(Rule):
|
||||
lat = place.get_latitude()
|
||||
lon = place.get_longitude()
|
||||
if lat and lon:
|
||||
if (hypot(float(self.latitude)-float(lat),
|
||||
float(self.longitude)-float(lon)) <= self.radius) == True:
|
||||
latit, longit = conv_lat_lon(lat, lon, "D.D8")
|
||||
if latit is None or longit is None:
|
||||
return False
|
||||
if (hypot(float(self.latitude)-float(latit),
|
||||
float(self.longitude)-float(longit))
|
||||
<= self.radius):
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -25,6 +25,7 @@ Package providing filter rules for Gramps.
|
||||
from ._allrepos import AllRepos
|
||||
from ._hasidof import HasIdOf
|
||||
from ._regexpidof import RegExpIdOf
|
||||
from ._hasattribute import HasAttribute
|
||||
from ._hasnoteregexp import HasNoteRegexp
|
||||
from ._hasnotematchingsubstringof import HasNoteMatchingSubstringOf
|
||||
from ._hasreferencecountof import HasReferenceCountOf
|
||||
@@ -37,6 +38,7 @@ from ._hastag import HasTag
|
||||
|
||||
editor_rule_list = [
|
||||
AllRepos,
|
||||
HasAttribute,
|
||||
HasIdOf,
|
||||
RegExpIdOf,
|
||||
HasNoteRegexp,
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
# Copyright (C) 2019 Matthias Kemmer
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Standard Python modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from ....const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from .._hasattributebase import HasAttributeBase
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# HasAttribute
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
class HasAttribute(HasAttributeBase):
|
||||
"""Rule that checks for a repository with a particular attribute"""
|
||||
|
||||
labels = [_('Repository attribute:'), _('Value:')]
|
||||
name = _('Repositories with the attribute <attribute>')
|
||||
description = _("Matches repositories with the attribute "
|
||||
"of a particular value")
|
||||
@@ -27,6 +27,7 @@ Package providing filter rules for Gramps.
|
||||
from .._hassourcebase import HasSourceBase as HasSource
|
||||
|
||||
from ._allsources import AllSources
|
||||
from ._hasattribute import HasAttribute
|
||||
from ._hasgallery import HasGallery
|
||||
from ._hasidof import HasIdOf
|
||||
from ._regexpidof import RegExpIdOf
|
||||
@@ -45,6 +46,7 @@ from ._hastag import HasTag
|
||||
|
||||
editor_rule_list = [
|
||||
AllSources,
|
||||
HasAttribute,
|
||||
HasGallery,
|
||||
HasIdOf,
|
||||
RegExpIdOf,
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2008 Gary Burton
|
||||
# Copyright (C) 2019 Matthias Kemmer
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Standard Python modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from ....const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
from .._hasattributebase import HasAttributeBase
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# HasAttribute
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
class HasAttribute(HasAttributeBase):
|
||||
"""Rule that checks for a source with a particular attribute"""
|
||||
|
||||
labels = [_('Source attribute:'), _('Value:')]
|
||||
name = _('Sources with the attribute <attribute>')
|
||||
description = _("Matches sources with the attribute "
|
||||
"of a particular value")
|
||||
@@ -193,7 +193,7 @@ class PluginData:
|
||||
|
||||
.. attribute:: id
|
||||
A unique identifier for the plugin. This is eg used to store the plugin
|
||||
settings.
|
||||
settings. MUST be in ASCII, with only "_- ().,'" special characters.
|
||||
.. attribute:: name
|
||||
A friendly name to call this plugin (normally translated)
|
||||
.. attribute:: name_accell
|
||||
|
||||
@@ -1038,7 +1038,7 @@ class GVPdfGsDoc(GVDocBase):
|
||||
# Generate Ghostscript code
|
||||
command = '%s -q -dBATCH -dNOPAUSE -dSAFER '\
|
||||
'-dDEVICEWIDTHPOINTS=%d -dDEVICEHEIGHTPOINTS=%d '\
|
||||
'-sOutputFile="%s" -sDEVICE=pdfwrite '\
|
||||
'-dFIXEDMEDIA -sOutputFile="%s" -sDEVICE=pdfwrite '\
|
||||
'-c "<</.HWMargins [%d %d %d %d] /PageOffset [%d %d]>> '\
|
||||
'setpagedevice" -f "%s"' % (
|
||||
_GS_CMD, width_pt + 10, height_pt + 10, tmp_pdf_piece,
|
||||
|
||||
@@ -46,8 +46,14 @@ from ..menu import NumberOption, TextOption, EnumeratedListOption
|
||||
from ...constfunc import win
|
||||
from ...config import config
|
||||
from ...const import GRAMPS_LOCALE as glocale
|
||||
from ...utils.grampslocale import GrampsLocale
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
LOCALE = GrampsLocale(lang='en')
|
||||
|
||||
LATIN = ['french', 'italian', 'spanish']
|
||||
LANG_SUPPORT = ['danish', 'dutch', 'german', 'swedish'] + LATIN
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# set up logging
|
||||
@@ -339,6 +345,14 @@ class TreeDocBase(BaseDoc, TreeDoc):
|
||||
self.write(0, '\\usepackage[%s,%s]{geometry}\n' % (paper, margin))
|
||||
self.write(0, '\\usepackage[all]{genealogytree}\n')
|
||||
self.write(0, '\\usepackage{color}\n')
|
||||
trans = glocale.language[0][:2]
|
||||
lang = LOCALE._get_language_string(trans).lower()
|
||||
if lang in LANG_SUPPORT:
|
||||
self.write(0, '\\gtrset{language=%s}\n' % lang)
|
||||
if lang in LATIN:
|
||||
self.write(0, '\\IfFileExists{lmodern.sty}{\n')
|
||||
self.write(0, ' \\usepackage{lmodern}\n')
|
||||
self.write(0, '}{}\n')
|
||||
self.write(0, '\\begin{document}\n')
|
||||
|
||||
if self.nodecolor == 'preferences':
|
||||
@@ -409,10 +423,7 @@ class TreeDocBase(BaseDoc, TreeDoc):
|
||||
options = ['id=%s' % family.gramps_id]
|
||||
if option_list:
|
||||
options.extend(option_list)
|
||||
if subgraph_type == 'sandclock':
|
||||
self.write(level, 'sandclock{\n')
|
||||
else:
|
||||
self.write(level, '%s[%s]{\n' % (subgraph_type, ','.join(options)))
|
||||
self.write(level, '%s[%s]{\n' % (subgraph_type, ','.join(options)))
|
||||
|
||||
def end_subgraph(self, level):
|
||||
self.write(level, '}\n')
|
||||
@@ -589,6 +600,47 @@ class TreeDocBase(BaseDoc, TreeDoc):
|
||||
self.write_end()
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# TreeGraphDoc
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
class TreeGraphDoc(TreeDocBase):
|
||||
"""
|
||||
TreeGraphDoc implementation that generates a .graph file.
|
||||
"""
|
||||
|
||||
def write_start(self):
|
||||
"""
|
||||
Write the start of the document - nothing for a graph file.
|
||||
"""
|
||||
pass
|
||||
|
||||
def start_tree(self, option_list):
|
||||
"""
|
||||
Write the start of a tree - nothing for a graph file.
|
||||
"""
|
||||
pass
|
||||
|
||||
def end_tree(self):
|
||||
"""
|
||||
Write the end of a tree - nothing for a graph file.
|
||||
"""
|
||||
pass
|
||||
|
||||
def write_end(self):
|
||||
"""
|
||||
Write the end of the document - nothing for a graph file.
|
||||
"""
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
""" Implements TreeDocBase.close() """
|
||||
TreeDocBase.close(self)
|
||||
|
||||
with open(self._filename, 'w', encoding='utf-8') as texfile:
|
||||
texfile.write(self._tex.getvalue())
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# TreeTexDoc
|
||||
@@ -656,6 +708,11 @@ if _LATEX_FOUND:
|
||||
'mime' : "application/pdf",
|
||||
'class': TreePdfDoc}]
|
||||
|
||||
FORMATS += [{'type' : "graph",
|
||||
'ext' : "graph",
|
||||
'descr': _("Graph File for genealogytree"),
|
||||
'class': TreeGraphDoc}]
|
||||
|
||||
FORMATS += [{'type' : "tex",
|
||||
'ext' : "tex",
|
||||
'descr': _("LaTeX File"),
|
||||
|
||||
@@ -161,12 +161,12 @@ def image_size(source):
|
||||
:returns: a tuple consisting of the width and height
|
||||
"""
|
||||
from gi.repository import GdkPixbuf
|
||||
from gi.repository import GObject
|
||||
from gi.repository import GLib
|
||||
try:
|
||||
img = GdkPixbuf.Pixbuf.new_from_file(source)
|
||||
width = img.get_width()
|
||||
height = img.get_height()
|
||||
except GObject.GError:
|
||||
except GLib.GError:
|
||||
width = 0
|
||||
height = 0
|
||||
return (width, height)
|
||||
|
||||
@@ -36,7 +36,7 @@ from hashlib import md5
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gi.repository import GObject
|
||||
from gi.repository import GLib
|
||||
from gi.repository import GdkPixbuf
|
||||
|
||||
try:
|
||||
@@ -98,7 +98,7 @@ def __get_gconf_string(key):
|
||||
"""
|
||||
try:
|
||||
val = CLIENT.get_string(key)
|
||||
except GObject.GError:
|
||||
except GLib.GError:
|
||||
val = None
|
||||
return str(val)
|
||||
|
||||
@@ -119,7 +119,7 @@ def __get_gconf_bool(key):
|
||||
"""
|
||||
try:
|
||||
val = CLIENT.get_bool(key)
|
||||
except GObject.GError:
|
||||
except GLib.GError:
|
||||
val = None
|
||||
return val
|
||||
|
||||
@@ -318,7 +318,7 @@ def get_thumbnail_image(src_file, mtype=None, rectangle=None, size=SIZE_NORMAL):
|
||||
try:
|
||||
filename = get_thumbnail_path(src_file, mtype, rectangle, size)
|
||||
return GdkPixbuf.Pixbuf.new_from_file(filename)
|
||||
except (GObject.GError, OSError):
|
||||
except (GLib.GError, OSError):
|
||||
if mtype:
|
||||
return find_mime_type_pixbuf(mtype)
|
||||
else:
|
||||
|
||||
+1
-1
@@ -212,7 +212,7 @@ def show_settings():
|
||||
Gtk.get_minor_version(), Gtk.get_micro_version())
|
||||
except: # any failure to 'get' the version
|
||||
gtkver_str = 'unknown version'
|
||||
except ImportError:
|
||||
except (ImportError, ValueError):
|
||||
gtkver_str = 'not found'
|
||||
# no DISPLAY is a RuntimeError in an older pygtk (e.g. 2.17 in Fedora 14)
|
||||
except RuntimeError:
|
||||
|
||||
@@ -171,7 +171,7 @@ class StandardCustomSelector:
|
||||
if self.active_key in items:
|
||||
parent = None
|
||||
else:
|
||||
parent = store.append(None, row=[None, heading, False])
|
||||
parent = store.append(None, row=[None, _(heading), False])
|
||||
for item in items:
|
||||
store.append(parent, row=[item, self.mapping[item], True])
|
||||
|
||||
|
||||
+43
-51
@@ -690,7 +690,7 @@ class GrampsPreferences(ConfigureDialog):
|
||||
hbox.pack_start(lwidget, False, False, 0)
|
||||
hbox.pack_start(self.color_scheme_box, False, False, 0)
|
||||
|
||||
restore_btn = Gtk.Button(_('Restore to defaults'))
|
||||
restore_btn = Gtk.Button(label=_('Restore to defaults'))
|
||||
restore_btn.set_tooltip_text(
|
||||
_('Restore colors for current theme to default.'))
|
||||
restore_btn.connect('clicked', self.restore_colors)
|
||||
@@ -1137,7 +1137,7 @@ class GrampsPreferences(ConfigureDialog):
|
||||
self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True,
|
||||
only_active=False)
|
||||
|
||||
def cb_grampletbar_close(self, obj, state):
|
||||
def cb_grampletbar_close(self, obj):
|
||||
"""
|
||||
Gramplet bar close button preference callback
|
||||
"""
|
||||
@@ -1256,14 +1256,15 @@ class GrampsPreferences(ConfigureDialog):
|
||||
_("Years, Months, Days")]
|
||||
list(map(obox.append_text, age_precision))
|
||||
# Combo_box active index is from 0 to 2, we need values from 1 to 3
|
||||
constant = 'preferences.age-display-precision'
|
||||
active = config.get(constant) - 1
|
||||
active = config.get('preferences.age-display-precision') - 1
|
||||
if active >= 0 and active <= 2:
|
||||
obox.set_active(active)
|
||||
else:
|
||||
obox.set_active(0)
|
||||
obox.connect('changed',
|
||||
lambda obj: config.set(constant, obj.get_active() + 1))
|
||||
obox.connect(
|
||||
'changed',
|
||||
lambda obj: config.set('preferences.age-display-precision',
|
||||
obj.get_active() + 1))
|
||||
lwidget = BasicLabel(_("%s: ")
|
||||
% _('Age display precision (requires restart)'))
|
||||
grid.attach(lwidget, 0, row, 1, 1)
|
||||
@@ -1300,10 +1301,10 @@ class GrampsPreferences(ConfigureDialog):
|
||||
obox = Gtk.ComboBoxText()
|
||||
formats = FamilyRelType().get_standard_names()
|
||||
list(map(obox.append_text, formats))
|
||||
constant = 'preferences.family-relation-type'
|
||||
obox.set_active(config.get(constant))
|
||||
obox.set_active(config.get('preferences.family-relation-type'))
|
||||
obox.connect('changed',
|
||||
lambda obj: config.set(constant, obj.get_active()))
|
||||
lambda obj: config.set('preferences.family-relation-type',
|
||||
obj.get_active()))
|
||||
lwidget = BasicLabel(_("%s: ") % _('Default family relationship'))
|
||||
grid.attach(lwidget, 0, row, 1, 1)
|
||||
grid.attach(obox, 1, row, 2, 1)
|
||||
@@ -1489,6 +1490,26 @@ class GrampsPreferences(ConfigureDialog):
|
||||
align=Gtk.Align.CENTER, bold=True)
|
||||
|
||||
row = 1
|
||||
self.add_pos_int_entry(
|
||||
grid, _('Markup for invalid date format'),
|
||||
row, 'preferences.invalid-date-format',
|
||||
self.update_markup_entry,
|
||||
helptext=_(
|
||||
'Convenience markups are:\n'
|
||||
'<b><b>Bold</b></b>\n'
|
||||
'<big><big>'
|
||||
'Makes font relatively larger</big></big>\n'
|
||||
'<i><i>Italic</i></i>\n'
|
||||
'<s><s>Strikethrough</s></s>\n'
|
||||
'<sub><sub>Subscript</sub></sub>\n'
|
||||
'<sup><sup>Superscript</sup></sup>\n'
|
||||
'<small><small>'
|
||||
'Makes font relatively smaller</small></small>\n'
|
||||
'<tt><tt>Monospace font</tt></tt>\n'
|
||||
'<u><u>Underline</u></u>\n\n'
|
||||
'For example: <u><b>%s</b></u>\n'
|
||||
'will display <u><b>Underlined bold date</b></u>.\n'))
|
||||
row += 1
|
||||
self.add_spinner(
|
||||
grid, _('Date about range'),
|
||||
row, 'behavior.date-about-range', (1, 9999))
|
||||
@@ -1516,26 +1537,6 @@ class GrampsPreferences(ConfigureDialog):
|
||||
self.add_spinner(
|
||||
grid, _('Average years between generations'),
|
||||
row, 'behavior.avg-generation-gap', (10, 30))
|
||||
row += 1
|
||||
self.add_pos_int_entry(
|
||||
grid, _('Markup for invalid date format'),
|
||||
row, 'preferences.invalid-date-format',
|
||||
self.update_markup_entry,
|
||||
helptext=_(
|
||||
'Convenience markups are:\n'
|
||||
'<b><b>Bold</b></b>\n'
|
||||
'<big><big>'
|
||||
'Makes font relatively larger</big></big>\n'
|
||||
'<i><i>Italic</i></i>\n'
|
||||
'<s><s>Strikethrough</s></s>\n'
|
||||
'<sub><sub>Subscript</sub></sub>\n'
|
||||
'<sup><sup>Superscript</sup></sup>\n'
|
||||
'<small><small>'
|
||||
'Makes font relatively smaller</small></small>\n'
|
||||
'<tt><tt>Monospace font</tt></tt>\n'
|
||||
'<u><u>Underline</u></u>\n\n'
|
||||
'For example: <u><b>%s</b></u>\n'
|
||||
'will display <u><b>Underlined bold date</b></u>.\n'))
|
||||
|
||||
return _('Dates'), grid
|
||||
|
||||
@@ -1827,12 +1828,10 @@ class GrampsPreferences(ConfigureDialog):
|
||||
Show dialog to choose media directory.
|
||||
"""
|
||||
f = Gtk.FileChooserDialog(title=_("Select media directory"),
|
||||
parent=self.window,
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER,
|
||||
buttons=(_('_Cancel'),
|
||||
Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'),
|
||||
Gtk.ResponseType.OK))
|
||||
transient_for=self.window,
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER)
|
||||
f.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'), Gtk.ResponseType.OK)
|
||||
mpath = media_path(self.dbstate.db)
|
||||
f.set_current_folder(os.path.dirname(mpath))
|
||||
|
||||
@@ -1877,12 +1876,10 @@ class GrampsPreferences(ConfigureDialog):
|
||||
Show dialog to choose backup directory.
|
||||
"""
|
||||
f = Gtk.FileChooserDialog(title=_("Select backup directory"),
|
||||
parent=self.window,
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER,
|
||||
buttons=(_('_Cancel'),
|
||||
Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'),
|
||||
Gtk.ResponseType.OK))
|
||||
transient_for=self.window,
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER)
|
||||
f.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'), Gtk.ResponseType.OK)
|
||||
backup_path = config.get('database.backup-path')
|
||||
if not backup_path:
|
||||
backup_path = config.get('database.path')
|
||||
@@ -2093,9 +2090,9 @@ class GrampsPreferences(ConfigureDialog):
|
||||
self.all_avail_fonts, callback=self.utf8_update_font,
|
||||
valueactive=True, setactive=active_val)
|
||||
if len(available_fonts) == 1:
|
||||
single_font = self.all_avail_fonts[choosefont.get_active()][1]
|
||||
single_font = self.all_avail_fonts[choosefont.get_active()][0]
|
||||
config.set('utf8.selected-font',
|
||||
self.all_avail_fonts[single_font])
|
||||
self.all_avail_fonts[single_font][1])
|
||||
self.utf8_show_example()
|
||||
symbols = Symbols()
|
||||
all_sbls = symbols.get_death_symbols()
|
||||
@@ -2162,11 +2159,9 @@ class GrampsPreferences(ConfigureDialog):
|
||||
scrollw.set_size_request(600, 100)
|
||||
text = Gtk.Label()
|
||||
text.set_line_wrap(True)
|
||||
font_description = Pango.font_description_from_string(font)
|
||||
text.modify_font(font_description)
|
||||
self.activate_change_font()
|
||||
text.set_halign(Gtk.Align.START)
|
||||
text.set_text(my_characters)
|
||||
text.set_markup("<span font='%s'>%s</span>" % (font, my_characters))
|
||||
scrollw.add(text)
|
||||
scrollw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
||||
self.grid.attach(scrollw, 1, 7, 8, 1)
|
||||
@@ -2179,12 +2174,9 @@ class GrampsPreferences(ConfigureDialog):
|
||||
my_characters += symbols.get_death_symbol_for_char(death_symbl)
|
||||
text = Gtk.Label()
|
||||
text.set_line_wrap(True)
|
||||
font_description = Pango.font_description_from_string(font)
|
||||
text.modify_font(font_description)
|
||||
text.set_halign(Gtk.Align.START)
|
||||
text.set_markup("<big><big><big><big>" +
|
||||
my_characters +
|
||||
"</big></big></big></big>")
|
||||
text.set_markup("<big><big><big><big><span font='%s'>%s</span>"
|
||||
"</big></big></big></big>" % (font, my_characters))
|
||||
self.grid.attach(text, 1, 8, 8, 1)
|
||||
scrollw.show_all()
|
||||
text.show_all()
|
||||
|
||||
@@ -380,7 +380,7 @@ class GrampsLoginDialog(ManagedWindow):
|
||||
self.title = _("Login")
|
||||
ManagedWindow.__init__(self, uistate, [], self.__class__, modal=True)
|
||||
|
||||
dialog = Gtk.Dialog(parent=uistate.window)
|
||||
dialog = Gtk.Dialog(transient_for=uistate.window)
|
||||
grid = Gtk.Grid()
|
||||
grid.set_border_width(6)
|
||||
grid.set_row_spacing(6)
|
||||
|
||||
@@ -42,6 +42,7 @@ import pickle
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import Pango
|
||||
from gi.repository.GLib import markup_escape_text
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -435,7 +436,6 @@ class EditPerson(EditPrimary):
|
||||
obj.connect('changed', self._changed_name)
|
||||
|
||||
self.preview_name = self.top.get_object("full_name")
|
||||
self.preview_name.override_font(Pango.FontDescription('sans bold 12'))
|
||||
self.surntab = SurnameTab(self.dbstate, self.uistate, self.track,
|
||||
self.obj.get_primary_name(),
|
||||
on_change=self._changed_name)
|
||||
@@ -550,7 +550,9 @@ class EditPerson(EditPrimary):
|
||||
Update the window title, and default name in name tab
|
||||
"""
|
||||
self.update_title(self.get_menu_title())
|
||||
self.preview_name.set_text(self.get_preview_name())
|
||||
self.preview_name.set_markup(
|
||||
"<span size='x-large' weight='bold'>%s</span>" %
|
||||
markup_escape_text(self.get_preview_name(), -1))
|
||||
self.name_list.update_defname()
|
||||
|
||||
def name_callback(self):
|
||||
@@ -638,7 +640,6 @@ class EditPerson(EditPrimary):
|
||||
"""
|
||||
self.imgmenu = Gtk.Menu()
|
||||
menu = self.imgmenu
|
||||
menu.set_title(_("Media Object"))
|
||||
obj = self.db.get_media_from_handle(photo.get_reference_handle())
|
||||
if obj:
|
||||
add_menuitem(menu, _("View"), photo,
|
||||
@@ -1086,9 +1087,9 @@ class EditPerson(EditPrimary):
|
||||
class GenderDialog(Gtk.MessageDialog):
|
||||
def __init__(self, parent=None):
|
||||
Gtk.MessageDialog.__init__(self,
|
||||
parent,
|
||||
flags=Gtk.DialogFlags.MODAL,
|
||||
type=Gtk.MessageType.QUESTION,
|
||||
transient_for=parent,
|
||||
modal=True,
|
||||
message_type=Gtk.MessageType.QUESTION,
|
||||
)
|
||||
self.set_icon(ICON)
|
||||
self.set_title('')
|
||||
|
||||
@@ -158,24 +158,30 @@ class EditPlace(EditPrimary):
|
||||
self.obj.set_code, self.obj.get_code,
|
||||
self.db.readonly)
|
||||
|
||||
entry = self.top.get_object("lon_entry")
|
||||
entry.set_ltr_mode()
|
||||
self.longitude = MonitoredEntry(
|
||||
self.top.get_object("lon_entry"),
|
||||
entry,
|
||||
self.obj.set_longitude, self.obj.get_longitude,
|
||||
self.db.readonly)
|
||||
self.longitude.connect("validate", self._validate_coordinate, "lon")
|
||||
#force validation now with initial entry
|
||||
self.top.get_object("lon_entry").validate(force=True)
|
||||
entry.validate(force=True)
|
||||
|
||||
entry = self.top.get_object("lat_entry")
|
||||
entry.set_ltr_mode()
|
||||
self.latitude = MonitoredEntry(
|
||||
self.top.get_object("lat_entry"),
|
||||
entry,
|
||||
self.obj.set_latitude, self.obj.get_latitude,
|
||||
self.db.readonly)
|
||||
self.latitude.connect("validate", self._validate_coordinate, "lat")
|
||||
#force validation now with initial entry
|
||||
self.top.get_object("lat_entry").validate(force=True)
|
||||
entry.validate(force=True)
|
||||
|
||||
entry = self.top.get_object("latlon_entry")
|
||||
entry.set_ltr_mode()
|
||||
self.latlon = MonitoredEntry(
|
||||
self.top.get_object("latlon_entry"),
|
||||
entry,
|
||||
self.set_latlongitude, self.get_latlongitude,
|
||||
self.db.readonly)
|
||||
|
||||
|
||||
@@ -151,24 +151,30 @@ class EditPlaceRef(EditReference):
|
||||
self.source.set_code, self.source.get_code,
|
||||
self.db.readonly)
|
||||
|
||||
entry = self.top.get_object("lon_entry")
|
||||
entry.set_ltr_mode()
|
||||
self.longitude = MonitoredEntry(
|
||||
self.top.get_object("lon_entry"),
|
||||
entry,
|
||||
self.source.set_longitude, self.source.get_longitude,
|
||||
self.db.readonly)
|
||||
self.longitude.connect("validate", self._validate_coordinate, "lon")
|
||||
#force validation now with initial entry
|
||||
self.top.get_object("lon_entry").validate(force=True)
|
||||
entry.validate(force=True)
|
||||
|
||||
entry = self.top.get_object("lat_entry")
|
||||
entry.set_ltr_mode()
|
||||
self.latitude = MonitoredEntry(
|
||||
self.top.get_object("lat_entry"),
|
||||
entry,
|
||||
self.source.set_latitude, self.source.get_latitude,
|
||||
self.db.readonly)
|
||||
self.latitude.connect("validate", self._validate_coordinate, "lat")
|
||||
#force validation now with initial entry
|
||||
self.top.get_object("lat_entry").validate(force=True)
|
||||
entry.validate(force=True)
|
||||
|
||||
entry = self.top.get_object("latlon_entry")
|
||||
entry.set_ltr_mode()
|
||||
self.latlon = MonitoredEntry(
|
||||
self.top.get_object("latlon_entry"),
|
||||
entry,
|
||||
self.set_latlongitude, self.get_latlongitude,
|
||||
self.db.readonly)
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ class EditTagList(ManagedWindow):
|
||||
Create a dialog box to select tags.
|
||||
"""
|
||||
# pylint: disable-msg=E1101
|
||||
top = Gtk.Dialog(parent=self.uistate.window)
|
||||
top = Gtk.Dialog(transient_for=self.uistate.window)
|
||||
top.vbox.set_spacing(5)
|
||||
|
||||
columns = [('', -1, 300),
|
||||
|
||||
@@ -311,7 +311,10 @@ class PlaceEntry(ObjEntry):
|
||||
|
||||
def get_label(self, place):
|
||||
place_title = place_displayer.display(self.db, place)
|
||||
return "%s [%s]" % (place_title, place.gramps_id)
|
||||
# When part of the place title contains RTL text, the gramps_id gets
|
||||
# messed up; so use Unicode FSI/PDI and LRM chars to isolate it.
|
||||
# see bug 10124 and PR924
|
||||
return "%s \u2068[%s]\u200e\u2069" % (place_title, place.gramps_id)
|
||||
|
||||
def call_editor(self, obj=None):
|
||||
if obj is None:
|
||||
@@ -356,7 +359,7 @@ class SourceEntry(ObjEntry):
|
||||
return self.db.get_source_from_handle(handle)
|
||||
|
||||
def get_label(self, source):
|
||||
return "%s [%s]" % (source.get_title(), source.gramps_id)
|
||||
return "%s \u2068[%s]\u200e\u2069" % (source.get_title(), source.gramps_id)
|
||||
|
||||
def call_editor(self, obj=None):
|
||||
if obj is None:
|
||||
@@ -402,7 +405,8 @@ class MediaEntry(ObjEntry):
|
||||
return self.db.get_media_from_handle(handle)
|
||||
|
||||
def get_label(self, object):
|
||||
return "%s [%s]" % (object.get_description(), object.gramps_id)
|
||||
return "%s \u2068[%s]\u200e\u2069" % (object.get_description(),
|
||||
object.gramps_id)
|
||||
|
||||
def call_editor(self, obj=None):
|
||||
if obj is None:
|
||||
@@ -462,7 +466,7 @@ class NoteEntry(ObjEntry):
|
||||
txt = " ".join(note.get().split())
|
||||
if len(txt) > 35:
|
||||
txt = txt[:35] + "..."
|
||||
return "%s [%s]" % (txt, note.gramps_id)
|
||||
return "%s \u2068[%s]\u200e\u2069" % (txt, note.gramps_id)
|
||||
|
||||
def call_editor(self, obj=None):
|
||||
if obj is None:
|
||||
|
||||
@@ -183,12 +183,17 @@ class PersonSidebarFilter(SidebarFilter):
|
||||
# build a GenericFilter
|
||||
generic_filter = GenericFilter()
|
||||
|
||||
# if the name is not empty, choose either the regular expression
|
||||
# version or the normal text match
|
||||
# if the name is not empty, split the name in multiple part if
|
||||
# we don't use regexp. if the regexp is used, don't split the
|
||||
# field
|
||||
if name:
|
||||
name_parts = name.split(sep=" ")
|
||||
for name_part in name_parts:
|
||||
rule = RegExpName([name_part], use_regex=regex)
|
||||
if not regex:
|
||||
name_parts = name.split(sep=" ")
|
||||
for name_part in name_parts:
|
||||
rule = RegExpName([name_part], use_regex=regex)
|
||||
generic_filter.add_rule(rule)
|
||||
else:
|
||||
rule = RegExpName([name], use_regex=regex)
|
||||
generic_filter.add_rule(rule)
|
||||
|
||||
# if the id is not empty, choose either the regular expression
|
||||
|
||||
@@ -284,7 +284,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
"information included in the error please remove "
|
||||
"it."))
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_padding(0, 4)
|
||||
label.set_margin_top(4)
|
||||
label.set_margin_bottom(4)
|
||||
label.set_line_wrap(True)
|
||||
|
||||
swin = Gtk.ScrolledWindow()
|
||||
@@ -300,9 +301,9 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
sw_frame = Gtk.Frame()
|
||||
sw_frame.add(swin)
|
||||
|
||||
reset = Gtk.Button("Reset")
|
||||
reset = Gtk.Button(label="Reset")
|
||||
reset.connect('clicked', self._reset_error_details)
|
||||
clear = Gtk.Button("Clear")
|
||||
clear = Gtk.Button(label="Clear")
|
||||
clear.connect('clicked', self._clear_error_details)
|
||||
|
||||
button_box = Gtk.ButtonBox()
|
||||
@@ -364,7 +365,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
"remove anything that you would rather not have "
|
||||
"included in the bug report."))
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_padding(0, 4)
|
||||
label.set_margin_top(4)
|
||||
label.set_margin_bottom(4)
|
||||
label.set_line_wrap(True)
|
||||
|
||||
swin = Gtk.ScrolledWindow()
|
||||
@@ -380,9 +382,9 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
sw_frame = Gtk.Frame()
|
||||
sw_frame.add(swin)
|
||||
|
||||
reset = Gtk.Button("Reset")
|
||||
reset = Gtk.Button(label="Reset")
|
||||
reset.connect('clicked', self._reset_sys_information)
|
||||
clear = Gtk.Button("Clear")
|
||||
clear = Gtk.Button(label="Clear")
|
||||
clear.connect('clicked', self._clear_sys_information)
|
||||
|
||||
|
||||
@@ -441,7 +443,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
"can about what you were doing when the error "
|
||||
"occurred."))
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_padding(0, 4)
|
||||
label.set_margin_top(4)
|
||||
label.set_margin_bottom(4)
|
||||
label.set_line_wrap(True)
|
||||
|
||||
swin = Gtk.ScrolledWindow()
|
||||
@@ -456,7 +459,7 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
sw_frame = Gtk.Frame()
|
||||
sw_frame.add(swin)
|
||||
|
||||
clear = Gtk.Button("Clear")
|
||||
clear = Gtk.Button(label="Clear")
|
||||
clear.connect('clicked', self._clear_user_information)
|
||||
|
||||
button_box = Gtk.ButtonBox()
|
||||
@@ -514,7 +517,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
"that it does not contain anything that you do not "
|
||||
"want to be sent to the developers."))
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_padding(0, 4)
|
||||
label.set_margin_top(4)
|
||||
label.set_margin_bottom(4)
|
||||
label.set_line_wrap(True)
|
||||
|
||||
swin = Gtk.ScrolledWindow()
|
||||
@@ -580,7 +584,8 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
"clipboard and then open a webbrowser to file a bug report at "),
|
||||
URL_BUGTRACKER))
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_padding(0, 4)
|
||||
label.set_margin_top(4)
|
||||
label.set_margin_bottom(4)
|
||||
label.set_line_wrap(True)
|
||||
label.set_use_markup(True)
|
||||
|
||||
@@ -589,11 +594,12 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
"and file a bug report on the Gramps bug "
|
||||
"tracking system."))
|
||||
url_label.set_halign(Gtk.Align.START)
|
||||
url_label.set_padding(0, 4)
|
||||
url_label.set_margin_top(4)
|
||||
url_label.set_margin_bottom(4)
|
||||
url_label.set_line_wrap(True)
|
||||
url_label.set_size_request(200, -1)
|
||||
|
||||
url_button = Gtk.Button("File bug report")
|
||||
url_button = Gtk.Button(label="File bug report")
|
||||
url_button.connect('clicked', self._start_gramps_bts_in_browser)
|
||||
url_button_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
url_button_vbox.pack_start(url_button, True, False, 0)
|
||||
@@ -613,11 +619,12 @@ class ErrorReportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
"the button below, paste the report and click "
|
||||
"submit report"))
|
||||
clip_label.set_halign(Gtk.Align.START)
|
||||
clip_label.set_padding(0, 4)
|
||||
clip_label.set_margin_top(4)
|
||||
clip_label.set_margin_bottom(4)
|
||||
clip_label.set_line_wrap(True)
|
||||
clip_label.set_size_request(200, -1)
|
||||
|
||||
clip_button = Gtk.Button("Copy to clipboard")
|
||||
clip_button = Gtk.Button(label="Copy to clipboard")
|
||||
clip_button.connect('clicked', self._copy_to_clipboard)
|
||||
clip_button_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
clip_button_vbox.pack_start(clip_button, True, False, 0)
|
||||
|
||||
@@ -105,7 +105,7 @@ class ErrorView(ManagedWindow):
|
||||
|
||||
def draw_window(self):
|
||||
title = "%s - Gramps" % _("Error Report")
|
||||
self.top = Gtk.Dialog(title)
|
||||
self.top = Gtk.Dialog(title=title)
|
||||
# look over the top level windows, it seems the oldest come first, so
|
||||
# the most recent still visible window appears to be a good choice for
|
||||
# a transient parent
|
||||
|
||||
@@ -49,7 +49,7 @@ from gramps.gen.const import GLADE_FILE, ICON
|
||||
from gramps.gen.errors import WindowActiveError
|
||||
from gramps.gen.config import config
|
||||
from gramps.gen.constfunc import is_quartz
|
||||
from .uimanager import ActionGroup
|
||||
from .uimanager import ActionGroup, valid_action_name
|
||||
from .glade import Glade
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -280,7 +280,7 @@ class GrampsWindowManager:
|
||||
return func
|
||||
|
||||
def generate_id(self, item):
|
||||
return 'wm/' + str(item.window_id).replace(' ', '_')
|
||||
return valid_action_name('wm-' + str(item.window_id))
|
||||
|
||||
def display_menu_list(self, data, action_data, mlist):
|
||||
menuitem = ('<item>\n'
|
||||
|
||||
@@ -75,16 +75,17 @@ class LastNameDialog(ManagedWindow):
|
||||
def __init__(self, database, uistate, track, surnames, skip_list=set()):
|
||||
|
||||
ManagedWindow.__init__(self, uistate, track, self, modal=True)
|
||||
flags = Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT
|
||||
buttons = (_('_Cancel'), Gtk.ResponseType.REJECT,
|
||||
_('_OK'), Gtk.ResponseType.ACCEPT)
|
||||
self.__dlg = Gtk.Dialog(None, uistate.window, flags, buttons)
|
||||
self.__dlg = Gtk.Dialog(
|
||||
transient_for=uistate.window, destroy_with_parent=True,
|
||||
modal=True)
|
||||
self.__dlg.add_buttons(_('_Cancel'), Gtk.ResponseType.REJECT,
|
||||
_('_OK'), Gtk.ResponseType.ACCEPT)
|
||||
self.set_window(self.__dlg, None, _('Select surname'))
|
||||
self.setup_configs('interface.lastnamedialog', 400, 400)
|
||||
|
||||
# build up a container to display all of the people of interest
|
||||
self.__model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_INT)
|
||||
self.__tree_view = Gtk.TreeView(self.__model)
|
||||
self.__tree_view = Gtk.TreeView(model=self.__model)
|
||||
col1 = Gtk.TreeViewColumn(_('Surname'), Gtk.CellRendererText(), text=0)
|
||||
col2 = Gtk.TreeViewColumn(_('Count'), Gtk.CellRendererText(), text=1)
|
||||
col1.set_resizable(True)
|
||||
@@ -1739,12 +1740,10 @@ class GuiDestinationOption(Gtk.Box):
|
||||
else:
|
||||
my_action = Gtk.FileChooserAction.SAVE
|
||||
|
||||
fcd = Gtk.FileChooserDialog(_("Save As"), action=my_action,
|
||||
parent=self.__uistate.window,
|
||||
buttons=(_('_Cancel'),
|
||||
Gtk.ResponseType.CANCEL,
|
||||
_('_Open'),
|
||||
Gtk.ResponseType.OK))
|
||||
fcd = Gtk.FileChooserDialog(title=_("Save As"), action=my_action,
|
||||
transient_for=self.__uistate.window)
|
||||
fcd.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Open'), Gtk.ResponseType.OK)
|
||||
|
||||
name = os.path.abspath(self.__option.get_value())
|
||||
if self.__option.get_directory_entry():
|
||||
|
||||
+10
-12
@@ -435,12 +435,10 @@ class PluginStatus(ManagedWindow):
|
||||
"""
|
||||
Select a file from the file system.
|
||||
"""
|
||||
fcd = Gtk.FileChooserDialog(_("Load Addon"),
|
||||
parent=self.__uistate.window,
|
||||
buttons=(_('_Cancel'),
|
||||
Gtk.ResponseType.CANCEL,
|
||||
_('_Open'),
|
||||
Gtk.ResponseType.OK))
|
||||
fcd = Gtk.FileChooserDialog(title=_("Load Addon"),
|
||||
transient_for=self.__uistate.window)
|
||||
fcd.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Open'), Gtk.ResponseType.OK)
|
||||
name = self.install_addon_path.get_text()
|
||||
dir = os.path.dirname(name)
|
||||
if not os.path.isdir(dir):
|
||||
@@ -688,10 +686,10 @@ class PluginTrace(ManagedWindow):
|
||||
) % {'str1': _("Plugin Error"), 'str2': name}
|
||||
ManagedWindow.__init__(self, uistate, track, self)
|
||||
|
||||
self.set_window(Gtk.Dialog("", uistate.window,
|
||||
Gtk.DialogFlags.DESTROY_WITH_PARENT,
|
||||
(_('_Close'), Gtk.ResponseType.CLOSE)),
|
||||
None, title)
|
||||
dlg = Gtk.Dialog(title="", transient_for=uistate.window,
|
||||
destroy_with_parent=True)
|
||||
dlg.add_button(_('_Close'), Gtk.ResponseType.CLOSE),
|
||||
self.set_window(dlg, None, title)
|
||||
self.setup_configs('interface.plugintrace', 600, 400)
|
||||
self.window.connect('response', self.close)
|
||||
|
||||
@@ -742,7 +740,7 @@ class ToolManagedWindowBase(ManagedWindow):
|
||||
self.format_menu = None
|
||||
self.style_button = None
|
||||
|
||||
window = Gtk.Dialog('Tool')
|
||||
window = Gtk.Dialog(title='Tool')
|
||||
self.set_window(window, None, self.get_title())
|
||||
|
||||
#self.window.connect('response', self.close)
|
||||
@@ -768,7 +766,7 @@ class ToolManagedWindowBase(ManagedWindow):
|
||||
|
||||
self.notebook = Gtk.Notebook()
|
||||
self.notebook.set_border_width(6)
|
||||
self.window.get_content_area().add(self.notebook)
|
||||
self.window.get_content_area().pack_start(self.notebook, True, True, 0)
|
||||
|
||||
self.results_text = Gtk.TextView()
|
||||
self.results_text.connect('button-press-event',
|
||||
|
||||
@@ -286,7 +286,7 @@ class ExportAssistant(ManagedWindow, Gtk.Assistant):
|
||||
self.set_page_complete(vbox, True)
|
||||
|
||||
def create_page_fileselect(self):
|
||||
self.chooser = Gtk.FileChooserWidget(Gtk.FileChooserAction.SAVE)
|
||||
self.chooser = Gtk.FileChooserWidget(action=Gtk.FileChooserAction.SAVE)
|
||||
self.chooser.set_homogeneous(False) # Fix for bug #8350.
|
||||
#add border
|
||||
self.chooser.set_border_width(12)
|
||||
|
||||
@@ -164,9 +164,9 @@ class WriterOptionBox:
|
||||
full_database_row.pack_start(label, True, True, 0)
|
||||
people_count = len(self.dbstate.db.get_person_handles())
|
||||
# translators: leave all/any {...} untranslated
|
||||
button = Gtk.Button(ngettext("{number_of} Person",
|
||||
"{number_of} People", people_count
|
||||
).format(number_of=people_count) )
|
||||
button = Gtk.Button(label=ngettext("{number_of} Person",
|
||||
"{number_of} People", people_count
|
||||
).format(number_of=people_count))
|
||||
button.set_tooltip_text(_("Click to see preview of unfiltered data"))
|
||||
button.set_size_request(107, -1)
|
||||
button.connect("clicked", self.show_preview_data)
|
||||
@@ -271,9 +271,9 @@ class WriterOptionBox:
|
||||
from gi.repository import Gtk
|
||||
from ...widgets import SimpleButton
|
||||
# translators: leave all/any {...} untranslated
|
||||
button = Gtk.Button(ngettext("{number_of} Person",
|
||||
"{number_of} People", 0
|
||||
).format(number_of=0) )
|
||||
button = Gtk.Button(label=ngettext("{number_of} Person",
|
||||
"{number_of} People", 0
|
||||
).format(number_of=0))
|
||||
button.set_size_request(107, -1)
|
||||
button.connect("clicked", self.show_preview_data)
|
||||
button.proxy_name = proxy_name
|
||||
@@ -283,7 +283,8 @@ class WriterOptionBox:
|
||||
label = Gtk.Label(label=_('_Person Filter') + COLON)
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_size_request(120, -1)
|
||||
label.set_padding(5, 0)
|
||||
label.set_margin_start(5)
|
||||
label.set_margin_end(5)
|
||||
label.set_use_underline(True)
|
||||
label.set_mnemonic_widget(self.filter_obj)
|
||||
box = Gtk.Box()
|
||||
@@ -301,7 +302,8 @@ class WriterOptionBox:
|
||||
label_note = Gtk.Label(label=_('_Note Filter') + COLON)
|
||||
label_note.set_halign(Gtk.Align.START)
|
||||
label_note.set_size_request(120, -1)
|
||||
label_note.set_padding(5, 0)
|
||||
label_note.set_margin_start(5)
|
||||
label_note.set_margin_end(5)
|
||||
label_note.set_use_underline(True)
|
||||
label_note.set_mnemonic_widget(self.filter_note)
|
||||
box = Gtk.Box()
|
||||
@@ -317,7 +319,8 @@ class WriterOptionBox:
|
||||
label = Gtk.Label(label=_("Privacy Filter") + COLON)
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_size_request(120, -1)
|
||||
label.set_padding(5, 0)
|
||||
label.set_margin_start(5)
|
||||
label.set_margin_end(5)
|
||||
box = Gtk.Box()
|
||||
box.pack_start(label, False, True, 0)
|
||||
box.add(self.private_check)
|
||||
@@ -327,7 +330,8 @@ class WriterOptionBox:
|
||||
label = Gtk.Label(label=_("Living Filter") + COLON)
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_size_request(120, -1)
|
||||
label.set_padding(5, 0)
|
||||
label.set_margin_start(5)
|
||||
label.set_margin_end(5)
|
||||
box = Gtk.Box()
|
||||
box.pack_start(label, False, True, 0)
|
||||
self.restrict_option = Gtk.ComboBox()
|
||||
@@ -339,7 +343,8 @@ class WriterOptionBox:
|
||||
label = Gtk.Label(label=_('Reference Filter') + COLON)
|
||||
label.set_halign(Gtk.Align.START)
|
||||
label.set_size_request(120, -1)
|
||||
label.set_padding(5, 0)
|
||||
label.set_margin_start(5)
|
||||
label.set_margin_end(5)
|
||||
box = Gtk.Box()
|
||||
box.pack_start(label, False, True, 0)
|
||||
box.pack_start(self.reference_filter, True, True, 0)
|
||||
|
||||
@@ -55,6 +55,7 @@ from gi.repository import Gtk
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from ...pluginmanager import GuiPluginManager
|
||||
from ...uimanager import valid_action_name
|
||||
from gramps.gen.plug import (CATEGORY_QR_PERSON, CATEGORY_QR_FAMILY, CATEGORY_QR_MEDIA,
|
||||
CATEGORY_QR_EVENT, CATEGORY_QR_SOURCE, CATEGORY_QR_MISC,
|
||||
CATEGORY_QR_PLACE, CATEGORY_QR_REPOSITORY,
|
||||
@@ -97,11 +98,9 @@ def create_web_connect_menu(dbstate, uistate, nav_group, handle, prefix):
|
||||
top = ("<placeholder id='WebConnect'><submenu>\n"
|
||||
'<attribute name="label" translatable="yes">'
|
||||
'Web Connection</attribute>\n')
|
||||
actions = []
|
||||
ofile = StringIO()
|
||||
ofile.write(top)
|
||||
#select the web connects to show
|
||||
showlst = []
|
||||
pmgr = GuiPluginManager.get_instance()
|
||||
plugins = pmgr.process_plugin_data('WebConnect')
|
||||
try:
|
||||
@@ -114,16 +113,19 @@ def create_web_connect_menu(dbstate, uistate, nav_group, handle, prefix):
|
||||
connections = flatten(connections)
|
||||
connections.sort(key=lambda plug: plug.name)
|
||||
actions = []
|
||||
for connect in connections:
|
||||
action = connect.key.replace(' ', '-')
|
||||
for indx, connect in enumerate(connections):
|
||||
# action would be better with "connect.key", but it seems to be
|
||||
# non-ASCII sometimes. So we use an action number instead.
|
||||
action = "web-con-%d" % indx
|
||||
ofile.write(MENUITEM.format(prefix=prefix, action=action,
|
||||
label=connect.name))
|
||||
callback = connect(dbstate, uistate, nav_group, handle)
|
||||
actions.append((action,
|
||||
lambda x, y: callback(x)))
|
||||
actions.append((action, make_web_connect_callback(callback)))
|
||||
ofile.write('</submenu></placeholder>\n')
|
||||
return (ofile.getvalue(), actions)
|
||||
|
||||
def make_web_connect_callback(func):
|
||||
return lambda x, y: func(x)
|
||||
|
||||
def create_quickreport_menu(category, dbstate, uistate, handle, prefix, track=[]):
|
||||
""" This functions querries the registered quick reports with
|
||||
@@ -155,7 +157,7 @@ def create_quickreport_menu(category, dbstate, uistate, handle, prefix, track=[]
|
||||
|
||||
showlst.sort(key=lambda x: x.name)
|
||||
for pdata in showlst:
|
||||
new_key = pdata.id.replace(' ', '-')
|
||||
new_key = valid_action_name("qr-%s" % pdata.id)
|
||||
ofile.write(MENUITEM.format(prefix=prefix, action=new_key,
|
||||
label=pdata.name))
|
||||
actions.append((new_key, make_quick_report_callback(
|
||||
|
||||
@@ -58,13 +58,11 @@ class FileEntry(Gtk.Box):
|
||||
else:
|
||||
my_action = Gtk.FileChooserAction.SAVE
|
||||
|
||||
dialog = Gtk.FileChooserDialog(self.title,
|
||||
self.parent,
|
||||
action=my_action,
|
||||
buttons=(_('_Cancel'),
|
||||
Gtk.ResponseType.CANCEL,
|
||||
_('_Open'),
|
||||
Gtk.ResponseType.OK))
|
||||
dialog = Gtk.FileChooserDialog(title=self.title,
|
||||
transient_for=self.parent,
|
||||
action=my_action)
|
||||
dialog.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Open'), Gtk.ResponseType.OK)
|
||||
|
||||
name = os.path.basename(self.entry.get_text())
|
||||
if self.dir:
|
||||
|
||||
@@ -175,7 +175,8 @@ class PaperFrame(Gtk.Box):
|
||||
|
||||
self.paper_grid.show_all()
|
||||
# Shift the grid from glade toplevel window to this box
|
||||
self.paper_grid.reparent(self)
|
||||
self.paper_grid.get_parent().remove(self.paper_grid)
|
||||
self.add(self.paper_grid)
|
||||
# need to get rid of glade toplevel now that we are done with it.
|
||||
self.top.destroy()
|
||||
|
||||
|
||||
@@ -414,7 +414,7 @@ class StyleEditor(ManagedWindow):
|
||||
spin.set_value(t.get_column_width(i))
|
||||
self.column.append(spin)
|
||||
hbox.pack_start(spin, False, False, 6)
|
||||
hbox.pack_start(Gtk.Label('%'), False, False, 6)
|
||||
hbox.pack_start(Gtk.Label(label='%'), False, False, 6)
|
||||
hbox.show_all()
|
||||
self.vbox.pack_start(hbox, False, False, 3)
|
||||
|
||||
|
||||
+27
-2
@@ -213,8 +213,17 @@ class UIManager():
|
||||
# need to copy the tree so we can preserve original for later edits.
|
||||
editable = copy.deepcopy(self.et_xml)
|
||||
iterator(editable) # clean up tree to builder specifications
|
||||
xml_str = ET.tostring(editable, encoding="unicode")
|
||||
#print(xml_str)
|
||||
# The following should work, but seems to have a Gtk bug
|
||||
# xml_str = ET.tostring(editable, encoding="unicode")
|
||||
|
||||
xml_str = ET.tostring(editable).decode(encoding='ascii')
|
||||
|
||||
# debugging
|
||||
# with open('try.xml', 'w', encoding='utf8') as file:
|
||||
# file.write(xml_str)
|
||||
# with open('try.xml', encoding='utf8') as file:
|
||||
# xml_str = file.read()
|
||||
# print(xml_str)
|
||||
self.builder = Gtk.Builder()
|
||||
self.builder.set_translation_domain(glocale.get_localedomain())
|
||||
self.builder.add_from_string(xml_str)
|
||||
@@ -355,6 +364,8 @@ class UIManager():
|
||||
else:
|
||||
window_group = group.act_group = self.app.window
|
||||
for item in group.actionlist:
|
||||
if not Gio.action_name_is_valid(item[ACTION_NAME]):
|
||||
LOG.warning('**Invalid action name %s', item[ACTION_NAME])
|
||||
# deal with accelerator overrides from a file
|
||||
accel = self.accel_dict.get(group.prefix + item[ACTION_NAME])
|
||||
if accel:
|
||||
@@ -517,3 +528,17 @@ class UIManager():
|
||||
with open(filename, 'r') as hndl:
|
||||
accels = hndl.read()
|
||||
self.accel_dict = ast.literal_eval(accels)
|
||||
|
||||
|
||||
INVALID_CHARS = [' ', '_', '(', ')', ',', "'"]
|
||||
|
||||
|
||||
def valid_action_name(text):
|
||||
""" This function cleans up action names to avoid some illegal
|
||||
characters. It does NOT clean up non-ASCII characters.
|
||||
This is used for plugin IDs to clean them up. It would be better if we
|
||||
made all plugin ids:
|
||||
ASCII Alphanumeric and the '.' or '-' characters."""
|
||||
for char in INVALID_CHARS:
|
||||
text = text.replace(char, '-')
|
||||
return text
|
||||
|
||||
+5
-4
@@ -551,16 +551,17 @@ def color_graph_box(alive=False, gender=Person.MALE):
|
||||
|
||||
def hex_to_rgb_float(value):
|
||||
"""
|
||||
Convert a hexademical value #FF00FF to rgb. Returns tuple of float between
|
||||
0 and 1
|
||||
Convert a 6 or 12 digit hexademical value to rgb. Returns tuple of floats
|
||||
between 0 and 1.
|
||||
"""
|
||||
value = value.lstrip('#')
|
||||
lenv = len(value)
|
||||
return tuple(int(value[i:i+lenv//3], 16)/256.0 for i in range(0, lenv, lenv//3))
|
||||
return tuple(int(value[i:i+lenv//3], 16)/16.0**(lenv//3)
|
||||
for i in range(0, lenv, lenv//3))
|
||||
|
||||
def hex_to_rgb(value):
|
||||
"""
|
||||
Convert a hexadecimal value #FF00FF to rgb. Returns tuple of integers
|
||||
Convert a 6 or 12 digit hexadecimal value to rgb. Returns tuple of integers.
|
||||
"""
|
||||
value = value.lstrip('#')
|
||||
lenv = len(value)
|
||||
|
||||
@@ -92,7 +92,7 @@ from .configure import GrampsPreferences
|
||||
from .aboutdialog import GrampsAboutDialog
|
||||
from .navigator import Navigator
|
||||
from .views.tags import Tags
|
||||
from .uimanager import ActionGroup
|
||||
from .uimanager import ActionGroup, valid_action_name
|
||||
from gramps.gen.lib import (Person, Surname, Family, Media, Note, Place,
|
||||
Source, Repository, Citation, Event, EventType,
|
||||
ChildRef)
|
||||
@@ -1429,7 +1429,7 @@ class ViewManager(CLIManager):
|
||||
pdatas = hash_data[key]
|
||||
pdatas.sort(key=lambda x: x.name)
|
||||
for pdata in pdatas:
|
||||
new_key = pdata.id.replace(' ', '-')
|
||||
new_key = valid_action_name(pdata.id)
|
||||
ofile.write(menuitem % (new_key, pdata.name))
|
||||
actions.append((new_key, func(pdata, self.dbstate,
|
||||
self.uistate)))
|
||||
@@ -1649,9 +1649,9 @@ class QuickBackup(ManagedWindow): # TODO move this class into its own module
|
||||
self.user = user
|
||||
|
||||
ManagedWindow.__init__(self, uistate, [], self.__class__)
|
||||
window = Gtk.Dialog('',
|
||||
self.uistate.window,
|
||||
Gtk.DialogFlags.DESTROY_WITH_PARENT, None)
|
||||
window = Gtk.Dialog(title='',
|
||||
transient_for=self.uistate.window,
|
||||
destroy_with_parent=True)
|
||||
self.set_window(window, None, _("Gramps XML Backup"))
|
||||
self.setup_configs('interface.quick-backup', 500, 150)
|
||||
close_button = window.add_button(_('_Close'),
|
||||
@@ -1787,12 +1787,10 @@ class QuickBackup(ManagedWindow): # TODO move this class into its own module
|
||||
"""
|
||||
fdialog = Gtk.FileChooserDialog(
|
||||
title=_("Select backup directory"),
|
||||
parent=self.window,
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER,
|
||||
buttons=(_('_Cancel'),
|
||||
Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'),
|
||||
Gtk.ResponseType.OK))
|
||||
transient_for=self.window,
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER)
|
||||
fdialog.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'), Gtk.ResponseType.OK)
|
||||
mpath = path_entry.get_text()
|
||||
if not mpath:
|
||||
mpath = HOME_DIR
|
||||
|
||||
@@ -269,7 +269,7 @@ class BookmarksDialog(ManagedWindow):
|
||||
|
||||
def draw_window(self):
|
||||
"""Draw the bookmark dialog box."""
|
||||
self.top = Gtk.Dialog(parent=self.parent_window)
|
||||
self.top = Gtk.Dialog(transient_for=self.parent_window)
|
||||
self.top.vbox.set_spacing(5)
|
||||
label = Gtk.Label(label='<span size="larger" weight="bold">%s</span>'
|
||||
% _("Organize Bookmarks"))
|
||||
|
||||
@@ -732,7 +732,8 @@ class ListView(NavigationView):
|
||||
[self.drag_list_info().target()],
|
||||
Gdk.DragAction.COPY)
|
||||
|
||||
self.uistate.modify_statusbar(self.dbstate)
|
||||
if self.uistate.viewmanager.active_page == self:
|
||||
self.uistate.modify_statusbar(self.dbstate)
|
||||
|
||||
def row_add(self, handle_list):
|
||||
"""
|
||||
@@ -1058,11 +1059,11 @@ class ListView(NavigationView):
|
||||
####################################################################
|
||||
def export(self, *obj):
|
||||
chooser = Gtk.FileChooserDialog(
|
||||
_("Export View as Spreadsheet"),
|
||||
self.uistate.window,
|
||||
Gtk.FileChooserAction.SAVE,
|
||||
(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Save'), Gtk.ResponseType.OK))
|
||||
title=_("Export View as Spreadsheet"),
|
||||
transient_for=self.uistate.window,
|
||||
action=Gtk.FileChooserAction.SAVE)
|
||||
chooser.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Save'), Gtk.ResponseType.OK)
|
||||
chooser.set_do_overwrite_confirmation(True)
|
||||
|
||||
combobox = Gtk.ComboBoxText()
|
||||
|
||||
@@ -331,7 +331,8 @@ class NavigationView(PageView):
|
||||
"""
|
||||
A dialog to move to a Gramps ID entered by the user.
|
||||
"""
|
||||
dialog = Gtk.Dialog(_('Jump to by Gramps ID'), self.uistate.window)
|
||||
dialog = Gtk.Dialog(title=_('Jump to by Gramps ID'),
|
||||
transient_for=self.uistate.window)
|
||||
dialog.set_border_width(12)
|
||||
label = Gtk.Label(label='<span weight="bold" size="larger">%s</span>' %
|
||||
_('Jump to by Gramps ID'))
|
||||
@@ -434,19 +435,15 @@ class NavigationView(PageView):
|
||||
hobj = self.get_history()
|
||||
menu_len = min(len(items) - 1, MRU_SIZE)
|
||||
|
||||
for index in range(0, menu_len):
|
||||
name, obj = navigation_label(self.dbstate.db, nav_type,
|
||||
items[index])
|
||||
menus += menuitem % (nav_type, index, html.escape(name))
|
||||
self.mru_ui = [MRU_TOP + menus + MRU_BTM]
|
||||
|
||||
mitems = items[-MRU_SIZE - 1:-1] # Ignore current handle
|
||||
mitems.reverse()
|
||||
data = []
|
||||
for index, handle in enumerate(mitems):
|
||||
data.append(('%s%02d'%(nav_type, index),
|
||||
make_callback(hobj.push, handle),
|
||||
"%s%d" % (mod_key(), index)))
|
||||
for index in range(menu_len - 1, -1, -1):
|
||||
name, _obj = navigation_label(self.dbstate.db, nav_type,
|
||||
items[index])
|
||||
menus += menuitem % (nav_type, index, html.escape(name))
|
||||
data.append(('%s%02d' % (nav_type, index),
|
||||
make_callback(hobj.push, items[index]),
|
||||
"%s%d" % (mod_key(), menu_len - 1 - index)))
|
||||
self.mru_ui = [MRU_TOP + menus + MRU_BTM]
|
||||
|
||||
self.mru_action = ActionGroup(name=self.title + '/MRU')
|
||||
self.mru_action.add_actions(data)
|
||||
|
||||
@@ -434,10 +434,10 @@ class PageView(DbGUIElement, metaclass=ABCMeta):
|
||||
View. The user typically defines self.action_list and
|
||||
self.action_toggle_list in this function.
|
||||
"""
|
||||
self._add_toggle_action('Sidebar', self.__sidebar_toggled, '',
|
||||
self.sidebar.get_property('visible'))
|
||||
self._add_toggle_action('Bottombar', self.__bottombar_toggled, '',
|
||||
self.bottombar.get_property('visible'))
|
||||
self._add_toggle_action('Sidebar', self.__sidebar_toggled,
|
||||
'<shift><PRIMARY>R', self.sidebar.get_property('visible'))
|
||||
self._add_toggle_action('Bottombar', self.__bottombar_toggled,
|
||||
'<shift><PRIMARY>B', self.bottombar.get_property('visible'))
|
||||
|
||||
def __build_action_group(self):
|
||||
"""
|
||||
|
||||
@@ -241,14 +241,21 @@ class Tags(DbGUIElement):
|
||||
tag_menu = ''
|
||||
menuitem = '''
|
||||
<item>
|
||||
<attribute name="action">win.TAG_%s</attribute>
|
||||
<attribute name="action">win.%s</attribute>
|
||||
<attribute name="label">%s</attribute>
|
||||
</item>'''
|
||||
|
||||
for tag_name, handle in self.__tag_list:
|
||||
tag_menu += menuitem % (handle, tag_name)
|
||||
actions.append(('TAG_%s' % handle,
|
||||
tag_menu += menuitem % ("TAG-%s" % handle,
|
||||
"Add tag '%s'" % tag_name)
|
||||
actions.append(('TAG-%s' % handle,
|
||||
make_callback(self.tag_selected_rows, handle)))
|
||||
for tag_name, handle in self.__tag_list:
|
||||
tag_menu += menuitem % ("R-TAG-%s" % handle,
|
||||
"Remove tag '%s'" % tag_name)
|
||||
actions.append(('R-TAG-%s' % handle,
|
||||
make_callback(self.remove_tag_selected_rows,
|
||||
handle)))
|
||||
tag_menu = TAG_MENU % tag_menu
|
||||
|
||||
self.tag_ui = [TAG_1 % tag_menu, TAG_2, TAG_3 % tag_menu]
|
||||
@@ -315,6 +322,28 @@ class Tags(DbGUIElement):
|
||||
view.add_tag(trans, object_handle, tag_handle)
|
||||
status.end()
|
||||
|
||||
def remove_tag_selected_rows(self, tag_handle):
|
||||
"""
|
||||
Remove tag from selected rows.
|
||||
"""
|
||||
view = self.uistate.viewmanager.active_page
|
||||
selected = view.selected_handles()
|
||||
# Make the dialog modal so that the user can't start another
|
||||
# database transaction while the one setting tags is still running.
|
||||
pmon = progressdlg.ProgressMonitor(progressdlg.GtkProgressDialog,
|
||||
("", self.uistate.window, Gtk.DialogFlags.MODAL), popup_time=2)
|
||||
status = progressdlg.LongOpStatus(msg=_("Adding Tags"),
|
||||
total_steps=len(selected),
|
||||
interval=len(selected)//20)
|
||||
pmon.add_op(status)
|
||||
tag = self.db.get_tag_from_handle(tag_handle)
|
||||
msg = _('Tag Selection (%s)') % tag.get_name()
|
||||
with DbTxn(msg, self.db) as trans:
|
||||
for object_handle in selected:
|
||||
status.heartbeat()
|
||||
view.remove_tag(trans, object_handle, tag_handle)
|
||||
status.end()
|
||||
|
||||
def cb_menu_position(*args):
|
||||
"""
|
||||
Determine the position of the popup menu.
|
||||
@@ -430,7 +459,7 @@ class OrganizeTagsDialog(ManagedWindow):
|
||||
Create a dialog box to organize tags.
|
||||
"""
|
||||
# pylint: disable-msg=E1101
|
||||
top = Gtk.Dialog(parent=self.parent_window)
|
||||
top = Gtk.Dialog(transient_for=self.parent_window)
|
||||
top.vbox.set_spacing(5)
|
||||
label = Gtk.Label(label='<span size="larger" weight="bold">%s</span>'
|
||||
% _("Organize Tags"))
|
||||
@@ -659,7 +688,7 @@ class EditTag(ManagedWindow):
|
||||
Create a dialog box to enter a new tag.
|
||||
"""
|
||||
# pylint: disable-msg=E1101
|
||||
top = Gtk.Dialog(parent=self.parent_window)
|
||||
top = Gtk.Dialog(transient_for=self.parent_window)
|
||||
top.vbox.set_spacing(5)
|
||||
|
||||
hbox = Gtk.Box()
|
||||
|
||||
@@ -143,7 +143,7 @@ class PlaceBaseModel:
|
||||
value = conv_lat_lon('0', data[3], format='DEG')[1]
|
||||
if not value:
|
||||
return _("Error in format")
|
||||
return value
|
||||
return ("\u202d" + value + "\u202e") if glocale.rtl_locale else value
|
||||
|
||||
def column_latitude(self, data):
|
||||
if not data[4]:
|
||||
@@ -151,7 +151,7 @@ class PlaceBaseModel:
|
||||
value = conv_lat_lon(data[4], '0', format='DEG')[0]
|
||||
if not value:
|
||||
return _("Error in format")
|
||||
return value
|
||||
return ("\u202d" + value + "\u202e") if glocale.rtl_locale else value
|
||||
|
||||
def sort_longitude(self, data):
|
||||
if not data[3]:
|
||||
|
||||
@@ -403,7 +403,8 @@ class GrampletBar(Gtk.Notebook):
|
||||
"""
|
||||
for gramplet in self.get_children():
|
||||
tablabel = self.get_tab_label(gramplet)
|
||||
tablabel.use_close(config.get('interface.grampletbar-close'))
|
||||
if not isinstance(tablabel, Gtk.Label):
|
||||
tablabel.use_close(config.get('interface.grampletbar-close'))
|
||||
|
||||
def __delete_clicked(self, button, gramplet):
|
||||
"""
|
||||
@@ -629,13 +630,11 @@ class DetachedWindow(ManagedWindow):
|
||||
self.grampletbar = grampletbar
|
||||
self.gramplet = gramplet
|
||||
|
||||
ManagedWindow.__init__(self, gramplet.uistate, [],
|
||||
self.title)
|
||||
self.set_window(Gtk.Dialog("", gramplet.uistate.window,
|
||||
Gtk.DialogFlags.DESTROY_WITH_PARENT,
|
||||
(_('_Close'), Gtk.ResponseType.CLOSE)),
|
||||
None,
|
||||
self.title)
|
||||
ManagedWindow.__init__(self, gramplet.uistate, [], self.title)
|
||||
dlg = Gtk.Dialog(transient_for=gramplet.uistate.window,
|
||||
destroy_with_parent = True)
|
||||
dlg.add_button(_('_Close'), Gtk.ResponseType.CLOSE)
|
||||
self.set_window(dlg, None, self.title)
|
||||
self.window.move(x_pos, y_pos)
|
||||
self.window.set_default_size(gramplet.detached_width,
|
||||
gramplet.detached_height)
|
||||
@@ -700,7 +699,8 @@ class DetachedWindow(ManagedWindow):
|
||||
self.gramplet.detached_width = size[0]
|
||||
self.gramplet.detached_height = size[1]
|
||||
self.gramplet.detached_window = None
|
||||
self.gramplet.reparent(self.grampletbar)
|
||||
self.notebook.remove(self.gramplet)
|
||||
self.grampletbar.add(self.gramplet)
|
||||
ManagedWindow.close(self, *args)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@@ -31,6 +31,7 @@ GrampletView interface.
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Pango
|
||||
from xml.sax.saxutils import escape
|
||||
import time
|
||||
import os
|
||||
import configparser
|
||||
@@ -49,7 +50,7 @@ from gramps.gen.const import URL_MANUAL_PAGE, VERSION_DIR, COLON
|
||||
from ..editors import EditPerson, EditFamily
|
||||
from ..managedwindow import ManagedWindow
|
||||
from ..utils import is_right_click, match_primary_mask, get_link_color
|
||||
from ..uimanager import ActionGroup
|
||||
from ..uimanager import ActionGroup, valid_action_name
|
||||
from ..plug import make_gui_option
|
||||
from ..plug.quick import run_quick_report_by_name
|
||||
from ..display import display_help, display_url
|
||||
@@ -232,12 +233,11 @@ class GrampletWindow(ManagedWindow):
|
||||
self.docked_state = gramplet.gstate
|
||||
# Now detach it
|
||||
self.gramplet.set_state("detached")
|
||||
ManagedWindow.__init__(self, gramplet.uistate, [],
|
||||
self.title)
|
||||
self.set_window(Gtk.Dialog("", gramplet.uistate.window,
|
||||
Gtk.DialogFlags.DESTROY_WITH_PARENT,
|
||||
(_('_Close'), Gtk.ResponseType.CLOSE)),
|
||||
None, self.title)
|
||||
ManagedWindow.__init__(self, gramplet.uistate, [], self.title)
|
||||
dlg = Gtk.Dialog(transient_for=gramplet.uistate.window,
|
||||
destroy_with_parent=True)
|
||||
dlg.add_button(_('_Close'), Gtk.ResponseType.CLOSE)
|
||||
self.set_window(dlg, None, self.title)
|
||||
cfg_name = gramplet.gname.replace(' ', '').lower() + '-gramplet'
|
||||
self.setup_configs('interface.' + cfg_name,
|
||||
gramplet.detached_width, gramplet.detached_height)
|
||||
@@ -245,7 +245,8 @@ class GrampletWindow(ManagedWindow):
|
||||
# add gramplet:
|
||||
if self.gramplet.pui:
|
||||
self.gramplet.pui.active = True
|
||||
self.gramplet.mainframe.reparent(self.window.vbox)
|
||||
self.gramplet.mainframe.get_parent().remove(self.gramplet.mainframe)
|
||||
self.window.vbox.add(self.gramplet.mainframe)
|
||||
self.window.connect('response', self.handle_response)
|
||||
self.show()
|
||||
# After we show, then we hide:
|
||||
@@ -309,7 +310,8 @@ class GrampletWindow(ManagedWindow):
|
||||
expand = self.gramplet.gstate == "maximized" and self.gramplet.expand
|
||||
column = pane.columns[col]
|
||||
parent = self.gramplet.pane.get_column_frame(self.gramplet.column)
|
||||
self.gramplet.mainframe.reparent(parent)
|
||||
self.gramplet.mainframe.get_parent().remove(self.gramplet.mainframe)
|
||||
parent.add(self.gramplet.mainframe)
|
||||
if self.gramplet.pui:
|
||||
self.gramplet.pui.active = self.gramplet.pane.pageview.active
|
||||
for gframe in stack:
|
||||
@@ -971,8 +973,11 @@ class GridGramplet(GuiGramplet):
|
||||
|
||||
def set_title(self, new_title, set_override=True):
|
||||
# can't do it if already titled that way
|
||||
if self.title == new_title: return True
|
||||
if new_title in self.pane.gramplet_map: return False
|
||||
if self.title == new_title:
|
||||
return True
|
||||
if(new_title in self.pane.gramplet_map or
|
||||
new_title != escape(new_title)): # avoid XML specific characters
|
||||
return False
|
||||
if set_override:
|
||||
self.title_override = True
|
||||
del self.pane.gramplet_map[self.title]
|
||||
@@ -1464,21 +1469,22 @@ class GrampletPane(Gtk.ScrolledWindow):
|
||||
actions = []
|
||||
r_menuitems = ''
|
||||
a_menuitems = ''
|
||||
names = [gplug.name for gplug in PLUGMAN.get_reg_gramplets()
|
||||
if gplug.navtypes == []
|
||||
or 'Dashboard' in gplug.navtypes]
|
||||
names.sort()
|
||||
for name in names:
|
||||
action_name = name.replace(' ', '-')
|
||||
a_menuitems += menuitem % (action_name, name)
|
||||
plugs = [gplug for gplug in PLUGMAN.get_reg_gramplets() if
|
||||
gplug.navtypes == [] or 'Dashboard' in gplug.navtypes]
|
||||
plugs.sort(key=lambda x: x.name)
|
||||
for plug in plugs:
|
||||
action_name = valid_action_name(plug.id)
|
||||
a_menuitems += menuitem % (action_name, plug.name)
|
||||
actions.append((action_name,
|
||||
make_callback(self.add_gramplet, name)))
|
||||
make_callback(self.add_gramplet, plug.name)))
|
||||
names = [gramplet.title for gramplet in self.closed_gramplets]
|
||||
names.extend(opts["title"] for opts in self.closed_opts)
|
||||
names.sort()
|
||||
if len(names) > 0:
|
||||
for name in names:
|
||||
action_name = name.replace(' ', '-')
|
||||
# 'name' could be non-ASCII when in non-English language
|
||||
# action names must be in ASCII, so use 'id' instead.
|
||||
action_name = valid_action_name(str(id(name)))
|
||||
r_menuitems += menuitem % (action_name, name)
|
||||
actions.append((action_name,
|
||||
make_callback(self.restore_gramplet,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
__all__ = ["LinkLabel", "EditLabel", "BasicLabel", "GenderLabel",
|
||||
__all__ = ["LinkLabel", "EditLabel", "BasicLabel",
|
||||
"MarkupLabel", "DualMarkupLabel"]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -127,7 +127,7 @@ class LinkLabel(Gtk.EventBox):
|
||||
hbox = Gtk.Box()
|
||||
hbox.pack_start(self.label, False, False, 0)
|
||||
if label[1]:
|
||||
hbox.pack_start(GenderLabel(label[1]), False, False, 0)
|
||||
hbox.pack_start(Gtk.Label(label=label[1]), False, False, 0)
|
||||
hbox.set_spacing(4)
|
||||
self.add(hbox)
|
||||
|
||||
@@ -138,7 +138,10 @@ class LinkLabel(Gtk.EventBox):
|
||||
self.connect('realize', realize_cb)
|
||||
|
||||
def set_padding(self, x, y):
|
||||
self.label.set_padding(x, y)
|
||||
self.label.set_margin_start(x)
|
||||
self.label.set_margin_end(x)
|
||||
self.label.set_margin_top(x)
|
||||
self.label.set_margin_bottom(x)
|
||||
|
||||
def enter_text(self, obj, event, handle):
|
||||
if self.emph:
|
||||
@@ -205,20 +208,6 @@ class BasicLabel(Gtk.Label):
|
||||
self.set_ellipsize(ellipsize)
|
||||
self.show()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GenderLabel class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class GenderLabel(Gtk.Label):
|
||||
|
||||
def __init__(self, text):
|
||||
Gtk.Label.__init__(self, label=text)
|
||||
self.set_halign(Gtk.Align.START)
|
||||
if win():
|
||||
pangoFont = Pango.FontDescription('Arial')
|
||||
self.override_font(pangoFont)
|
||||
self.show()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -247,7 +236,6 @@ class DualMarkupLabel(Gtk.Box):
|
||||
label.set_use_markup(True)
|
||||
|
||||
self.pack_start(label, False, False, 0)
|
||||
b = GenderLabel(alt)
|
||||
b.set_use_markup(True)
|
||||
b = Gtk.Label(label=alt)
|
||||
self.pack_start(b, False, False, 4)
|
||||
self.show()
|
||||
|
||||
@@ -64,8 +64,6 @@ from gramps.gen.errors import ValidationError
|
||||
_RETURN = Gdk.keyval_from_name("Return")
|
||||
_KP_ENTER = Gdk.keyval_from_name("KP_Enter")
|
||||
|
||||
# table for skipping illegal control chars
|
||||
INVISIBLE = dict.fromkeys(list(range(32)))
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -141,14 +139,10 @@ class MonitoredEntry:
|
||||
self.obj.connect(signal, callback, *data)
|
||||
|
||||
def _on_quit(self, obj, event):
|
||||
text = obj.get_text().translate(INVISIBLE).strip()
|
||||
self.set_val(text)
|
||||
obj.set_text(text)
|
||||
self.set_val(obj.get_text().strip())
|
||||
|
||||
def _on_change(self, obj):
|
||||
new_text = obj.get_text().translate(INVISIBLE)
|
||||
self.set_val(new_text)
|
||||
obj.set_text(new_text)
|
||||
self.set_val(obj.get_text())
|
||||
if self.changed:
|
||||
self.changed(obj)
|
||||
|
||||
@@ -183,36 +177,8 @@ class MonitoredEntryIndicator(MonitoredEntry):
|
||||
autolist=None, changed=None):
|
||||
MonitoredEntry.__init__(self, obj, set_val, get_val, read_only,
|
||||
autolist, changed)
|
||||
self.origcolor = obj.get_style_context().get_color(Gtk.StateType.NORMAL)
|
||||
if get_val():
|
||||
self.indicatorshown = False
|
||||
else:
|
||||
self.indicatorshown = True
|
||||
self.indicator = indicator
|
||||
self.obj.set_text(indicator)
|
||||
rgba = Gdk.RGBA()
|
||||
Gdk.RGBA.parse(rgba, 'grey')
|
||||
self.obj.override_color(Gtk.StateType.NORMAL, rgba)
|
||||
self.obj.override_font(Pango.FontDescription('sans italic'))
|
||||
self.fockey = self.obj.connect('focus-in-event',
|
||||
self._obj_focus)
|
||||
self.obj.set_placeholder_text(indicator)
|
||||
|
||||
def _on_change(self, obj):
|
||||
if not self.indicatorshown:
|
||||
self.set_val(str(obj.get_text()))
|
||||
if self.changed:
|
||||
self.changed(obj)
|
||||
|
||||
def _obj_focus(self, widg, eve):
|
||||
"""
|
||||
callback for when prefix obtains focus
|
||||
"""
|
||||
self.set_text('')
|
||||
self.obj.override_color(Gtk.StateType.NORMAL, self.origcolor)
|
||||
self.obj.override_font(Pango.FontDescription('normal'))
|
||||
self.obj.disconnect(self.fockey)
|
||||
self.indicatorshown = False
|
||||
return False
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
@@ -84,7 +84,6 @@ class Photo(Gtk.EventBox):
|
||||
elif is_right_click(event):
|
||||
if self.handle and self.uistate:
|
||||
self.menu = Gtk.Menu()
|
||||
self.menu.set_title(_("Media Object"))
|
||||
add_menuitem(self.menu, _("Make Active Media"), widget,
|
||||
lambda obj: self.uistate.set_active(self.handle, "Media"))
|
||||
self.menu.popup(None, None, None, None, event.button, event.time)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import GdkPixbuf
|
||||
from gi.repository import GObject
|
||||
from gi.repository import GLib, GObject
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -305,7 +305,7 @@ class SelectionWidget(Gtk.ScrolledWindow):
|
||||
viewport_size.height)
|
||||
self._rescale()
|
||||
self.loaded = True
|
||||
except (GObject.GError, OSError):
|
||||
except (GLib.GError, OSError):
|
||||
self.show_missing()
|
||||
|
||||
def show_missing(self):
|
||||
|
||||
@@ -531,7 +531,9 @@ class StyledTextEditor(Gtk.TextView):
|
||||
"""
|
||||
self.uimanager = uimanager
|
||||
# build the toolbar
|
||||
builder = Gtk.Builder.new_from_string(FORMAT_TOOLBAR, -1)
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain(glocale.get_localedomain())
|
||||
builder.add_from_string(FORMAT_TOOLBAR)
|
||||
# define the actions...
|
||||
_actions = [
|
||||
('ITALIC', self._on_toggle_action_activate, '<PRIMARY>i', False),
|
||||
@@ -774,7 +776,8 @@ class StyledTextEditor(Gtk.TextView):
|
||||
for style, style_value in changed_styles.items():
|
||||
if style in types:
|
||||
action = self.uimanager.get_action(
|
||||
self.action_group, str(StyledTextTagType(style)).upper())
|
||||
self.action_group,
|
||||
StyledTextTagType(style).xml_str().upper())
|
||||
action.change_state(Variant.new_boolean(style_value))
|
||||
elif (style == StyledTextTagType.FONTFACE):
|
||||
self.fontface.set_text(style_value)
|
||||
|
||||
@@ -46,6 +46,11 @@ from gi.repository import Gtk
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from .undoablebuffer import Stack
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
|
||||
# table for skipping illegal control chars
|
||||
INVISIBLE = dict.fromkeys(list(range(32)) + [0x202d, 0x202e])
|
||||
|
||||
|
||||
class UndoableInsertEntry:
|
||||
"""something that has been inserted into our Gtk.editable"""
|
||||
@@ -84,6 +89,10 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
|
||||
|
||||
Additional features:
|
||||
- Undo and Redo on CTRL-Z/CTRL-SHIFT-Z
|
||||
|
||||
- ltr_mode (forces the field to always be left to right, useful for GPS
|
||||
coordinates and similar numbers that might contain RTL characters.
|
||||
See set_ltr_mode.
|
||||
"""
|
||||
__gtype_name__ = 'UndoableEntry'
|
||||
|
||||
@@ -94,12 +103,12 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
|
||||
undo_stack_size = 50
|
||||
|
||||
def __init__(self):
|
||||
Gtk.Entry.__init__(self)
|
||||
self.undo_stack = Stack(self.undo_stack_size)
|
||||
self.redo_stack = []
|
||||
self.not_undoable_action = False
|
||||
self.undo_in_progress = False
|
||||
|
||||
self.ltr_mode = False
|
||||
Gtk.Entry.__init__(self)
|
||||
self.connect('delete-text', self._on_delete_text)
|
||||
self.connect('key-press-event', self._on_key_press_event)
|
||||
|
||||
@@ -156,10 +165,17 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
|
||||
return False
|
||||
return True
|
||||
|
||||
text = text.translate(INVISIBLE)
|
||||
if self.ltr_mode:
|
||||
if position == 0:
|
||||
position = 1
|
||||
elif position >= self.get_text_length():
|
||||
position -= 1
|
||||
|
||||
if not self.undo_in_progress:
|
||||
self.__empty_redo_stack()
|
||||
while not self.not_undoable_action:
|
||||
undo_action = self.insertclass(text, length, self.get_position())
|
||||
undo_action = self.insertclass(text, length, position)
|
||||
try:
|
||||
prev_insert = self.undo_stack.pop()
|
||||
except IndexError:
|
||||
@@ -180,6 +196,7 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
|
||||
self.get_buffer().insert_text(position, text, len(text))
|
||||
return position + len(text)
|
||||
|
||||
|
||||
def _on_delete_text(self, editable, start, end):
|
||||
def can_be_merged(prev, cur):
|
||||
"""
|
||||
@@ -206,32 +223,49 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
|
||||
return False
|
||||
return True
|
||||
|
||||
if not self.undo_in_progress:
|
||||
self.__empty_redo_stack()
|
||||
if self.not_undoable_action:
|
||||
return
|
||||
undo_action = self.deleteclass(editable, start, end)
|
||||
try:
|
||||
prev_delete = self.undo_stack.pop()
|
||||
except IndexError:
|
||||
self.undo_stack.append(undo_action)
|
||||
return
|
||||
if not isinstance(prev_delete, self.deleteclass):
|
||||
self.undo_stack.append(prev_delete)
|
||||
self.undo_stack.append(undo_action)
|
||||
return
|
||||
if can_be_merged(prev_delete, undo_action):
|
||||
if prev_delete.start == undo_action.start: # delete key used
|
||||
prev_delete.text += undo_action.text
|
||||
prev_delete.end += (undo_action.end - undo_action.start)
|
||||
else: # Backspace used
|
||||
prev_delete.text = "%s%s" % (undo_action.text,
|
||||
prev_delete.text)
|
||||
prev_delete.start = undo_action.start
|
||||
self.undo_stack.append(prev_delete)
|
||||
else:
|
||||
self.undo_stack.append(prev_delete)
|
||||
self.undo_stack.append(undo_action)
|
||||
if self.ltr_mode: # limit deletes to area between LRO/PDF
|
||||
if start == 0:
|
||||
start = 1
|
||||
elif start > self.get_text_length() - 1:
|
||||
start -= 1
|
||||
if end == 0:
|
||||
end = 1
|
||||
elif end > self.get_text_length() - 1:
|
||||
end -= 1
|
||||
elif end < 0:
|
||||
end = self.get_text_length() - 1
|
||||
|
||||
while True:
|
||||
if not self.undo_in_progress:
|
||||
self.__empty_redo_stack()
|
||||
if self.not_undoable_action:
|
||||
break
|
||||
undo_action = self.deleteclass(self, start, end)
|
||||
try:
|
||||
prev_delete = self.undo_stack.pop()
|
||||
except IndexError:
|
||||
self.undo_stack.append(undo_action)
|
||||
break
|
||||
if not isinstance(prev_delete, self.deleteclass):
|
||||
self.undo_stack.append(prev_delete)
|
||||
self.undo_stack.append(undo_action)
|
||||
break
|
||||
if can_be_merged(prev_delete, undo_action):
|
||||
if prev_delete.start == undo_action.start: # delete key used
|
||||
prev_delete.text += undo_action.text
|
||||
prev_delete.end += (undo_action.end - undo_action.start)
|
||||
else: # Backspace used
|
||||
prev_delete.text = "%s%s" % (undo_action.text,
|
||||
prev_delete.text)
|
||||
prev_delete.start = undo_action.start
|
||||
self.undo_stack.append(prev_delete)
|
||||
else:
|
||||
self.undo_stack.append(prev_delete)
|
||||
self.undo_stack.append(undo_action)
|
||||
break
|
||||
self.get_buffer().delete_text(start, end - start)
|
||||
self.stop_emission_by_name('delete-text')
|
||||
return True
|
||||
|
||||
def begin_not_undoable_action(self):
|
||||
"""don't record the next actions
|
||||
@@ -323,3 +357,40 @@ class UndoableEntry(Gtk.Entry, Gtk.Editable):
|
||||
|
||||
def _handle_redo(self, redo_action):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_ltr_mode(self):
|
||||
""" sets up the Entry to always be in LTR left to right even if some
|
||||
characters are RTL.
|
||||
This works by inserting the LRO/PDF Unicode Explicit Directional
|
||||
Override characters around the entry text. These characters are then
|
||||
protected agains insert/delete operations.
|
||||
|
||||
This call must be made before other text is inserted to the Entry.
|
||||
|
||||
Note: we only enable this during rtl_local languages because it has a
|
||||
minor consequence; if cutting a field from this Entry with this mode
|
||||
enabled, the LRO/PDF characters may end up in the clipboard. If pasted
|
||||
back into another UndoableEntry, this is ignored, but if pasted in
|
||||
another app it may be noticable.
|
||||
"""
|
||||
if glocale.rtl_locale:
|
||||
self.get_buffer().set_text("\u202d\u202e", -1)
|
||||
self.ltr_mode = True
|
||||
|
||||
def do_set_position(self, position):
|
||||
""" In ltr_mode, this ensures that the cursor cannot be put outside
|
||||
the LRO/PDF characters on the ends of the buffer. """
|
||||
if position < 0:
|
||||
position = self.get_text_length()
|
||||
if self.ltr_mode:
|
||||
if position == 0:
|
||||
position = 1
|
||||
elif position == self.get_text_length():
|
||||
position -= 1
|
||||
Gtk.Editable.select_region(self, position, position)
|
||||
|
||||
def get_text(self):
|
||||
""" Used to remove the LRO/PDF characters when in ltr_mode.
|
||||
"""
|
||||
text = Gtk.Entry.get_text(self)
|
||||
return text[1:-1] if self.ltr_mode else text
|
||||
|
||||
@@ -191,7 +191,7 @@ class MaskedEntry(UndoableEntry):
|
||||
:param mask: the mask to set
|
||||
"""
|
||||
if not mask:
|
||||
self.override_font(Pango.FontDescription("sans"))
|
||||
# self.override_font(Pango.FontDescription("sans"))
|
||||
self._mask = mask
|
||||
return
|
||||
|
||||
@@ -221,7 +221,9 @@ class MaskedEntry(UndoableEntry):
|
||||
pos += 1
|
||||
|
||||
self._mask_fields.append((field_begin, field_end))
|
||||
self.override_font(Pango.FontDescription("monospace"))
|
||||
# The set_mask function doesn't seem to be used, except for the test
|
||||
# so removing the monospace doesn't change visible functionality
|
||||
# self.override_font(Pango.FontDescription("monospace"))
|
||||
|
||||
self._really_delete_text(0, -1)
|
||||
self._insert_mask(0, input_length)
|
||||
@@ -940,6 +942,8 @@ VALIDATION_ICON_WIDTH = 16
|
||||
MANDATORY_ICON = 'dialog-information'
|
||||
ERROR_ICON = 'process-stop'
|
||||
DELAY_TIME = 2500
|
||||
READWRITE = (GObject.PARAM_READWRITE if GLib.check_version(2, 42, 0) else
|
||||
GObject.ParamFlags.READWRITE)
|
||||
|
||||
class ValidatableMaskedEntry(MaskedEntry):
|
||||
"""
|
||||
@@ -969,12 +973,12 @@ class ValidatableMaskedEntry(MaskedEntry):
|
||||
'data-type': (GObject.TYPE_PYOBJECT,
|
||||
'Data Type of the widget',
|
||||
'Type object',
|
||||
GObject.PARAM_READWRITE),
|
||||
READWRITE),
|
||||
'mandatory': (GObject.TYPE_BOOLEAN,
|
||||
'Mandatory',
|
||||
'Mandatory',
|
||||
False,
|
||||
GObject.PARAM_READWRITE),
|
||||
READWRITE),
|
||||
}
|
||||
|
||||
# FIXME put the data type support back
|
||||
@@ -1193,12 +1197,16 @@ class ValidatableMaskedEntry(MaskedEntry):
|
||||
# If content isn't empty set_text emitts changed twice.
|
||||
# Protect content-changed from being updated and issue
|
||||
# a manual emission afterwards
|
||||
pos = self.get_position()
|
||||
self._block_changed = True
|
||||
MaskedEntry.set_text(self, text)
|
||||
self._block_changed = False
|
||||
self.emit('content-changed')
|
||||
|
||||
self.set_position(-1)
|
||||
if pos < len(text):
|
||||
self.set_position(pos)
|
||||
else:
|
||||
self.set_position(-1)
|
||||
|
||||
# Private
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ class DbTest(unittest.TestCase):
|
||||
"get_number_of_places",
|
||||
"get_number_of_repositories",
|
||||
"get_number_of_sources",
|
||||
"get_number_of_citations",
|
||||
"get_number_of_tags",
|
||||
"get_media_from_gramps_id",
|
||||
"get_media_from_handle",
|
||||
|
||||
@@ -1541,7 +1541,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
||||
Insert a mark at this point in the document.
|
||||
"""
|
||||
if mark:
|
||||
key = escape(mark.key, ESC_MAP)
|
||||
key = escape(mark.key)
|
||||
key = key.replace('"', '"')
|
||||
if mark.type == INDEX_TYPE_ALP:
|
||||
self.cntnt.write(
|
||||
@@ -1710,7 +1710,7 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc):
|
||||
"""
|
||||
self.meta = StringIO()
|
||||
generator = PROGRAM_NAME + ' ' + VERSION
|
||||
creator = self.get_creator()
|
||||
creator = escape(self.get_creator(), ESC_MAP)
|
||||
date = self.time
|
||||
lang = self.lang
|
||||
gramps_home_url = URL_HOMEPAGE
|
||||
|
||||
@@ -42,7 +42,6 @@ from gramps.gen.plug.menu import (TextOption, NumberOption, BooleanOption,
|
||||
EnumeratedListOption, StringOption,
|
||||
PersonOption)
|
||||
from gramps.gen.plug.report import Report, MenuReportOptions, stdoptions
|
||||
from gramps.gen.plug.report import utils
|
||||
from gramps.gen.plug.docgen import (FontStyle, ParagraphStyle, GraphicsStyle,
|
||||
FONT_SANS_SERIF, PARA_ALIGN_CENTER)
|
||||
from gramps.plugins.lib.libtreebase import *
|
||||
@@ -64,6 +63,7 @@ _MARR = _("marriage abbreviation|m."),
|
||||
|
||||
LVL_GEN, LVL_INDX, LVL_Y = range(3)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Box classes
|
||||
@@ -82,6 +82,7 @@ class PersonBox(BoxBase):
|
||||
def __lt__(self, other):
|
||||
return self.level[LVL_Y] < other.level[LVL_Y]
|
||||
|
||||
|
||||
class FamilyBox(BoxBase):
|
||||
"""
|
||||
Calculates information about the box that will print on a page
|
||||
@@ -114,6 +115,7 @@ class TitleN(TitleNoDisplay):
|
||||
self.mark_text = self._("Ancestor Graph")
|
||||
self.text = ''
|
||||
|
||||
|
||||
class TitleA(TitleBox):
|
||||
"""Title class for the report """
|
||||
def __init__(self, doc, locale, name_displayer):
|
||||
@@ -172,31 +174,32 @@ class CalcItems:
|
||||
def calc_person(self, index, indi_handle, fams_handle):
|
||||
working_lines = ""
|
||||
if index[1] % 2 == 0 or (index[1] == 1 and self.center_use == 0):
|
||||
if indi_handle == fams_handle == None:
|
||||
if indi_handle == fams_handle is None:
|
||||
working_lines = self.__calc_l.calc_lines(
|
||||
None, None, self._gui.get_val("father_disp"))
|
||||
else:
|
||||
working_lines = self.disp_father
|
||||
else:
|
||||
if indi_handle == fams_handle == None:
|
||||
if indi_handle == fams_handle is None:
|
||||
working_lines = self.__calc_l.calc_lines(
|
||||
None, None, self._gui.get_val("mother_disp"))
|
||||
else:
|
||||
working_lines = self.disp_mother
|
||||
|
||||
if indi_handle == fams_handle == None:
|
||||
if indi_handle == fams_handle is None:
|
||||
return working_lines
|
||||
else:
|
||||
return self.__calc_l.calc_lines(indi_handle, fams_handle,
|
||||
working_lines)
|
||||
|
||||
def calc_marriage(self, indi_handle, fams_handle):
|
||||
if indi_handle == fams_handle == None:
|
||||
if indi_handle == fams_handle is None:
|
||||
return self.__blank_marriage
|
||||
else:
|
||||
return self.__calc_l.calc_lines(indi_handle, fams_handle,
|
||||
self.disp_marr)
|
||||
|
||||
|
||||
class MakeAncestorTree(AscendPerson):
|
||||
"""
|
||||
The main procedure to use recursion to make the tree based off of a person.
|
||||
@@ -223,9 +226,9 @@ class MakeAncestorTree(AscendPerson):
|
||||
""" Makes a person box and add that person into the Canvas. """
|
||||
|
||||
#print str(index) + " add_person " + str(indi_handle)
|
||||
myself = PersonBox((index[0]-1,) + index[1:])
|
||||
myself = PersonBox((index[0] - 1,) + index[1:])
|
||||
|
||||
if index[LVL_GEN] == 1: #Center Person
|
||||
if index[LVL_GEN] == 1: # Center Person
|
||||
self.center_family = fams_handle
|
||||
|
||||
if index[LVL_GEN] > self.max_generation:
|
||||
@@ -235,7 +238,7 @@ class MakeAncestorTree(AscendPerson):
|
||||
indi_handle, fams_handle)
|
||||
# myself.text[0] = myself.text[0] + ' ' + repr(index) # for debugging
|
||||
|
||||
if indi_handle is not None: # None is legal for an empty box
|
||||
if indi_handle is not None: # None is legal for an empty box
|
||||
myself.add_mark(self.database,
|
||||
self.database.get_person_from_handle(indi_handle))
|
||||
|
||||
@@ -245,12 +248,12 @@ class MakeAncestorTree(AscendPerson):
|
||||
indx = index[LVL_GEN]
|
||||
self.lines[indx] = myself
|
||||
if indx > 1:
|
||||
if self.lines[indx-1].line_to is None:
|
||||
line = LineBase(self.lines[indx-1])
|
||||
self.lines[indx-1].line_to = line
|
||||
if self.lines[indx - 1].line_to is None:
|
||||
line = LineBase(self.lines[indx - 1])
|
||||
self.lines[indx - 1].line_to = line
|
||||
self.canvas.add_line(line)
|
||||
else:
|
||||
line = self.lines[indx-1].line_to
|
||||
line = self.lines[indx - 1].line_to
|
||||
line.add_to(myself)
|
||||
|
||||
return myself
|
||||
@@ -264,7 +267,7 @@ class MakeAncestorTree(AscendPerson):
|
||||
if not self.inlc_marr:
|
||||
return
|
||||
|
||||
myself = FamilyBox((index[0]-1,) + index[1:])
|
||||
myself = FamilyBox((index[0] - 1,) + index[1:])
|
||||
|
||||
#calculate the text.
|
||||
myself.text = self.calc_items.calc_marriage(indi_handle, fams_handle)
|
||||
@@ -280,7 +283,7 @@ class MakeAncestorTree(AscendPerson):
|
||||
tmp_y = index - (2**x_level)
|
||||
#Calculate which row in the table (yes table) of people.
|
||||
delta = (2**self.max_generation) // (2**(x_level))
|
||||
return int((delta/2) + (tmp_y*delta)) -1
|
||||
return int((delta / 2) + (tmp_y * delta)) - 1
|
||||
|
||||
def do_y_indx(self):
|
||||
''' Make the y_index for all boxes
|
||||
@@ -292,8 +295,8 @@ class MakeAncestorTree(AscendPerson):
|
||||
for box in self.canvas.boxes:
|
||||
if "fam" in box.boxstr:
|
||||
box.level = box.level + \
|
||||
(self.y_index(box.level[LVL_GEN]-1,
|
||||
int(box.level[LVL_INDX]/2)),)
|
||||
(self.y_index(box.level[LVL_GEN] - 1,
|
||||
int(box.level[LVL_INDX] / 2)),)
|
||||
else:
|
||||
box.level = box.level + \
|
||||
(self.y_index(box.level[LVL_GEN], box.level[LVL_INDX]),)
|
||||
@@ -304,10 +307,10 @@ class MakeAncestorTree(AscendPerson):
|
||||
#Then there could be a gap. Remove this gap
|
||||
if min_y > 0:
|
||||
for box in self.canvas.boxes:
|
||||
box.level = box.level[:LVL_Y] + (box.level[LVL_Y]-min_y,)
|
||||
box.level = box.level[:LVL_Y] + (box.level[LVL_Y] - min_y,)
|
||||
|
||||
#Now that we have y_index, lets see if we need to squish the tree
|
||||
self.canvas.boxes.sort() #Sort them on the y_index
|
||||
self.canvas.boxes.sort() # Sort them on the y_index
|
||||
if not self.compress_tree:
|
||||
return
|
||||
#boxes are already in top down [LVL_Y] form so lets
|
||||
@@ -336,20 +339,19 @@ class MakeAncestorTree(AscendPerson):
|
||||
line = center.line_to
|
||||
level = center.level[LVL_Y]
|
||||
|
||||
move = level - (len(mykids)//2) + ((len(mykids)+1)%2)
|
||||
move = level - (len(mykids) // 2) + ((len(mykids) + 1) % 2)
|
||||
|
||||
if move < 0:
|
||||
# more kids than parents. ran off the page. Move them all down
|
||||
for box in self.canvas.boxes:
|
||||
box.level = (box.level[0], box.level[1], box.level[2]-move)
|
||||
box.level = (box.level[0], box.level[1], box.level[2] - move)
|
||||
move = 0
|
||||
|
||||
|
||||
line.start = []
|
||||
rrr = -1 # if len(mykids)%2 == 1 else 0
|
||||
for kid in mykids:
|
||||
rrr += 1
|
||||
mee = self.add_person((1, 1, move+rrr), kid, self.center_family)
|
||||
mee = self.add_person((1, 1, move + rrr), kid, self.center_family)
|
||||
line.add_from(mee)
|
||||
#mee.level = (0, 1, level - (len(mykids)//2)+rrr)
|
||||
mee.line_to = line
|
||||
@@ -387,7 +389,8 @@ class LRTransform:
|
||||
def __init__(self, canvas, max_generations):
|
||||
self.canvas = canvas
|
||||
self.rept_opts = canvas.report_opts
|
||||
self.y_offset = self.rept_opts.littleoffset*2 + self.canvas.title.height
|
||||
self.y_offset = (self.rept_opts.littleoffset * 2 +
|
||||
self.canvas.title.height)
|
||||
|
||||
def _place(self, box):
|
||||
""" put the box in it's correct spot """
|
||||
@@ -410,6 +413,7 @@ class LRTransform:
|
||||
for box in self.canvas.boxes:
|
||||
self._place(box)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# class make_report
|
||||
@@ -441,7 +445,7 @@ class MakeReport:
|
||||
self.canvas.set_box_height_width(box)
|
||||
|
||||
if box.width > self.canvas.report_opts.max_box_width:
|
||||
self.canvas.report_opts.max_box_width = box.width #+ box.shadow
|
||||
self.canvas.report_opts.max_box_width = box.width # + box.shadow
|
||||
|
||||
if box.level[LVL_Y] > 0:
|
||||
if box.level[LVL_INDX] % 2 == 0 and box.height > self.father_ht:
|
||||
@@ -456,7 +460,7 @@ class MakeReport:
|
||||
return self.max_generations
|
||||
|
||||
def start(self):
|
||||
## __gui = GUIConnect()
|
||||
# __gui = GUIConnect()
|
||||
# 1.
|
||||
#set the sizes for each box and get the max_generations.
|
||||
self.father_ht = 0.0
|
||||
@@ -466,10 +470,10 @@ class MakeReport:
|
||||
|
||||
if self.compress_tree and not self.inlc_marr:
|
||||
self.canvas.report_opts.max_box_height = \
|
||||
min(self.father_ht, self.mother_ht)
|
||||
min(self.father_ht, self.mother_ht)
|
||||
else:
|
||||
self.canvas.report_opts.max_box_height = \
|
||||
max(self.father_ht, self.mother_ht)
|
||||
max(self.father_ht, self.mother_ht)
|
||||
|
||||
#At this point we know everything we need to make the report.
|
||||
#Size of each column of people - self.rept_opt.box_width
|
||||
@@ -492,7 +496,8 @@ class GUIConnect:
|
||||
"""
|
||||
|
||||
__shared_state = {}
|
||||
def __init__(self): #We are BORG!
|
||||
|
||||
def __init__(self): # We are BORG!
|
||||
self.__dict__ = self.__shared_state
|
||||
|
||||
def set__opts(self, options, locale, name_displayer):
|
||||
@@ -533,6 +538,7 @@ class GUIConnect:
|
||||
def compress_tree(self):
|
||||
return self.get_val("compress_tree")
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# AncestorTree
|
||||
@@ -600,7 +606,7 @@ class AncestorTree(Report):
|
||||
ReportOptions(self.doc, font_normal, 'AC2-line'))
|
||||
|
||||
self.canvas.report_opts.box_shadow *= \
|
||||
self.connect.get_val('shadowscale')
|
||||
self.connect.get_val('shadowscale')
|
||||
self.canvas.report_opts.box_pgap *= self.connect.get_val('box_Yscale')
|
||||
self.canvas.report_opts.box_mgap *= self.connect.get_val('box_Yscale')
|
||||
|
||||
@@ -608,7 +614,7 @@ class AncestorTree(Report):
|
||||
_('Making the Tree...'), 4) as step:
|
||||
|
||||
#make the tree onto the canvas
|
||||
## inlc_marr = self.connect.get_val("inc_marr")
|
||||
# inlc_marr = self.connect.get_val("inc_marr")
|
||||
self.max_generations = self.connect.get_val('maxgen')
|
||||
tree = MakeAncestorTree(database, self.canvas)
|
||||
tree.start(self.connect.get_val('pid'))
|
||||
@@ -626,7 +632,7 @@ class AncestorTree(Report):
|
||||
#make the report as big as it wants to be.
|
||||
report = MakeReport(database, self.doc, self.canvas, font_normal)
|
||||
report.start()
|
||||
self.max_generations = report.get_generations() #already know
|
||||
self.max_generations = report.get_generations() # already know
|
||||
report = None
|
||||
|
||||
step()
|
||||
@@ -670,8 +676,9 @@ class AncestorTree(Report):
|
||||
|
||||
colsperpage = self.doc.get_usable_width()
|
||||
colsperpage += self.canvas.report_opts.col_width
|
||||
colsperpage = int(colsperpage / (self.canvas.report_opts.max_box_width +
|
||||
self.canvas.report_opts.col_width))
|
||||
colsperpage = int(
|
||||
colsperpage / (self.canvas.report_opts.max_box_width +
|
||||
self.canvas.report_opts.col_width))
|
||||
colsperpage = colsperpage or 1
|
||||
|
||||
#####################
|
||||
@@ -761,6 +768,7 @@ class AncestorTree(Report):
|
||||
|
||||
self.doc.set_style_sheet(style_sheet)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# AncestorTreeOptions
|
||||
@@ -853,8 +861,7 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
self.scale.add_item(1, _("Scale tree to fit page width only"))
|
||||
self.scale.add_item(2, _("Scale tree to fit the size of the page"))
|
||||
self.scale.set_help(
|
||||
_("Whether to scale the tree to fit a specific paper size")
|
||||
)
|
||||
_("Whether to scale the tree to fit a specific paper size"))
|
||||
menu.add_option(category_name, "scale_tree", self.scale)
|
||||
self.scale.connect('value-changed', self.__check_blank)
|
||||
|
||||
@@ -863,7 +870,7 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
_("Resize Page to Fit Tree size\n"
|
||||
"\n"
|
||||
"Note: Overrides options in the 'Paper Option' tab"
|
||||
),
|
||||
),
|
||||
False)
|
||||
self.__onepage.set_help(
|
||||
_("Whether to resize the page to fit the size \n"
|
||||
@@ -880,7 +887,7 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
"\n"
|
||||
"With 'Scale tree to fit the size of the page' the page\n"
|
||||
" is resized to remove any gap in either height or width"
|
||||
))
|
||||
))
|
||||
menu.add_option(category_name, "resize_page", self.__onepage)
|
||||
self.__onepage.connect('value-changed', self.__check_blank)
|
||||
else:
|
||||
@@ -910,8 +917,8 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
|
||||
disp = TextOption(_("Father\nDisplay Format"),
|
||||
["$n",
|
||||
"%s $b" %_BORN,
|
||||
"-{%s $d}" %_DIED])
|
||||
"%s $b" % _BORN,
|
||||
"-{%s $d}" % _DIED])
|
||||
disp.set_help(_("Display format for the fathers box."))
|
||||
menu.add_option(category_name, "father_disp", disp)
|
||||
|
||||
@@ -925,9 +932,9 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
|
||||
disp_mom = TextOption(_("Mother\nDisplay Format"),
|
||||
["$n",
|
||||
"%s $b" %_BORN,
|
||||
"%s $m" %_MARR,
|
||||
"-{%s $d}" %_DIED])
|
||||
"%s $b" % _BORN,
|
||||
"%s $m" % _MARR,
|
||||
"-{%s $d}" % _DIED])
|
||||
disp_mom.set_help(_("Display format for the mothers box."))
|
||||
menu.add_option(category_name, "mother_disp", disp_mom)
|
||||
|
||||
@@ -945,7 +952,7 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
self.incmarr.connect('value-changed', self._incmarr_changed)
|
||||
|
||||
self.marrdisp = StringOption(_("Marriage\nDisplay Format"),
|
||||
"%s $m" % _MARR)
|
||||
"%s $m" % _MARR)
|
||||
self.marrdisp.set_help(_("Display format for the marital box."))
|
||||
menu.add_option(category_name, "marr_disp", self.marrdisp)
|
||||
self._incmarr_changed()
|
||||
@@ -964,7 +971,8 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
# _('Include thumbnail images of people'), False)
|
||||
# self.__include_images.set_help(
|
||||
# _("Whether to include thumbnails of people."))
|
||||
# menu.add_option(category_name, "includeImages", self.__include_images)
|
||||
# menu.add_option(category_name, "includeImages",
|
||||
# self.__include_images)
|
||||
|
||||
self.usenote = BooleanOption(_('Include a note'), False)
|
||||
self.usenote.set_help(_("Whether to include a note on the report."))
|
||||
@@ -991,7 +999,7 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
menu.add_option(category_name, "box_Yscale", self.box_Y_sf)
|
||||
|
||||
self.box_shadow_sf = NumberOption(_("box shadow scale factor"),
|
||||
1.00, 0.00, 2.00, 0.01) # down to 0
|
||||
1.00, 0.00, 2.00, 0.01) # down to 0
|
||||
self.box_shadow_sf.set_help(_("Make the box shadow bigger or smaller"))
|
||||
menu.add_option(category_name, "shadowscale", self.box_shadow_sf)
|
||||
|
||||
@@ -1033,13 +1041,13 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
for itr in range(2, max_gen))
|
||||
|
||||
self.fillout.set_items(item_list)
|
||||
if old_val+2 > len(item_list):
|
||||
self.fillout.set_value(len(item_list) -2)
|
||||
if old_val + 2 > len(item_list):
|
||||
self.fillout.set_value(len(item_list) - 2)
|
||||
|
||||
def make_default_style(self, default_style):
|
||||
"""Make the default output style for the Ancestor Tree."""
|
||||
|
||||
## Paragraph Styles:
|
||||
# Paragraph Styles:
|
||||
font = FontStyle()
|
||||
font.set_size(9)
|
||||
font.set_type_face(FONT_SANS_SERIF)
|
||||
@@ -1068,16 +1076,16 @@ class AncestorTreeOptions(MenuReportOptions):
|
||||
para_style.set_description(_('The style used for the title.'))
|
||||
default_style.add_paragraph_style("AC2-Title", para_style)
|
||||
|
||||
## Draw styles
|
||||
# Draw styles
|
||||
graph_style = GraphicsStyle()
|
||||
graph_style.set_paragraph_style("AC2-Normal")
|
||||
graph_style.set_shadow(1, box_shadow) #shadow set by text size
|
||||
graph_style.set_shadow(1, box_shadow) # shadow set by text size
|
||||
graph_style.set_fill_color((255, 255, 255))
|
||||
default_style.add_draw_style("AC2-box", graph_style)
|
||||
|
||||
graph_style = GraphicsStyle()
|
||||
graph_style.set_paragraph_style("AC2-Normal")
|
||||
#graph_style.set_shadow(0, PT2CM(9)) #shadow set by text size
|
||||
#graph_style.set_shadow(0, PT2CM(9)) # shadow set by text size
|
||||
graph_style.set_fill_color((255, 255, 255))
|
||||
default_style.add_draw_style("AC2-fam-box", graph_style)
|
||||
|
||||
|
||||
@@ -225,7 +225,10 @@ class TitleDPY(DescendantTitleBase):
|
||||
|
||||
center = self.database.get_person_from_gramps_id(person_id)
|
||||
family2_h = center.get_main_parents_family_handle()
|
||||
family2 = self.database.get_family_from_handle(family2_h)
|
||||
if family2_h:
|
||||
family2 = self.database.get_family_from_handle(family2_h)
|
||||
else:
|
||||
family2 = None
|
||||
|
||||
person_list = None
|
||||
if family2:
|
||||
@@ -270,8 +273,11 @@ class TitleDFY(DescendantTitleBase):
|
||||
|
||||
parent_list = None
|
||||
family_h = person.get_main_parents_family_handle()
|
||||
family = self.database.get_family_from_handle(family_h)
|
||||
if family: #family = fathers parents
|
||||
if family_h:
|
||||
family = self.database.get_family_from_handle(family_h)
|
||||
else:
|
||||
family = None
|
||||
if family: # family = fathers parents
|
||||
father_h = family.get_father_handle()
|
||||
mother_h = family.get_mother_handle()
|
||||
parent_list = [self.database.get_person_from_handle(handle)
|
||||
@@ -1814,30 +1820,31 @@ class DescendTreeOptions(MenuReportOptions):
|
||||
graph_style = GraphicsStyle()
|
||||
graph_style.set_paragraph_style("CG2-Normal")
|
||||
graph_style.set_fill_color((255, 255, 255))
|
||||
graph_style.set_description(_("The style for the marriage box."))
|
||||
default_style.add_draw_style("CG2-fam-box", graph_style)
|
||||
|
||||
graph_style = GraphicsStyle()
|
||||
graph_style.set_paragraph_style("CG2-Normal")
|
||||
graph_style.set_shadow(1, box_shadow)
|
||||
graph_style.set_fill_color((255, 255, 255))
|
||||
graph_style.set_description(_("The style for the spouse box."))
|
||||
default_style.add_draw_style("CG2-box", graph_style)
|
||||
|
||||
graph_style = GraphicsStyle()
|
||||
graph_style.set_paragraph_style("CG2-Bold")
|
||||
graph_style.set_shadow(1, box_shadow)
|
||||
graph_style.set_fill_color((255, 255, 255))
|
||||
graph_style.set_description(
|
||||
_("The style for the direct descendant box."))
|
||||
default_style.add_draw_style("CG2b-box", graph_style)
|
||||
|
||||
graph_style = GraphicsStyle()
|
||||
graph_style.set_paragraph_style("CG2-Note")
|
||||
graph_style.set_fill_color((255, 255, 255))
|
||||
graph_style.set_description(_("The style for the note box."))
|
||||
default_style.add_draw_style("CG2-note-box", graph_style)
|
||||
|
||||
graph_style = GraphicsStyle()
|
||||
graph_style.set_description(
|
||||
_("The style for the connection lines and report border."))
|
||||
default_style.add_draw_style("CG2-line", graph_style)
|
||||
|
||||
#=====================================
|
||||
#So do not fear, for I am with you; do not be dismayed,
|
||||
#for I am your God. I will strengthen you and help you;
|
||||
#I will uphold you with my righteous right hand.
|
||||
#Isaiah 41:10
|
||||
|
||||
@@ -82,7 +82,8 @@ class FtreeWriter:
|
||||
self.option_box.parse_options()
|
||||
self.db = option_box.get_filtered_database(self.db)
|
||||
|
||||
self.plist = [x for x in self.db.iter_person_handles()]
|
||||
self.plist = self.db.get_person_handles()
|
||||
self.plist.sort()
|
||||
# the following are used to update the progress meter
|
||||
self.total = 2 * len(self.plist)
|
||||
self.count = 0
|
||||
|
||||
@@ -596,7 +596,7 @@ class GedcomWriter(UpdateCallback):
|
||||
if val.strip():
|
||||
self._writeln(2, 'TYPE', val)
|
||||
else:
|
||||
self._writeln(2, 'TYPE', str(event.get_type()))
|
||||
self._writeln(2, 'TYPE', event.get_type().xml_str())
|
||||
self._dump_event_stats(event, event_ref)
|
||||
if etype == EventType.ADOPT and not adop_written:
|
||||
adop_written = True
|
||||
@@ -656,7 +656,7 @@ class GedcomWriter(UpdateCallback):
|
||||
|
||||
attr_type = int(attr.get_type())
|
||||
name = libgedcom.PERSONALCONSTANTATTRIBUTES.get(attr_type)
|
||||
key = str(attr.get_type())
|
||||
key = attr.get_type().xml_str()
|
||||
value = attr.get_value().strip().replace('\r', ' ')
|
||||
|
||||
if key in ("AFN", "RFN", "REFN", "_UID", "_FSFTID"):
|
||||
@@ -735,14 +735,14 @@ class GedcomWriter(UpdateCallback):
|
||||
child.mrel == ChildRefType.FOSTER:
|
||||
self._writeln(2, 'PEDI foster')
|
||||
elif child.frel == child.mrel:
|
||||
self._writeln(2, 'PEDI %s' % str(child.frel))
|
||||
self._writeln(2, 'PEDI %s' % child.frel.xml_str())
|
||||
else:
|
||||
self._writeln(2, '_FREL %s' %
|
||||
PEDIGREE_TYPES.get(child.frel.value,
|
||||
str(child.frel)))
|
||||
self._writeln(2, '_MREL %s' %
|
||||
PEDIGREE_TYPES.get(child.mrel.value,
|
||||
str(child.mrel)))
|
||||
self._writeln(
|
||||
2, '_FREL %s' % PEDIGREE_TYPES.get(
|
||||
child.frel.value, child.frel.xml_str()))
|
||||
self._writeln(
|
||||
2, '_MREL %s' % PEDIGREE_TYPES.get(
|
||||
child.mrel.value, child.mrel.xml_str()))
|
||||
|
||||
def _parent_families(self, person):
|
||||
"""
|
||||
@@ -910,9 +910,9 @@ class GedcomWriter(UpdateCallback):
|
||||
self._writeln(1, 'EVEN', descr)
|
||||
else:
|
||||
self._writeln(1, 'EVEN')
|
||||
the_type = str(event.get_type())
|
||||
the_type = event.get_type()
|
||||
if the_type:
|
||||
self._writeln(2, 'TYPE', the_type)
|
||||
self._writeln(2, 'TYPE', the_type.xml_str())
|
||||
|
||||
def _family_event_attrs(self, attr_list, level):
|
||||
"""
|
||||
@@ -946,7 +946,7 @@ class GedcomWriter(UpdateCallback):
|
||||
|
||||
attr_type = int(attr.get_type())
|
||||
name = libgedcom.FAMILYCONSTANTATTRIBUTES.get(attr_type)
|
||||
key = str(attr.get_type())
|
||||
key = attr.get_type().xml_str()
|
||||
value = attr.get_value().replace('\r', ' ')
|
||||
|
||||
if key in ("AFN", "RFN", "REFN", "_UID"):
|
||||
@@ -1097,7 +1097,8 @@ class GedcomWriter(UpdateCallback):
|
||||
if reporef.get_call_number():
|
||||
self._writeln(level + 1, 'CALN', reporef.get_call_number())
|
||||
if reporef.get_media_type():
|
||||
self._writeln(level + 2, 'MEDI', str(reporef.get_media_type()))
|
||||
self._writeln(level + 2, 'MEDI',
|
||||
reporef.get_media_type().xml_str())
|
||||
|
||||
def _person_event_ref(self, key, event_ref):
|
||||
"""
|
||||
|
||||
@@ -91,7 +91,8 @@ class GeneWebWriter:
|
||||
self.dirname = os.path.dirname (self.filename)
|
||||
try:
|
||||
with open(self.filename, "wb") as self.g:
|
||||
self.flist = [x for x in self.db.iter_family_handles()]
|
||||
self.flist = self.db.get_family_handles()
|
||||
self.flist.sort()
|
||||
if len(self.flist) < 1:
|
||||
self.user.notify_error(_("No families matched by selected filter"))
|
||||
return False
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#-------------------------------------------------------------------------
|
||||
import os
|
||||
import sys
|
||||
from time import localtime
|
||||
import time
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -51,10 +51,10 @@ _ = glocale.translation.gettext
|
||||
from gramps.gui.plug.export import WriterOptionBox
|
||||
from gramps.gen.utils.db import family_name
|
||||
from gramps.gen.lib import Date, EventType
|
||||
from gramps.gui.glade import Glade
|
||||
from gramps.gen.display.name import displayer as name_displayer
|
||||
from gramps.gen.display.place import displayer as _pd
|
||||
|
||||
|
||||
class CalendarWriter:
|
||||
def __init__(self, database, filename, user, option_box=None):
|
||||
self.db = database
|
||||
@@ -95,24 +95,27 @@ class CalendarWriter:
|
||||
|
||||
def export_data(self, filename):
|
||||
|
||||
self.dirname = os.path.dirname (filename)
|
||||
self.dirname = os.path.dirname(filename)
|
||||
try:
|
||||
with open(filename,"w") as self.g:
|
||||
with open(filename, "w", encoding='utf8',
|
||||
newline='\r\n') as self.g:
|
||||
self.writeln("BEGIN:VCALENDAR")
|
||||
self.writeln("PRODID:-//GNU//Gramps//EN")
|
||||
self.writeln("VERSION:1.0")
|
||||
self.writeln("VERSION:2.0")
|
||||
|
||||
self.total = (len([x for x in self.db.iter_person_handles()]) +
|
||||
len([x for x in self.db.iter_family_handles()]))
|
||||
for key in self.db.iter_person_handles():
|
||||
p_hndls = self.db.get_person_handles()
|
||||
p_hndls.sort()
|
||||
f_hndls = self.db.get_family_handles()
|
||||
f_hndls.sort()
|
||||
self.total = len(p_hndls) + len(f_hndls)
|
||||
for key in p_hndls:
|
||||
self.write_person(key)
|
||||
self.update()
|
||||
|
||||
for key in self.db.iter_family_handles():
|
||||
for key in f_hndls:
|
||||
self.write_family(key)
|
||||
self.update()
|
||||
|
||||
self.writeln("")
|
||||
self.writeln("END:VCALENDAR")
|
||||
|
||||
return True
|
||||
@@ -129,16 +132,11 @@ class CalendarWriter:
|
||||
if family:
|
||||
for event_ref in family.get_event_ref_list():
|
||||
event = self.db.get_event_from_handle(event_ref.ref)
|
||||
if event.get_type() == EventType.MARRIAGE:
|
||||
m_date = event.get_date_object()
|
||||
place_handle = event.get_place_handle()
|
||||
if event and event.get_type() == EventType.MARRIAGE:
|
||||
# feature requests 2356, 1657: avoid genitive form
|
||||
text = "%s - %s" % (family_name(family, self.db), _("Marriage"))
|
||||
if place_handle:
|
||||
place_title = _pd.display_event(self.db, event)
|
||||
self.write_vevent( text, m_date, place_title)
|
||||
else:
|
||||
self.write_vevent( text, m_date)
|
||||
text = "%s - %s" % (family_name(family, self.db),
|
||||
_("Marriage"))
|
||||
self.write_vevent(text, event)
|
||||
|
||||
def write_person(self, person_handle):
|
||||
person = self.db.get_person_from_handle(person_handle)
|
||||
@@ -147,45 +145,26 @@ class CalendarWriter:
|
||||
if birth_ref:
|
||||
birth = self.db.get_event_from_handle(birth_ref.ref)
|
||||
if birth:
|
||||
b_date = birth.get_date_object()
|
||||
place_handle = birth.get_place_handle()
|
||||
if place_handle:
|
||||
# feature requests 2356, 1657: avoid genitive form
|
||||
place_title = _pd.display_event(self.db, birth)
|
||||
self.write_vevent("%s - %s" %
|
||||
(name_displayer.display(person), _("Birth")),
|
||||
b_date, place_title)
|
||||
else:
|
||||
# feature requests 2356, 1657: avoid genitive form
|
||||
self.write_vevent("%s - %s" %
|
||||
(name_displayer.display(person), _("Birth")),
|
||||
b_date)
|
||||
# feature requests 2356, 1657: avoid genitive form
|
||||
self.write_vevent("%s - %s" %
|
||||
(name_displayer.display(person),
|
||||
_("Birth")), birth)
|
||||
|
||||
death_ref = person.get_death_ref()
|
||||
if death_ref:
|
||||
death = self.db.get_event_from_handle(death_ref.ref)
|
||||
if death:
|
||||
d_date = death.get_date_object()
|
||||
place_handle = death.get_place_handle()
|
||||
if place_handle:
|
||||
# feature requests 2356, 1657: avoid genitive form
|
||||
place_title = _pd.display_event(self.db, death)
|
||||
self.write_vevent("%s - %s" %
|
||||
(name_displayer.display(person), _("Death")),
|
||||
d_date, place_title)
|
||||
else:
|
||||
# feature requests 2356, 1657: avoid genitive form
|
||||
self.write_vevent("%s - %s" %
|
||||
(name_displayer.display(person), _("Death")),
|
||||
d_date)
|
||||
|
||||
# feature requests 2356, 1657: avoid genitive form
|
||||
self.write_vevent("%s - %s" %
|
||||
(name_displayer.display(person),
|
||||
_("Death")), death)
|
||||
|
||||
def format_single_date(self, subdate, thisyear, cal):
|
||||
retval = ""
|
||||
(day, month, year, sl) = subdate
|
||||
|
||||
if thisyear:
|
||||
year = localtime().tm_year
|
||||
year = time.localtime().tm_year
|
||||
|
||||
if not cal == Date.CAL_GREGORIAN:
|
||||
return ""
|
||||
@@ -196,7 +175,6 @@ class CalendarWriter:
|
||||
retval = "%s%02d%02d" % (year, month, day)
|
||||
return retval
|
||||
|
||||
|
||||
def format_date(self, date, thisyear=0):
|
||||
retval = ""
|
||||
if date.get_modifier() == Date.MOD_TEXTONLY:
|
||||
@@ -220,23 +198,43 @@ class CalendarWriter:
|
||||
start)
|
||||
return retval
|
||||
|
||||
def write_vevent(self, event_text, date, location=""):
|
||||
def write_vevent(self, event_text, event):
|
||||
date = event.get_date_object()
|
||||
place_handle = event.get_place_handle()
|
||||
date_string = self.format_date(date, 1)
|
||||
if date_string is not "":
|
||||
self.writeln("")
|
||||
# self.writeln("")
|
||||
self.writeln("BEGIN:VEVENT")
|
||||
self.writeln("SUMMARY:%s %s" % (date.get_year(), event_text))
|
||||
if location:
|
||||
self.writeln("LOCATION:%s" % location)
|
||||
time_s = time.gmtime(event.change)
|
||||
self.writeln("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ" % time_s[0:6])
|
||||
self.writeln("UID:%s@gramps.com" % event.handle)
|
||||
self.writeln(fold("SUMMARY:%s %s" % (date.get_year(), event_text)))
|
||||
if place_handle:
|
||||
location = _pd.display_event(self.db, event)
|
||||
if location:
|
||||
self.writeln("LOCATION:%s" % location)
|
||||
self.writeln("RRULE:FREQ=YEARLY")
|
||||
self.writeln(date_string)
|
||||
self.writeln("END:VEVENT")
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
def fold(txt):
|
||||
""" Limit line length to 75 octets (per RFC 5545) """
|
||||
l_len = 0
|
||||
text = ''
|
||||
for char in txt:
|
||||
c_len = len(char.encode('utf8'))
|
||||
if c_len + l_len > 75:
|
||||
l_len = 1
|
||||
text += '\n ' + char
|
||||
else:
|
||||
l_len += c_len
|
||||
text += char
|
||||
return text
|
||||
|
||||
|
||||
def exportData(database, filename, user, option_box=None):
|
||||
cw = CalendarWriter(database, filename, user, option_box)
|
||||
return cw.export_data(filename)
|
||||
|
||||
@@ -51,13 +51,13 @@ class AgeStatsGramplet(Gramplet):
|
||||
def build_options(self):
|
||||
from gramps.gen.plug.menu import NumberOption
|
||||
self.add_option(NumberOption(_("Max age"),
|
||||
self.max_age, 1, 150))
|
||||
self.max_age, 5, 150, 5))
|
||||
self.add_option(NumberOption(_("Max age of Mother at birth"),
|
||||
self.max_mother_diff, 1, 150))
|
||||
self.max_mother_diff, 5, 150, 5))
|
||||
self.add_option(NumberOption(_("Max age of Father at birth"),
|
||||
self.max_father_diff, 1, 150))
|
||||
self.max_father_diff, 5, 150, 5))
|
||||
self.add_option(NumberOption(_("Chart width"),
|
||||
self.chart_width, 1, 150))
|
||||
self.chart_width, 45, 150))
|
||||
|
||||
def save_options(self):
|
||||
self.max_age = int(self.get_option(_("Max age")).get_value())
|
||||
|
||||
@@ -139,7 +139,6 @@ class GeoEvents(Gramplet, DbGUIElement):
|
||||
"""
|
||||
self.menu = Gtk.Menu()
|
||||
menu = self.menu
|
||||
menu.set_title(_('Edit'))
|
||||
title = _('Edit the event')
|
||||
add_item = Gtk.MenuItem(label=title)
|
||||
add_item.connect("activate", self.edit_event, treeview)
|
||||
|
||||
@@ -70,7 +70,7 @@ class FanChart2WayGramplet(FanChart2WayGrampsGUI, Gramplet):
|
||||
self.on_popup))
|
||||
# Replace the standard textview with the fan chart widget:
|
||||
self.gui.get_container_widget().remove(self.gui.textview)
|
||||
self.gui.get_container_widget().add_with_viewport(self.fan)
|
||||
self.gui.get_container_widget().add(self.fan)
|
||||
# Make sure it is visible:
|
||||
self.fan.show()
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Pango
|
||||
from gi.repository.GLib import markup_escape_text
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -61,7 +61,6 @@ class PersonDetails(Gramplet):
|
||||
self.photo = Photo(self.uistate.screen_height() < 1000)
|
||||
self.photo.show()
|
||||
self.name = Gtk.Label(halign=Gtk.Align.START)
|
||||
self.name.override_font(Pango.FontDescription('sans bold 12'))
|
||||
self.name.set_selectable(True)
|
||||
vbox.pack_start(self.name, fill=True, expand=False, padding=7)
|
||||
self.grid = Gtk.Grid(orientation=Gtk.Orientation.VERTICAL)
|
||||
@@ -150,7 +149,9 @@ class PersonDetails(Gramplet):
|
||||
Display details of the active person.
|
||||
"""
|
||||
self.load_person_image(active_person)
|
||||
self.name.set_text(name_displayer.display(active_person))
|
||||
self.name.set_markup(
|
||||
"<span size='large' weight='bold'>%s</span>" %
|
||||
markup_escape_text(name_displayer.display(active_person), -1))
|
||||
self.clear_grid()
|
||||
self.display_alternate_names(active_person)
|
||||
self.display_parents(active_person)
|
||||
@@ -177,8 +178,8 @@ class PersonDetails(Gramplet):
|
||||
"""
|
||||
Display an empty row to separate groupd of entries.
|
||||
"""
|
||||
label = Gtk.Label(label='')
|
||||
label.override_font(Pango.FontDescription('sans 4'))
|
||||
label = Gtk.Label()
|
||||
label.set_markup("<span font='sans 4'> </span>")
|
||||
label.set_selectable(True)
|
||||
label.show()
|
||||
self.grid.add(label)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Pango
|
||||
from gi.repository.GLib import markup_escape_text
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -55,7 +55,6 @@ class PlaceDetails(Gramplet):
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
self.photo = Photo(self.uistate.screen_height() < 1000)
|
||||
self.title = Gtk.Label(halign=Gtk.Align.START)
|
||||
self.title.override_font(Pango.FontDescription('sans bold 12'))
|
||||
self.title.set_selectable(True)
|
||||
vbox.pack_start(self.title, False, True, 7)
|
||||
self.grid = Gtk.Grid(orientation=Gtk.Orientation.VERTICAL)
|
||||
@@ -119,7 +118,8 @@ class PlaceDetails(Gramplet):
|
||||
"""
|
||||
self.load_place_image(place)
|
||||
title = place_displayer.display(self.dbstate.db, place)
|
||||
self.title.set_text(title)
|
||||
self.title.set_markup("<span size='large' weight='bold'>%s</span>" %
|
||||
markup_escape_text(title))
|
||||
|
||||
self.clear_grid()
|
||||
self.add_row(_('Name'), place.get_name().get_value())
|
||||
@@ -158,8 +158,8 @@ class PlaceDetails(Gramplet):
|
||||
"""
|
||||
Display an empty row to separate groupd of entries.
|
||||
"""
|
||||
label = Gtk.Label(label='')
|
||||
label.override_font(Pango.FontDescription('sans 4'))
|
||||
label = Gtk.Label()
|
||||
label.set_markup("<span font='sans 4'> </span>")
|
||||
label.set_selectable(True)
|
||||
label.show()
|
||||
self.grid.add(label)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#-------------------------------------------------------------------------
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Pango
|
||||
from gi.repository.GLib import markup_escape_text
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -51,7 +52,6 @@ class RepositoryDetails(Gramplet):
|
||||
self.top = Gtk.Box()
|
||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
self.name = Gtk.Label(halign=Gtk.Align.START)
|
||||
self.name.override_font(Pango.FontDescription('sans bold 12'))
|
||||
self.name.set_selectable(True)
|
||||
vbox.pack_start(self.name, fill=True, expand=False, padding=7)
|
||||
self.grid = Gtk.Grid(orientation=Gtk.Orientation.VERTICAL)
|
||||
@@ -112,7 +112,9 @@ class RepositoryDetails(Gramplet):
|
||||
"""
|
||||
Display details of the active repository.
|
||||
"""
|
||||
self.name.set_text(repo.get_name())
|
||||
self.name.set_markup(
|
||||
"<span size='large' weight='bold'>%s</span>" %
|
||||
markup_escape_text(repo.get_name(), -1))
|
||||
|
||||
self.clear_grid()
|
||||
address_list = repo.get_address_list()
|
||||
@@ -154,8 +156,8 @@ class RepositoryDetails(Gramplet):
|
||||
"""
|
||||
Display an empty row to separate groupd of entries.
|
||||
"""
|
||||
label = Gtk.Label(label='')
|
||||
label.override_font(Pango.FontDescription('sans 4'))
|
||||
label = Gtk.Label()
|
||||
label.set_markup("<span font='sans 4'> </span>")
|
||||
label.set_selectable(True)
|
||||
label.show()
|
||||
self.grid.add(label)
|
||||
|
||||
@@ -33,6 +33,7 @@ Family Lines, a Graphviz-based plugin for Gramps.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from functools import partial
|
||||
import html
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -818,10 +819,10 @@ class FamilyLinesReport(Report):
|
||||
if bth_event and self._incdates:
|
||||
date = bth_event.get_date_object()
|
||||
if self._just_years and date.get_year_valid():
|
||||
birth_str = self._get_date( # localized year
|
||||
birth_str = self.get_date( # localized year
|
||||
Date(date.get_year()))
|
||||
else:
|
||||
birth_str = self._get_date(date)
|
||||
birth_str = self.get_date(date)
|
||||
|
||||
# get birth place (one of: hamlet, village, town, city, parish,
|
||||
# county, province, region, state or country)
|
||||
@@ -834,10 +835,10 @@ class FamilyLinesReport(Report):
|
||||
if dth_event and self._incdates:
|
||||
date = dth_event.get_date_object()
|
||||
if self._just_years and date.get_year_valid():
|
||||
death_str = self._get_date( # localized year
|
||||
death_str = self.get_date( # localized year
|
||||
Date(date.get_year()))
|
||||
else:
|
||||
death_str = self._get_date(date)
|
||||
death_str = self.get_date(date)
|
||||
|
||||
# get death place (one of: hamlet, village, town, city, parish,
|
||||
# county, province, region, state or country)
|
||||
@@ -876,8 +877,7 @@ class FamilyLinesReport(Report):
|
||||
label += '<TD>'
|
||||
|
||||
# at the very least, the label must have the person's name
|
||||
name = name.replace('"', '"')
|
||||
label += name.replace('<', '<').replace('>', '>')
|
||||
label += html.escape(name)
|
||||
if self.includeid == 1: # same line
|
||||
label += " (%s)" % p_id
|
||||
elif self.includeid == 2: # own line
|
||||
@@ -964,10 +964,10 @@ class FamilyLinesReport(Report):
|
||||
if self._incdates:
|
||||
date = event.get_date_object()
|
||||
if self._just_years and date.get_year_valid():
|
||||
wedding_date = self._get_date( # localized year
|
||||
wedding_date = self.get_date( # localized year
|
||||
Date(date.get_year()))
|
||||
else:
|
||||
wedding_date = self._get_date(date)
|
||||
wedding_date = self.get_date(date)
|
||||
# get the wedding location
|
||||
if self._incplaces:
|
||||
wedding_place = self.get_event_place(event)
|
||||
@@ -1090,6 +1090,9 @@ class FamilyLinesReport(Report):
|
||||
place = self._db.get_place_from_handle(place_handle)
|
||||
if place:
|
||||
place_text = _pd.display(self._db, place)
|
||||
place_text = place_text.replace('<', '<')
|
||||
place_text = place_text.replace('>', '>')
|
||||
place_text = html.escape(place_text)
|
||||
return place_text
|
||||
|
||||
def get_date(self, date):
|
||||
""" return a formatted date """
|
||||
return html.escape(self._get_date(date))
|
||||
|
||||
@@ -32,6 +32,7 @@ Generate an hourglass graph using the Graphviz generator.
|
||||
# python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import html
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -251,18 +252,17 @@ class HourGlassReport(Report):
|
||||
"""
|
||||
p_id = person.get_gramps_id()
|
||||
name = self._name_display.display(person)
|
||||
name = name.replace('"', '"')
|
||||
name = name.replace('<', '<').replace('>', '>')
|
||||
name = html.escape(name)
|
||||
|
||||
birth_evt = get_birth_or_fallback(self.__db, person)
|
||||
if birth_evt:
|
||||
birth = self._get_date(birth_evt.get_date_object())
|
||||
birth = self.get_date(birth_evt.get_date_object())
|
||||
else:
|
||||
birth = ""
|
||||
|
||||
death_evt = get_death_or_fallback(self.__db, person)
|
||||
if death_evt:
|
||||
death = self._get_date(death_evt.get_date_object())
|
||||
death = self.get_date(death_evt.get_date_object())
|
||||
else:
|
||||
death = ""
|
||||
|
||||
@@ -295,7 +295,7 @@ class HourGlassReport(Report):
|
||||
label = ""
|
||||
marriage = utils.find_marriage(self.__db, family)
|
||||
if marriage:
|
||||
label = self._get_date(marriage.get_date_object())
|
||||
label = self.get_date(marriage.get_date_object())
|
||||
if self.includeid == 1 and label: # same line
|
||||
label = "%s (%s)" % (label, family_id)
|
||||
elif self.includeid == 1 and not label:
|
||||
@@ -343,7 +343,9 @@ class HourGlassReport(Report):
|
||||
else:
|
||||
fill = self.colors['unknown']
|
||||
return(shape, style, color, fill)
|
||||
|
||||
def get_date(self, date):
|
||||
""" return a formatted date """
|
||||
return html.escape(self._get_date(date))
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
@@ -40,6 +40,7 @@ Create a relationship graph using Graphviz
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from functools import partial
|
||||
import html
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -616,8 +617,7 @@ class RelGraphReport(Report):
|
||||
|
||||
# at the very least, the label must have the person's name
|
||||
p_name = self._name_display.display(person)
|
||||
p_name = p_name.replace('"', '"')
|
||||
label += p_name.replace('<', '<').replace('>', '>')
|
||||
label += html.escape(p_name)
|
||||
p_id = person.get_gramps_id()
|
||||
if self.includeid == 1: # same line
|
||||
label += " (%s)" % p_id
|
||||
@@ -751,10 +751,10 @@ class RelGraphReport(Report):
|
||||
event_date = event.get_date_object()
|
||||
if event_date.get_year_valid():
|
||||
if self.event_choice in [4, 5]:
|
||||
return self._get_date( # localized year
|
||||
return self.get_date( # localized year
|
||||
Date(event_date.get_year()))
|
||||
elif self.event_choice in [1, 2, 3, 7]:
|
||||
return self._get_date(event_date)
|
||||
return self.get_date(event_date)
|
||||
return ''
|
||||
|
||||
def get_place_string(self, event):
|
||||
@@ -768,8 +768,11 @@ class RelGraphReport(Report):
|
||||
"""
|
||||
if event and self.event_choice in [2, 3, 5, 6, 7]:
|
||||
place = _pd.display_event(self._db, event)
|
||||
return place.replace('<', '<').replace('>', '>')
|
||||
return html.escape(place)
|
||||
return ''
|
||||
def get_date(self, date):
|
||||
""" return a formatted date """
|
||||
return html.escape(self._get_date(date))
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
@@ -559,6 +559,14 @@ class BasePersonView(ListView):
|
||||
person.add_tag(tag_handle)
|
||||
self.dbstate.db.commit_person(person, transaction)
|
||||
|
||||
def remove_tag(self, transaction, person_handle, tag_handle):
|
||||
"""
|
||||
Remove the given tag from the given person.
|
||||
"""
|
||||
person = self.dbstate.db.get_person_from_handle(person_handle)
|
||||
person.remove_tag(tag_handle)
|
||||
self.dbstate.db.commit_person(person, transaction)
|
||||
|
||||
def get_default_gramplets(self):
|
||||
"""
|
||||
Define the default gramplets for the sidebar and bottombar.
|
||||
|
||||
@@ -595,6 +595,14 @@ class PlaceBaseView(ListView):
|
||||
place.add_tag(tag_handle)
|
||||
self.dbstate.db.commit_place(place, transaction)
|
||||
|
||||
def remove_tag(self, transaction, place_handle, tag_handle):
|
||||
"""
|
||||
Remove the given tag from the given place.
|
||||
"""
|
||||
place = self.dbstate.db.get_place_from_handle(place_handle)
|
||||
place.remove_tag(tag_handle)
|
||||
self.dbstate.db.commit_place(place, transaction)
|
||||
|
||||
def get_default_gramplets(self):
|
||||
"""
|
||||
Define the default gramplets for the sidebar and bottombar.
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
"""
|
||||
|
||||
from gramps.gen.plug.report import utils
|
||||
from gramps.gen.lib import ChildRefType
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@@ -56,6 +55,7 @@ class _PersonSeen:
|
||||
if person_handle is not None:
|
||||
self.people_seen.add(person_handle)
|
||||
|
||||
|
||||
class _FamilySeen:
|
||||
""" librecurse base boject only
|
||||
Keep track of the famalies that have been seen so we can call the correct
|
||||
@@ -80,6 +80,7 @@ class _FamilySeen:
|
||||
self.add_marriage(level, person_handle, family_handle)
|
||||
self.families_seen.add(family_handle)
|
||||
|
||||
|
||||
class _StopRecurse:
|
||||
""" A simple class to break out the
|
||||
. stop_recursion
|
||||
@@ -101,7 +102,7 @@ class _StopRecurse:
|
||||
|
||||
def can_recurse(self):
|
||||
""" Has the upper class told up to stop or can we continue? """
|
||||
return self.__stop_recursion == False
|
||||
return not self.__stop_recursion
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@@ -276,7 +277,7 @@ class DescendPerson(_StopRecurse, _PersonSeen, _FamilySeen):
|
||||
for family_handle in family_handles:
|
||||
#Marriage box if the option is there.
|
||||
self._add_marriage((g_level, s_level + 1),
|
||||
person_handle, family_handle)
|
||||
person_handle, family_handle)
|
||||
|
||||
if not self.can_recurse():
|
||||
self.continue_recursion()
|
||||
@@ -288,7 +289,7 @@ class DescendPerson(_StopRecurse, _PersonSeen, _FamilySeen):
|
||||
if self.max_spouses > s_level:
|
||||
self.__this_slevel = s_level + 1
|
||||
self._add_person((g_level, s_level + 1),
|
||||
spouse_handle, family_handle)
|
||||
spouse_handle, family_handle)
|
||||
|
||||
if not self.can_recurse:
|
||||
self.continue_recursion()
|
||||
@@ -446,13 +447,13 @@ class AscendPerson(_StopRecurse, _PersonSeen):
|
||||
# Recursively call the function. It is okay if the handle is None,
|
||||
# since routine handles a handle of None
|
||||
|
||||
self.__fill(generation+1, index*2, mx_fill-1)
|
||||
self.__fill(generation + 1, index * 2, mx_fill - 1)
|
||||
if mx_fill > 1: # marriage of parents
|
||||
self.add_marriage((generation+1, index*2), None, None)
|
||||
self.add_marriage((generation + 1, index * 2), None, None)
|
||||
if not self.can_recurse():
|
||||
self.continue_recursion()
|
||||
return
|
||||
self.__fill(generation+1, (index*2)+1, mx_fill-1)
|
||||
self.__fill(generation + 1, (index * 2) + 1, mx_fill - 1)
|
||||
|
||||
def __iterate(self, generation, index, person_handle, full_family_handle):
|
||||
"""
|
||||
@@ -478,15 +479,15 @@ class AscendPerson(_StopRecurse, _PersonSeen):
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
|
||||
# we have a valid person, add him/her
|
||||
self._add_person((generation, index), person_handle, full_family_handle)
|
||||
self._add_person((generation, index), person_handle,
|
||||
full_family_handle)
|
||||
|
||||
# has the user canceled recursion?
|
||||
if not self.can_recurse():
|
||||
self.continue_recursion()
|
||||
return
|
||||
|
||||
|
||||
#Now recurse on the parents
|
||||
# Now recurse on the parents
|
||||
family_handle = person.get_main_parents_family_handle()
|
||||
|
||||
if family_handle is not None:
|
||||
@@ -498,21 +499,26 @@ class AscendPerson(_StopRecurse, _PersonSeen):
|
||||
mother_handle = None
|
||||
|
||||
# Recursively call the function. It is okay if the handle is None,
|
||||
self.__iterate(generation+1, index*2, father_handle, family_handle) #recurse on dad
|
||||
self.__iterate(generation + 1, index * 2, father_handle,
|
||||
family_handle) # recurse on dad
|
||||
if generation < self.max_generations:
|
||||
if father_handle is not None: # Stil winin max_generations
|
||||
self.add_marriage((generation+1, index*2), father_handle, family_handle)
|
||||
self.add_marriage((generation + 1, index * 2), father_handle,
|
||||
family_handle)
|
||||
elif mother_handle is not None:
|
||||
self.add_marriage((generation+1, index*2), mother_handle, family_handle)
|
||||
self.add_marriage((generation + 1, index * 2), mother_handle,
|
||||
family_handle)
|
||||
elif family_handle is not None:
|
||||
self.add_marriage((generation+1, index*2), None, family_handle)
|
||||
self.add_marriage((generation + 1, index * 2), None,
|
||||
family_handle)
|
||||
elif self.fill_out > 0:
|
||||
self.add_marriage((generation+1, index*2), None, None)
|
||||
self.add_marriage((generation + 1, index * 2), None, None)
|
||||
|
||||
if not self.can_recurse():
|
||||
self.continue_recursion()
|
||||
return
|
||||
self.__iterate(generation+1, (index*2)+1, mother_handle, family_handle) #recurse mom
|
||||
self.__iterate(generation + 1, (index * 2) + 1, mother_handle,
|
||||
family_handle) # recurse mom
|
||||
|
||||
def recurse(self, person_handle):
|
||||
"""
|
||||
|
||||
@@ -405,7 +405,6 @@ class GeoGraphyView(OsmGps, NavigationView):
|
||||
|
||||
self.changemap = Gtk.Menu()
|
||||
changemap = self.changemap
|
||||
changemap.set_title(title)
|
||||
changemap.show()
|
||||
add_item.set_submenu(changemap)
|
||||
# show in the map menu all available providers
|
||||
@@ -885,7 +884,6 @@ class GeoGraphyView(OsmGps, NavigationView):
|
||||
menu.append(add_item)
|
||||
self.itemoption = Gtk.Menu()
|
||||
itemoption = self.itemoption
|
||||
itemoption.set_title(message)
|
||||
itemoption.show()
|
||||
add_item.set_submenu(itemoption)
|
||||
modify = Gtk.MenuItem(label=_("Edit Place"))
|
||||
@@ -990,11 +988,11 @@ class GeoGraphyView(OsmGps, NavigationView):
|
||||
filtering = Gtk.FileFilter()
|
||||
filtering.add_pattern("*.kml")
|
||||
kml = Gtk.FileChooserDialog(
|
||||
_("Select a kml file used to add places"),
|
||||
title=_("Select a kml file used to add places"),
|
||||
action=Gtk.FileChooserAction.OPEN,
|
||||
parent=self.uistate.window,
|
||||
buttons=(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'), Gtk.ResponseType.OK))
|
||||
transient_for=self.uistate.window)
|
||||
kml.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'), Gtk.ResponseType.OK)
|
||||
mpath = HOME_DIR
|
||||
kml.set_current_folder(os.path.dirname(mpath))
|
||||
kml.set_filter(filtering)
|
||||
@@ -1286,13 +1284,11 @@ class GeoGraphyView(OsmGps, NavigationView):
|
||||
"""
|
||||
dummy_obj = obj
|
||||
selected_dir = Gtk.FileChooserDialog(
|
||||
_("Select tile cache directory for offline mode"),
|
||||
title=_("Select tile cache directory for offline mode"),
|
||||
action=Gtk.FileChooserAction.SELECT_FOLDER,
|
||||
parent=self.uistate.window,
|
||||
buttons=(_('_Cancel'),
|
||||
Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'),
|
||||
Gtk.ResponseType.OK))
|
||||
transient_for=self.uistate.window)
|
||||
selected_dir.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
|
||||
_('_Apply'), Gtk.ResponseType.OK)
|
||||
mpath = config.get('geography.path')
|
||||
if not mpath:
|
||||
mpath = HOME_DIR
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user