Compare commits

...

57 Commits

Author SHA1 Message Date
romjerome 1c241125d7 8555: Database repair tool always modify all source objects 2016-11-26 12:51:56 +01:00
romjerome e81c82fcc0 9003: Locality data in address was not imported 2015-10-27 09:48:20 +01:00
romjerome 7d91f4fae8 8188: Problem with existing selection in media reference editor
like selection box disappears when scrollbar appears

Now, do not expand bottom section (Media Object fields) by default

Wonder if we should not do that on all Reference Editors?
2015-09-24 11:07:56 +02:00
Nick Hall 78a74cae5c Make place title in GEDCOM export date dependent 2015-07-25 23:17:08 +01:00
Doug Blank 5039ad10f0 7261: Import GEDCOM file from MyHeritage, added __str__ to Attribute 2015-07-23 10:25:36 -04:00
Doug Blank 926bb60650 Merge pull request #43 from sam-m888/8702UpdateMapServicelinksOpenStreetMap
8702 Update Map Service links for OpenStreetMap
2015-07-14 07:04:24 -04:00
Doug Blank 314484cf84 Merge pull request #41 from ennoborg/maintenance/gramps41
8663: add exception for UnicodeEncodeError.
2015-07-13 23:12:01 -04:00
Enno Borgsteede ae0a039216 8663: add exception for UnicodeEncodeError. 2015-07-12 11:41:57 +02:00
kulath 296e8ca562 fix testcasegenerator AttributeError 2015-06-20 00:14:52 +02:00
kulath 4e6a06bfac 0008537: Gedcom import crashes. Fix problem when matching places with
the same name which are enclosed by different places.
2015-06-18 22:52:53 +01:00
Doug Blank 5ff70a665e Merge pull request #37 from ennoborg/maintenance/gramps41
Re-aligned check buttons in remove unused objects dialog.
2015-06-18 16:03:41 -04:00
Enno Borgsteede c0a0c1d302 Re-aligned check buttons in remove unused objects dialog. 2015-06-18 21:34:21 +02:00
kulath e71115af1b 8614: pickleupgrade.txt should not be written for python2 2015-06-18 20:25:33 +01:00
Doug Blank 5828dd3aa8 8537: Gedcom import crashes; kulath patch 2015-06-17 07:59:19 -04:00
Doug Blank 273a5f986f 8614: addresses pickleupgrade.txt issue, by kulath 2015-06-17 06:27:08 -04:00
Hivernat Emmanuel 00032f0cad 7347: fix a bug 'on mouse over' event 2015-06-12 16:37:45 +02:00
Josip 1ed6103a41 8625: Cannot open Citation references from Clip Board 2015-06-12 16:07:44 +02:00
Zdeněk Hataš ea2c71d238 fix mistake that prevent python2 to work 2015-06-07 11:10:22 +02:00
SNoiraud 6605d868cb Geography : bug 8612 : introspection problem with gtk 3.16. 2015-06-07 10:30:00 +02:00
Doug Blank 7a57c8584e 8621: Recursion Filter error 2015-06-06 19:58:41 -04:00
Zdeněk Hataš 46a509ee1d merge inflection fixes for cs lang from gramps42 branch 2015-06-06 14:14:29 +02:00
Josip 1aad1d6be0 Data Verify Tool: fix set transient parent 2015-06-05 12:13:43 +02:00
Josip 104808cf8f Relationship Calculator: fix set transient parent 2015-06-05 12:11:44 +02:00
Josip 8a34d98fb5 8619: Relationship Calculator - can't select person to relate to 2015-06-04 23:01:49 +02:00
erikdrgm c42f714393 Updated 150602 Dutch translation 2015-06-02 21:18:49 +02:00
erikdrgm d8ba31cc29 Merge branch 'maintenance/gramps41' of github.com:gramps-project/gramps into gramps41 2015-06-02 20:48:50 +02:00
Nick Hall f9bb9e5e73 8488: Use place displayer for headings 2015-05-28 19:57:54 +01:00
Nick Hall ed0b50e9b8 8487: Use place displayer to generate title in views 2015-05-28 16:31:59 +01:00
Jérôme Rapinat 19acd368c0 8583: Custom Events not shown in the filter siderbar 2015-05-26 20:51:30 +02:00
Enno Borgsteede 9de644bf1d #4161 #8548: Fix a baptism date error
https://gramps-project.org/bugs/view.php?id=8548#c41455

also reported and patched by 'hmmmpf' on #4161
2015-05-26 20:38:03 +02:00
Jérôme Rapinat bdd70dec1c 4161: Fix empty #buri fields
Still present on Geneweb 6 and 7alpha

patch by 'hmmmpf'
2015-05-26 20:36:37 +02:00
Jérôme Rapinat 2a26ca6c5c 8567: Imprecise French translation in Place dialog
'Enclosed by' was translated in French by 'Lié à'
2015-05-26 18:55:20 +02:00
Jérôme Rapinat f675fc1114 8580: "_Apply" button not translated on "Events comparison" tool 2015-05-26 18:46:44 +02:00
Doug Blank 143df8d42c Merge pull request #23 from belissent/belissent/gramps41
Modification for example.gramps database 
(custom parent relationship, notes)
2015-05-24 17:00:59 -04:00
Josip d71a36b240 8579: Creation of Narration Website report fails 2015-05-24 12:13:54 +02:00
Josip 085d1ee095 8398: lock.file with accent letter cause gramps to crash at start 2015-05-22 18:55:21 +02:00
Leonhaeuser cc2f803b86 update German translation 2015-05-17 10:30:04 +02:00
Josip 9c34e17bd9 Fix AgeStats gramplet for Python3 2015-05-16 12:51:18 +02:00
Josip 136bdd015a fix identation error of 8561#c41511 2015-05-16 06:06:14 +02:00
Josip e0b56f65ef 8561#c41511 2015-05-16 05:04:48 +02:00
Josip 089d028e8f 8562: Cannot create family lines diagram 2015-05-16 04:50:07 +02:00
Josip 6e4ce84396 Set transient parent for errorview and errorreportassistant 2015-05-16 04:19:11 +02:00
Josip 0930c0041f 8561: Problem with importing ged file from My Heritage 2015-05-16 00:32:40 +02:00
Doug Blank ef0492e0ff 8564: Recursion error when filtering for relatives 2015-05-15 18:01:59 -04:00
Josip e1a71dcd34 8497: Error on use of Ctrl-Z 2015-05-14 17:30:41 +02:00
Pierre Bélissent 6895594cdc Modification for exemple.gramps database (custom parent relationship, notes)
Modification for exemple.gramps database (custom parent relationship,
notes):
- Added custom parent relationship for I0044
- Added notes with ID: '_header1', '_footer1', '_custom1'
- Added a date for media O0010
These modifications are used for the DynamicWeb report addon tests.
2015-05-11 18:36:48 +02:00
Josip 45f82f1ec5 Workaround for broken introspection
8474: Crash after merge places
8498: Crash when attempting to add gramplet
8536: clicking on tag icon in person view causes gramps to crash
2015-05-11 17:45:42 +02:00
Josip c26fcf6d56 8445: Drag & Drop to add media: wrong handling of non-ascii characters 2015-05-07 21:04:22 +02:00
Doug Blank 2701d51b62 8541: Crash following update: addon permission issue blocks
re-starting gramps

There were two issues:

1. attempting to read a new addon file that wasn't readable
   threw an exception, aborted updating addons

2. global error catching didn't properly handle error code
   from an OSError for Python3
2015-05-05 13:44:20 -04:00
Matti Niemelä 9683a9e9eb new Finnish translation for gramps41 2015-05-05 00:37:14 -07:00
Jérôme Rapinat d03e9e6553 fix mistake on versioning (inherited from '4.1.3' release) 2015-05-03 17:41:26 +02:00
Josip 0f8b77b706 8469: GUI allows multiple Find Duplicates, then faults
Yet another case of dialog without transient parent
2015-05-03 11:32:07 +02:00
John Ralls a2244c6ab4 Update mac info for 4.1.3 release. 2015-05-02 11:53:51 -07:00
Jérôme Rapinat 2eccc6c4ce 8532: typo on the french translation
plural = single form for month(s) (moi => mois)
2015-05-02 17:02:27 +02:00
Jérôme Rapinat 815596a88d bump to 4.1.4 2015-05-02 10:51:08 +02:00
SNoiraud 98fdeaeb6b narrativeweb : bug 8528 : local variable 'body' referenced before assignment 2015-05-01 10:32:55 +02:00
erikdrgm 69e7501acc Update Dutch Translation 2015-03-09 10:09:38 +01:00
59 changed files with 13807 additions and 17277 deletions
+109 -21
View File
@@ -3,11 +3,11 @@
"http://gramps-project.org/xml/1.6.0/grampsxml.dtd">
<database xmlns="http://gramps-project.org/xml/1.6.0/">
<header>
<created date="2014-11-13" version="4.1.0"/>
<created date="2015-05-10" version="4.1.4"/>
<researcher>
<resname>Alex Roitman,,,</resname>
</researcher>
<mediapath>/home/cristina/gramps/master/example/gramps</mediapath>
<mediapath>/home/pierre/Gramps/master/example/gramps</mediapath>
</header>
<name-formats>
<format number="-1" name="SURNAME, Given (Common)" fmt_str="SURNAME, given (common)" active="1"/>
@@ -91,6 +91,11 @@
<dateval val="1592" type="about"/>
<description>Birth of Abbott, Frances</description>
</event>
<event handle="_a5af0eb6abd74c3d7fc" change="1284030605" id="E3415">
<type>Death</type>
<dateval val="1642-01" type="about"/>
<description>Death of Abbott, Frances</description>
</event>
<event handle="_a5af0eb6add73de72aa" change="1284030598" id="E0014">
<type>Birth</type>
<dateval val="1520" type="about"/>
@@ -17897,11 +17902,6 @@
<type>Death</type>
<dateval val="1850" type="about" quality="estimated"/>
</event>
<event handle="_a5af0eb6abd74c3d7fc" change="1284030605" id="E3415">
<type>Death</type>
<dateval val="1642-01" type="about"/>
<description>Death of Abbott, Frances</description>
</event>
</events>
<people home="_GNUJQCL9MD64AM56OH">
<person handle="_004KQCGYT27EEPQHK" change="1185438865" id="I0552">
@@ -20260,7 +20260,7 @@
<parentin hlink="_HQ8KQCT2UX4S9I0E26"/>
<citationref hlink="_c140d24b31f74169170"/>
</person>
<person handle="_3RFKQCNKMX9HVLNSLW" change="1185438865" id="I1116">
<person handle="_3RFKQCNKMX9HVLNSLW" change="1431174900" id="I1116">
<gender>F</gender>
<name type="Birth Name">
<surname>Garner</surname>
@@ -22104,7 +22104,7 @@
<parentin hlink="_JT4KQC83ZKPOLC0UEJ"/>
<citationref hlink="_c140d24fa2503a14583"/>
</person>
<person handle="_6TFKQCUTO94WB2NHN" change="1185438865" id="I1119">
<person handle="_6TFKQCUTO94WB2NHN" change="1431174900" id="I1119">
<gender>F</gender>
<name type="Birth Name">
<first>Zelpha Josephine</first>
@@ -23913,7 +23913,7 @@
<parentin hlink="_1RUJQCCL9MVRYLMTBO"/>
<citationref hlink="_c140d254dcc234394a3"/>
</person>
<person handle="_9QFKQC54ET79K2SD57" change="1185438865" id="I1115">
<person handle="_9QFKQC54ET79K2SD57" change="1431174900" id="I1115">
<gender>F</gender>
<name type="Birth Name">
<first>Mary M.</first>
@@ -24600,7 +24600,7 @@
<parentin hlink="_4W1KQCYZD6N5M576RA"/>
<citationref hlink="_c140d2566d57b164cf5"/>
</person>
<person handle="_AWFKQCJELLUWDY2PD3" change="1284030919" id="I1123">
<person handle="_AWFKQCJELLUWDY2PD3" change="1431174900" id="I1123">
<gender>M</gender>
<name type="Birth Name">
<first>Robert F.</first>
@@ -27182,7 +27182,7 @@
<parentin hlink="_0Q3KQCBZ4421A3L5B4"/>
<citationref hlink="_c140d25c5be3120050a"/>
</person>
<person handle="_EPFKQCETTDTEL3PYIR" change="1185438865" id="I1114">
<person handle="_EPFKQCETTDTEL3PYIR" change="1431174900" id="I1114">
<gender>F</gender>
<name type="Birth Name">
<first>Mary J.</first>
@@ -28226,7 +28226,7 @@
<parentin hlink="_BWAKQCZLIWDX9ZEFED"/>
<citationref hlink="_c140d25eec45aabbd80"/>
</person>
<person handle="_GNUJQCL9MD64AM56OH" change="1328027440" id="I0044">
<person handle="_GNUJQCL9MD64AM56OH" change="1431174904" id="I0044">
<gender>M</gender>
<name type="Birth Name">
<first>Lewis Anderson</first>
@@ -28454,7 +28454,7 @@
<childof hlink="_05XJQC935HU62H3KL4"/>
<citationref hlink="_c140d25f5c448b251ca"/>
</person>
<person handle="_GYFKQCPH8Q0JDN94GR" change="1185438865" id="I1126">
<person handle="_GYFKQCPH8Q0JDN94GR" change="1431174900" id="I1126">
<gender>F</gender>
<name type="Birth Name">
<first>Anetta</first>
@@ -32105,7 +32105,7 @@
<parentin hlink="_ZA6KQC27P0I8E2JZUC"/>
<citationref hlink="_c140d2677c105a1b132"/>
</person>
<person handle="_MUFKQCMXUJ07MCDUNI" change="1185438865" id="I1121">
<person handle="_MUFKQCMXUJ07MCDUNI" change="1431174900" id="I1121">
<gender>F</gender>
<name type="Birth Name">
<first>Iola Elizabeth Betty</first>
@@ -33279,7 +33279,7 @@
<parentin hlink="_9SEKQCAAWRUCIO7A0M"/>
<citationref hlink="_c140d269f4c7c13bf87"/>
</person>
<person handle="_ORFKQC4KLWEGTGR19L" change="1185438865" id="I1117">
<person handle="_ORFKQC4KLWEGTGR19L" change="1431174900" id="I1117">
<gender>F</gender>
<name type="Birth Name">
<first>Rebecca Catharine</first>
@@ -33963,7 +33963,7 @@
<parentin hlink="_IXDKQCOYLEMDKWJZPC"/>
<citationref hlink="_c140d26b98d33ec7f15"/>
</person>
<person handle="_PXFKQCXEHJX3W1Q1IV" change="1185438865" id="I1125">
<person handle="_PXFKQCXEHJX3W1Q1IV" change="1431174900" id="I1125">
<gender>F</gender>
<name type="Birth Name">
<first>Emma A.</first>
@@ -35695,7 +35695,7 @@
<parentin hlink="_FP4KQCQQX8O84KK3IF"/>
<citationref hlink="_c140d27142a05b2d019"/>
</person>
<person handle="_SOFKQCBYAO18OWC0CS" change="1185438865" id="I1113">
<person handle="_SOFKQCBYAO18OWC0CS" change="1431174900" id="I1113">
<gender>F</gender>
<name type="Birth Name">
<first>Phebe</first>
@@ -37068,7 +37068,7 @@
<parentin hlink="_7ZWJQC8ZR4WJZE09RW"/>
<citationref hlink="_c140d276c1802ec5ac3"/>
</person>
<person handle="_UZFKQCIHVT44DC9KGH" change="1185438865" id="I1128">
<person handle="_UZFKQCIHVT44DC9KGH" change="1431174900" id="I1128">
<gender>F</gender>
<name type="Birth Name">
<first>Antoinette</first>
@@ -42060,12 +42060,12 @@
<childref hlink="_GH0KQCGPLF5J17PELU"/>
<citationref hlink="_c140d286d0e2f46fb29"/>
</family>
<family handle="_8OUJQCUVZ0XML7BQLF" change="1185438865" id="F0018">
<family handle="_8OUJQCUVZ0XML7BQLF" change="1431174900" id="F0018">
<rel type="Married"/>
<father hlink="_35WJQC1B7T7NPV8OLV"/>
<mother hlink="_46WJQCIOLQ0KOX2XCC"/>
<eventref hlink="_a5af0ed602318310d6d" role="Family"/>
<childref hlink="_GNUJQCL9MD64AM56OH"/>
<childref hlink="_GNUJQCL9MD64AM56OH" mrel="Custom relationship to mother" frel="Custom relationship to father"/>
<childref hlink="_SOFKQCBYAO18OWC0CS"/>
<childref hlink="_EPFKQCETTDTEL3PYIR"/>
<childref hlink="_9QFKQC54ET79K2SD57"/>
@@ -63928,6 +63928,94 @@ page 26 Repository:Address</text>
<range start="0" end="705"/>
</style>
</note>
<note handle="_d0436bba4ec328d3b631259a4ee" change="1431184305" id="_header1" type="General">
<text>Title for the example pages</text>
<style name="fontcolor" value="#ef2929">
<range start="0" end="27"/>
</style>
<style name="underline">
<range start="0" end="27"/>
</style>
<style name="fontface" value="Serif">
<range start="0" end="27"/>
</style>
<style name="bold">
<range start="0" end="27"/>
</style>
<style name="fontsize" value="8">
<range start="0" end="27"/>
</style>
</note>
<note handle="_d0436bcc69d6bba278bff5bc7db" change="1431184300" id="_footer1" type="General">
<text>Footer: exported by __GRAMPS_HOMEPAGE__ on __EXPORT_DATE__</text>
</note>
<note handle="_d0436be64ac277b615b79b34e72" change="1431211661" id="_custom1" type="General">
<text>Export date: __EXPORT_DATE__
GRAMPS homepage: __GRAMPS_HOMEPAGE__
GRAMPS version: __GRAMPS_VERSION__
Number of families: __NB_FAMILIES__
Number of persons: __NB_INDIVIDUALS__
Number of media objects: __NB_MEDIA__
Number of sources: __NB_SOURCES__
Number of repositories: __NB_REPOSITORIES__
Number of places: __NB_PLACES__
Search form:
__SEARCH_FORM__
Test link person: Garner von Zieliński, Lewis Anderson Sr
Test link family: Family of Warner, Allen Carl and Garner, Rita Marie
Test link source: World of the Wierd
Test link media: 1897_expeditionsmannschaft_rio_a
Test link place: Warren-Farmington Hills-Troy, MI
Test internet link: blog.codinghorror.com
Test relative path link: relative file path to &quot;archive.zip&quot;
Test relative path link: relative file path to &quot;archive.tgz&quot;
Thumbnail for &quot;1897_expeditionsmannschaft_rio_a&quot;:
__THUMB_O0010__
Image &quot;AntoineClaudet&quot;:
__MEDIA_O0011__
Thumbnail for &quot;1897_expeditionsmannschaft_rio_a&quot; with link:
__THUMB_O0010__
Image &quot;AntoineClaudet&quot; with link:
__MEDIA_O0011__
Wrong media ID:
__MEDIA_wrong id__</text>
<style name="link" value="relative://relative.archive.zip">
<range start="663" end="686"/>
</style>
<style name="link" value="gramps://Media/handle/238CGQ939HG18SS5MG">
<range start="952" end="967"/>
</style>
<style name="link" value="gramps://Media/handle/238CGQ939HG18SS5MG">
<range start="520" end="535"/>
</style>
<style name="link" value="gramps://Family/handle/48TJQCGNNIR5SJRCAK">
<range start="413" end="429"/>
</style>
<style name="link" value="gramps://Person/handle/GNUJQCL9MD64AM56OH">
<range start="355" end="371"/>
</style>
<style name="link" value="http://blog.codinghorror.com/">
<range start="621" end="639"/>
</style>
<style name="link" value="gramps://Source/handle/VUBKMQTA2XZG1V6QP8">
<range start="483" end="499"/>
</style>
<style name="link" value="gramps://Place/handle/3WTJQCB9F2MX9W98VP">
<range start="570" end="585"/>
</style>
<style name="link" value="gramps://Media/handle/Y3ARGQWE088EQRTTDH">
<range start="1002" end="1017"/>
</style>
<style name="link" value="relative://relative.archive.tgz">
<range start="724" end="747"/>
</style>
</note>
</notes>
<bookmarks>
<bookmark target="person" hlink="_AWFKQCJELLUWDY2PD3"/>
+3 -1
View File
@@ -497,6 +497,8 @@ def time_val(dirpath):
if tval_mod > tval:
tval = tval_mod
last = time.strftime('%x %X', time.localtime(tval))
if sys.version_info[0] < 3:
last = last.decode(glocale.encoding)
else:
tval = 0
last = _("Never")
@@ -517,6 +519,6 @@ def find_locker_name(dirpath):
# feature request 2356: avoid genitive form
last = _("Locked by %s") % username
ifile.close()
except (OSError, IOError):
except (OSError, IOError, UnicodeDecodeError):
last = _("Unknown")
return last
+3 -1
View File
@@ -221,7 +221,9 @@ class DateDisplayCZ(DateDisplay):
# this must agree with DateDisplayEn's "formats" definition
# (since no locale-specific _display_gregorian exists, here)
def display(self, date):
display = DateDisplay.display_formatted
def orig_display(self, date):
"""
Return a text string representing the date.
"""
+6 -1
View File
@@ -27,6 +27,7 @@ Class handling language-specific selection for date parser and displayer.
# Python modules
#
#-------------------------------------------------------------------------
import sys
import time
#-------------------------------------------------------------------------
@@ -35,6 +36,7 @@ import time
#
#-------------------------------------------------------------------------
from ..lib.date import Date
from ..const import GRAMPS_LOCALE as glocale
from . import LANG_TO_DISPLAY, LANG, parser, displayer
#--------------------------------------------------------------
@@ -94,4 +96,7 @@ def format_time(secs):
"""
t = time.localtime(secs)
d = Date(t.tm_year, t.tm_mon, t.tm_mday)
return displayer.display(d) + time.strftime(' %X', t)
if sys.version_info[0] < 3:
return displayer.display(d) + time.strftime(' %X', t).decode(glocale.encoding)
else:
return displayer.display(d) + time.strftime(' %X', t)
+8 -8
View File
@@ -2471,14 +2471,14 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
with open(versionpath, "w") as version_file:
version_file.write(version)
versionpath = os.path.join(name, cuni(PCKVERSFN))
_LOG.debug("Write pickle version file to %s" % "Yes")
with open(versionpath, "w") as version_file:
version = "Yes"
if sys.version_info[0] <3:
if isinstance(version, UNITYPE):
version = version.encode('utf-8')
version_file.write(version)
# The pickle upgrade file is not written for Python2; its contents is
# never actually examined, all that matters is whether it is present
if sys.version_info[0] >= 3:
versionpath = os.path.join(name, cuni(PCKVERSFN))
_LOG.debug("Write pickle version file to %s" % "Yes")
with open(versionpath, "w") as version_file:
version = "Yes"
version_file.write(version)
versionpath = os.path.join(name, cuni(SCHVERSFN))
_LOG.debug("Write schema version file to %s" % str(_DBVERSION))
@@ -78,22 +78,26 @@ class IsDescendantFamilyOf(Rule):
return
# Add self
self.matches.add(person.handle)
expand = [person]
for family_handle in person.get_family_handle_list():
family = self.db.get_family_from_handle(family_handle)
if family:
# Add every child recursively
for child_ref in family.get_child_ref_list():
if child_ref:
self.add_matches(self.db.get_person_from_handle(child_ref.ref))
# Add spouse
if person.handle == family.get_father_handle():
spouse_handle = family.get_mother_handle()
else:
spouse_handle = family.get_father_handle()
self.matches.add(spouse_handle)
while expand:
person = expand.pop(0)
if person is None:
continue
self.matches.add(person.handle)
for family_handle in person.get_family_handle_list():
family = self.db.get_family_from_handle(family_handle)
if family:
# Add every child recursively
for child_ref in family.get_child_ref_list():
if child_ref:
expand.append(self.db.get_person_from_handle(child_ref.ref))
# Add spouse
if person.handle == family.get_father_handle():
spouse_handle = family.get_mother_handle()
else:
spouse_handle = family.get_father_handle()
self.matches.add(spouse_handle)
def exclude(self):
# This removes root person and his/her spouses from the matches set
@@ -63,34 +63,42 @@ class IsRelatedWith(Rule):
return person.handle in self.relatives
def add_relative(self, person):
"""Recursive function that scans relatives and add them to self.relatives"""
if not(person) or person.handle in self.relatives:
def add_relative(self, start):
"""Non-recursive function that scans relatives and add them to self.relatives"""
if not(start):
return
# Add the relative to the list
self.relatives.append(person.handle)
expand = [start]
relatives = {}
while expand:
person = expand.pop()
# Add the relative to the list
if person is None or (person.handle in relatives):
continue
relatives[person.handle] = True
for family_handle in person.get_parent_family_handle_list():
family = self.db.get_family_from_handle(family_handle)
if family:
# Check Parents
for parent_handle in (family.get_father_handle(), family.get_mother_handle()):
if parent_handle:
self.add_relative(self.db.get_person_from_handle(parent_handle))
# Check Sibilings
for child_ref in family.get_child_ref_list():
self.add_relative(self.db.get_person_from_handle(child_ref.ref))
for family_handle in person.get_family_handle_list():
family = self.db.get_family_from_handle(family_handle)
if family:
# Check Spouse
for parent_handle in (family.get_father_handle(), family.get_mother_handle()):
if parent_handle:
self.add_relative(self.db.get_person_from_handle(parent_handle))
# Check Children
for child_ref in family.get_child_ref_list():
self.add_relative(self.db.get_person_from_handle(child_ref.ref))
return
for family_handle in person.get_parent_family_handle_list():
family = self.db.get_family_from_handle(family_handle)
if family:
# Check Parents
for parent_handle in (family.get_father_handle(), family.get_mother_handle()):
if parent_handle:
expand.append(self.db.get_person_from_handle(parent_handle))
# Check Sibilings
for child_ref in family.get_child_ref_list():
expand.append(self.db.get_person_from_handle(child_ref.ref))
for family_handle in person.get_family_handle_list():
family = self.db.get_family_from_handle(family_handle)
if family:
# Check Spouse
for parent_handle in (family.get_father_handle(), family.get_mother_handle()):
if parent_handle:
expand.append(self.db.get_person_from_handle(parent_handle))
# Check Children
for child_ref in family.get_child_ref_list():
expand.append(self.db.get_person_from_handle(child_ref.ref))
self.relatives = list(relatives.keys())
return
+3
View File
@@ -67,6 +67,9 @@ class AttributeRoot(SecondaryObject, PrivacyBase):
self.type = None
self.value = None
def __str__(self):
return str(self.value)
def serialize(self):
"""
Convert the object to a serialized tuple of data.
+10 -4
View File
@@ -1100,10 +1100,16 @@ class PluginRegister(object):
continue
lenpd = len(self.__plugindata)
full_filename = os.path.join(dir, filename)
if sys.version_info[0] < 3:
fd = open(full_filename, "r")
else:
fd = io.open(full_filename, "r", encoding='utf-8')
try:
if sys.version_info[0] < 3:
fd = open(full_filename, "r")
else:
fd = io.open(full_filename, "r", encoding='utf-8')
except Exception as msg:
print(_('ERROR: Failed reading plugin registration %(filename)s') % \
{'filename' : filename})
print(msg)
continue
stream = fd.read()
fd.close()
if os.path.exists(os.path.join(os.path.dirname(full_filename),
+2
View File
@@ -195,4 +195,6 @@ def create_checksum(full_path):
md5sum = hashlib.md5(media_file.read()).hexdigest()
except IOError:
md5sum = ''
except UnicodeEncodeError:
md5sum = ''
return md5sum
+9 -3
View File
@@ -29,6 +29,7 @@ Make an 'Unknown' primary object
# Python modules
#
#-------------------------------------------------------------------------
import sys
import time
import os
@@ -146,8 +147,11 @@ def make_unknown(class_arg, explanation, class_func, commit_func, transaction,
elif isinstance(obj, Tag):
if not hasattr(make_unknown, 'count'):
make_unknown.count = 1 #primitive static variable
tval = time.strftime('%x %X', time.localtime())
if sys.version_info[0] < 3:
tval = tval.decode(glocale.encoding)
obj.set_name(_("Unknown, was missing %(time)s (%(count)d)") % {
'time': time.strftime('%x %X', time.localtime()),
'time': tval,
'count': make_unknown.count})
make_unknown.count += 1
else:
@@ -165,9 +169,11 @@ def create_explanation_note(dbase):
those objects of type "Unknown" need a explanatory note. This funcion
provides such a note for import methods.
"""
tval = time.strftime('%x %X', time.localtime())
if sys.version_info[0] < 3:
tval = tval.decode(glocale.encoding)
note = Note( _('Objects referenced by this note '
'were missing in a file imported on %s.') %
time.strftime('%x %X', time.localtime()))
'were missing in a file imported on %s.') % tval)
note.set_handle(create_id())
note.set_gramps_id(dbase.find_next_note_gramps_id())
# Use defaults for privacy, format and type.
+10 -1
View File
@@ -1564,7 +1564,8 @@ class MultiTreeView(Gtk.TreeView):
def edit_obj(self, objclass, handle):
from .editors import (EditPerson, EditEvent, EditFamily, EditSource,
EditPlace, EditRepository, EditNote, EditMedia)
EditPlace, EditRepository, EditNote, EditMedia,
EditCitation)
if objclass == 'Person':
person = self.dbstate.db.get_person_from_handle(handle)
if person:
@@ -1629,6 +1630,14 @@ class MultiTreeView(Gtk.TreeView):
self.uistate, [], ref)
except WindowActiveError:
pass
elif objclass == 'Citation':
ref = self.dbstate.db.get_citation_from_handle(handle)
if ref:
try:
EditCitation(self.dbstate,
self.uistate, [], ref)
except WindowActiveError:
pass
def short(val,size=60):
if len(val) > size:
+3 -10
View File
@@ -514,17 +514,10 @@ class GalleryTab(ButtonTab, DbGUIElement):
elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type:
self.handle_extra_type(mytype, obj)
except pickle.UnpicklingError:
#modern file managers provide URI_LIST. For Windows split sel_data.data
if win():
files = sel_data.get_data().split('\n')
else:
files = sel_data.get_uris()
files = sel_data.get_uris()
for file in files:
if win():
d = conv_to_unicode((file.replace('\0',' ').strip()), None)
else:
d = file
protocol, site, mfile, j, k, l = urlparse(d)
protocol, site, mfile, j, k, l = urlparse(file)
if protocol == "file":
name = url2pathname(mfile)
mime = get_type(name)
@@ -62,11 +62,13 @@ class EventSidebarFilter(SidebarFilter):
self.filter_event = Event()
self.filter_event.set_type((EventType.CUSTOM, ''))
self.etype = Gtk.ComboBox(has_entry=True)
self.custom_types = dbstate.db.get_event_types()
self.event_menu = widgets.MonitoredDataType(
self.etype,
self.filter_event.set_type,
self.filter_event.get_type)
self.filter_event.get_type,
custom_values=self.custom_types)
self.filter_mainparts = widgets.BasicEntry()
self.filter_date = widgets.DateEntry(uistate, [])
-1
View File
@@ -2,7 +2,6 @@
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkDialog" id="clipboard">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Clipboard</property>
<property name="default_width">500</property>
-1
View File
@@ -391,7 +391,6 @@ You can use the mouse on the picture to select a region, or use these spinbutton
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="expanded">True</property>
<child>
<object class="GtkNotebook" id="notebook_shared">
<property name="visible">True</property>
+1 -1
View File
@@ -378,7 +378,7 @@ def __startgramps(errors, argparser):
% e.code, exc_info=True)
except OSError as e:
quit_now = True
exit_code = e[0] or 1
exit_code = e.errno or 1
try:
fn = e.filename
except AttributeError:
@@ -89,6 +89,15 @@ class ErrorReportAssistant(Gtk.Assistant):
self.build_page4()
self.build_page5()
self.create_page_summary()
try:
self.set_transient_for(self.list_toplevels()[-2])
except IndexError:
self.set_position(Gtk.WindowPosition.CENTER)
self.set_urgency_hint(True)
self.set_keep_above(True)
self.set_default_size(800,-1)
self.show_all()
self.ownthread = ownthread
+7 -1
View File
@@ -82,6 +82,13 @@ class ErrorView(object):
def draw_window(self):
title = "%s - Gramps" % _("Error Report")
self.top = Gtk.Dialog(title)
try:
self.top.set_transient_for(self.top.list_toplevels()[-2])
except IndexError:
self.top.set_position(Gtk.WindowPosition.CENTER)
self.top.set_urgency_hint(True)
self.top.set_keep_above(True)
self.top.set_default_size(800,-1)
vbox = self.top.get_content_area()
vbox.set_spacing(5)
self.top.set_border_width(12)
@@ -128,7 +135,6 @@ class ErrorView(object):
vbox.pack_start(tb_expander, True, True, 5)
self.top.add_button(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL)
self.top.add_button(_("Report"),Gtk.ResponseType.YES)
self.top.add_button(Gtk.STOCK_HELP,Gtk.ResponseType.HELP)
+3
View File
@@ -41,6 +41,7 @@ from gramps.gen.const import URL_MANUAL_PAGE
from ..display import display_help
from ..managedwindow import ManagedWindow
from gramps.gen.merge import MergePlaceQuery
from gramps.gen.display.place import displayer as place_displayer
#-------------------------------------------------------------------------
#
@@ -140,6 +141,8 @@ class MergePlace(ManagedWindow):
self.get_widget(widget_name).set_sensitive(False)
# Main window widgets that determine which handle survives
title1 = place_displayer.display(database, self.pl1)
title2 = place_displayer.display(database, self.pl2)
rbutton1 = self.get_widget("handle_btn1")
rbutton_label1 = self.get_widget("label_handle_btn1")
rbutton_label2 = self.get_widget("label_handle_btn2")
+9 -1
View File
@@ -292,10 +292,18 @@ class Navigator(object):
# Functions
#
#-------------------------------------------------------------------------
def cb_menu_position(menu, button):
def cb_menu_position(*args):
"""
Determine the position of the popup menu.
"""
# takes two argument: menu, button
if len(args) == 2:
menu = args[0]
button = args[1]
# broken introspection can't handle MenuPositionFunc annotations corectly
else:
menu = args[0]
button = args[3]
ret_val, x_pos, y_pos = button.get_window().get_origin()
x_pos += button.get_allocation().x
y_pos += button.get_allocation().y + button.get_allocation().height
+9 -1
View File
@@ -277,10 +277,18 @@ class Tags(DbGUIElement):
view.add_tag(trans, object_handle, tag_handle)
status.end()
def cb_menu_position(menu, button):
def cb_menu_position(*args):
"""
Determine the position of the popup menu.
"""
# takes two argument: menu, button
if len(args) == 2:
menu = args[0]
button = args[1]
# broken introspection can't handle MenuPositionFunc annotations corectly
else:
menu = args[0]
button = args[3]
ret_val, x_pos, y_pos = button.get_window().get_origin()
x_pos += button.get_allocation().x
y_pos += button.get_allocation().y + button.get_allocation().height
+5 -2
View File
@@ -44,9 +44,10 @@ from gi.repository import Gtk
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib.placetype import PlaceType
from gramps.gen.lib import Place, PlaceType
from gramps.gen.datehandler import format_time
from gramps.gen.utils.place import conv_lat_lon
from gramps.gen.display.place import displayer as place_displayer
from gramps.gen.constfunc import cuni
from .flatbasemodel import FlatBaseModel
from .treebasemodel import TreeBaseModel
@@ -116,7 +117,9 @@ class PlaceBaseModel(object):
return len(self.fmap)+1
def column_title(self, data):
return cuni(data[2])
place = Place()
place.unserialize(data)
return place_displayer.display(self.db, place)
def column_name(self, data):
return cuni(data[6])
+9 -1
View File
@@ -734,10 +734,18 @@ class TabLabel(Gtk.HBox):
else:
self.closebtn.hide()
def cb_menu_position(menu, button):
def cb_menu_position(*args):
"""
Determine the position of the popup menu.
"""
# takes two argument: menu, button
if len(args) == 2:
menu = args[0]
button = args[1]
# broken introspection can't handle MenuPositionFunc annotations corectly
else:
menu = args[0]
button = args[3]
ret_val, x_pos, y_pos = button.get_window().get_origin()
x_pos += button.get_allocation().x
y_pos += button.get_allocation().y + button.get_allocation().height
+5 -1
View File
@@ -284,7 +284,11 @@ class UndoableEntry(Gtk.Entry):
self.set_position(undo_action.offset)
def _undo_delete(self, undo_action):
self.insert_text(undo_action.text, undo_action.start)
if not isinstance(undo_action.text, UNITYPE):
undo_action.text = conv_to_unicode(undo_action.text, 'utf-8')
with warnings.catch_warnings():
warnings.simplefilter('ignore')
self.insert_text(undo_action.text, undo_action.start)
if undo_action.delete_key_used:
self.set_position(undo_action.start)
else:
+5 -5
View File
@@ -1095,7 +1095,7 @@ class GedcomWriter(UpdateCallback):
if event.get_place_handle():
place = self.dbase.get_place_from_handle(event.get_place_handle())
self._place(place, 2)
self._place(place, dateobj, 2)
for attr in event.get_attribute_list():
attr_type = attr.get_type()
@@ -1166,8 +1166,8 @@ class GedcomWriter(UpdateCallback):
if lds_ord.get_temple():
self._writeln(index+1, 'TEMP', lds_ord.get_temple())
if lds_ord.get_place_handle():
self._place(
self.dbase.get_place_from_handle(lds_ord.get_place_handle()), 2)
place = self.dbase.get_place_from_handle(lds_ord.get_place_handle())
self._place(place, lds_ord.get_date_object(), 2)
if lds_ord.get_status() != LdsOrd.STATUS_NONE:
self._writeln(2, 'STAT', LDS_STATUS[lds_ord.get_status()])
@@ -1371,7 +1371,7 @@ class GedcomWriter(UpdateCallback):
self._note_references(photo_obj.get_note_list(), level+1)
def _place(self, place, level):
def _place(self, place, dateobj, level):
"""
PLACE_STRUCTURE:=
n PLAC <PLACE_NAME> {1:1}
@@ -1386,7 +1386,7 @@ class GedcomWriter(UpdateCallback):
+1 <<NOTE_STRUCTURE>> {0:M}
"""
if place is None: return
place_name = place_displayer.display(self.dbase, place)
place_name = place_displayer.display(self.dbase, place, dateobj)
self._writeln(level, "PLAC", place_name.replace('\r', ' '), limit=120)
longitude = place.get_longitude()
latitude = place.get_latitude()
+2 -2
View File
@@ -249,9 +249,9 @@ class AgeStatsGramplet(Gramplet):
"""
# first, binify:
#print "create_bargraph", hash
bin = [0] * (max_val/bin_size)
bin = [0] * int(max_val/bin_size)
for value, hash_value in hash.items():
bin[value/bin_size] += hash_value
bin[int(value/bin_size)] += hash_value
text = ""
max_bin = float(max(bin))
if max_bin != 0:
+6 -6
View File
@@ -644,9 +644,8 @@ class GeneWebParser(object):
birth_source = self.get_or_create_source(self.decode(fields[idx]))
idx += 1
elif field[0] == '!':
LOG.debug("Baptize at: %s" % fields[idx])
bapt_date = self.parse_date(self.decode(fields[idx][1:]))
idx += 1
LOG.debug("Baptize at: %s" % field[1:])
bapt_date = self.parse_date(self.decode(field[1:]))
elif field == '#bp' and idx < len(fields):
LOG.debug("Birth Place: %s" % fields[idx])
birth_place = self.get_or_create_place(self.decode(fields[idx]))
@@ -668,9 +667,10 @@ class GeneWebParser(object):
death_source = self.get_or_create_source(self.decode(fields[idx]))
idx += 1
elif field == '#buri' and idx < len(fields):
LOG.debug("Burial Date: %s" % fields[idx])
bur_date = self.parse_date(self.decode(fields[idx]))
idx += 1
if fields[idx][0]!='#': # bug in GeneWeb: empty #buri fields
LOG.debug("Burial Date: %s" % fields[idx])
bur_date = self.parse_date(self.decode(fields[idx]))
idx += 1
elif field == '#crem' and idx < len(fields):
LOG.debug("Cremention Date: %s" % fields[idx])
crem_date = self.parse_date(self.decode(fields[idx]))
+2 -1
View File
@@ -693,7 +693,8 @@ class GrampsParser(UpdateCallback):
"places": (None, self.stop_places),
"placeobj": (self.start_placeobj, self.stop_placeobj),
"placeref": (self.start_placeref, self.stop_placeref),
"ptitle": (None, self.stop_ptitle),
"ptitle": (None, self.stop_ptitle),
"locality": (None, self.stop_locality),
"location": (self.start_location, None),
"lds_ord": (self.start_lds_ord, self.stop_lds_ord),
"temple": (self.start_temple, None),
+121 -114
View File
@@ -2004,6 +2004,7 @@ class GedcomParser(UpdateCallback):
self.default_tag = None
self.dir_path = os.path.dirname(filename)
self.is_ftw = False
self.addr_is_detail = False
self.groups = None
self.want_parse_warnings = True
@@ -2822,7 +2823,12 @@ class GedcomParser(UpdateCallback):
else:
message = _("GEDCOM import report: %s errors detected") % \
self.number_of_errors
self.user.info(message, "".join(self.errors), monospaced=True)
if hasattr(self.user.uistate, 'window'):
parent_window = self.user.uistate.window
else:
parent_window = None
self.user.info(message, "".join(self.errors),
parent = parent_window, monospaced=True)
def __clean_up(self):
"""
@@ -2991,7 +2997,7 @@ class GedcomParser(UpdateCallback):
return True
return False
def __find_place(self, title, location):
def __find_place(self, title, location, placeref_list):
"""
Finds an existing place based on the title and primary location.
@@ -3005,31 +3011,43 @@ class GedcomParser(UpdateCallback):
place = self.dbase.get_place_from_handle(place_handle)
if place.get_title() == title:
if self.__loc_is_empty(location) and \
self.__loc_is_empty(self.__get_first_loc(place)):
self.__loc_is_empty(self.__get_first_loc(place)) and \
place.get_placeref_list() == placeref_list:
return place
elif (not self.__loc_is_empty(location) and \
not self.__loc_is_empty(self.__get_first_loc(place)) and
self.__get_first_loc(place).is_equivalent(location) == IDENTICAL):
self.__get_first_loc(place).is_equivalent(location) == IDENTICAL) and \
place.get_placeref_list() == placeref_list:
return place
return None
def __create_place(self, title, location):
def __add_place(self, event, sub_state):
"""
Create a new place based on the title and primary location.
Add a new place to an event if not already present, or update a
place.
@param title: The place title
@type title: string
@param location: The current location
@type location: gen.lib.Location
@return gen.lib.Place
@param event: The event
@type event: gen.lib.Event
@param substate: The sub-state for PLAC or ADDR elements (i.e. parsed by
event_parse_tbl)
@type sub_state: CurrentState
"""
place = Place()
place.set_title(title)
if location:
place.add_alternate_locations(location)
self.dbase.add_place(place, self.trans)
self.place_names[title].append(place.get_handle())
return place
if sub_state.place:
# see whether this place already exists
place = self.__find_place(sub_state.place.get_title(),
self.__get_first_loc(sub_state.place),
sub_state.place.get_placeref_list())
if place is None:
place = sub_state.place
self.dbase.add_place(place, self.trans)
self.place_names[place.get_title()].append(place.get_handle())
event.set_place_handle(place.get_handle())
else:
place.merge(sub_state.place)
self.dbase.commit_place(place, self.trans)
event.set_place_handle(place.get_handle())
place_title = place_displayer.display(self.dbase, place)
sub_state.pf.load_place(self.place_import, place, place_title)
def __find_file(self, fullname, altpath):
tries = []
@@ -3940,10 +3958,13 @@ class GedcomParser(UpdateCallback):
sub_state.level = state.level+1
sub_state.event = event
sub_state.event_ref = event_ref
sub_state.pf = self.place_parser
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
state.msg += sub_state.msg
self.__add_place(event, sub_state)
self.dbase.commit_event(event, self.trans)
event_ref.ref = event.handle
state.person.add_event_ref(event_ref)
@@ -4145,10 +4166,13 @@ class GedcomParser(UpdateCallback):
sub_state.level = state.level+1
sub_state.event = event
sub_state.event_ref = event_ref
sub_state.pf = self.place_parser
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
state.msg += sub_state.msg
self.__add_place(event, sub_state)
self.dbase.add_event(event, self.trans)
event_ref.ref = event.handle
state.person.add_event_ref(event_ref)
@@ -4596,12 +4620,15 @@ class GedcomParser(UpdateCallback):
"""
try:
title = line.data
place = self.__find_place(title, None)
if place:
state.place = place
place = self.__find_place(title, None, None)
if place is None:
place = Place()
place.set_title(title)
self.dbase.add_place(place, self.trans)
self.place_names[place.get_title()].append(place.get_handle())
else:
state.place = self.__create_place(title, None)
state.lds_ord.set_place_handle(state.place.handle)
pass
state.lds_ord.set_place_handle(place.handle)
except NameError:
return
@@ -4965,10 +4992,13 @@ class GedcomParser(UpdateCallback):
sub_state.level = state.level+1
sub_state.event = event
sub_state.event_ref = event_ref
sub_state.pf = self.place_parser
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
state.msg += sub_state.msg
self.__add_place(event, sub_state)
if event.type == EventType.MARRIAGE:
descr = event.get_description()
if descr == "Civil Union":
@@ -5008,9 +5038,12 @@ class GedcomParser(UpdateCallback):
sub_state.level = state.level+1
sub_state.event = event
sub_state.event_ref = event_ref
sub_state.pf = self.place_parser
self.__parse_level(sub_state, self.event_parse_tbl, self.__undefined)
state.msg += sub_state.msg
self.__add_place(event, sub_state)
self.dbase.commit_event(event, self.trans)
event_ref.ref = event.handle
@@ -5439,65 +5472,30 @@ class GedcomParser(UpdateCallback):
state.event.set_description(line.data)
else:
title = line.data
place_handle = state.event.get_place_handle()
if place_handle:
place = state.place
if place:
# We encounter a PLAC, having previously encountered an ADDR
old_place = self.dbase.get_place_from_handle(place_handle)
old_title = old_place.get_title()
location = self.__get_first_loc(old_place)
if old_title != "":
if place.get_title() and place.get_title() != "":
# We have previously found a PLAC
self.__add_msg(_("A second PLAC ignored"), line, state)
# ignore this second PLAC, and use the old one
title = old_title
place = old_place
else:
# This is the first PLAC
refs = list(self.dbase.find_backlink_handles(place_handle))
# We haven't commited the event yet, so the place will not
# be linked to it. If there are any refs they will be from
# other events (etc)
if len(refs) == 0:
place = self.__find_place(title, location)
if place is None:
place = old_place
place.set_title(title)
self.place_names[old_title].remove(place_handle)
self.place_names[title].append(place_handle)
else:
place.merge(old_place)
self.place_import.remove_location(old_place.handle)
self.dbase.remove_place(place_handle, self.trans)
self.place_names[old_title].remove(place_handle)
else:
place = self.__find_place(title, location)
if place is None:
place = self.__create_place(title, location)
else:
pass
place.set_title(line.data)
else:
# The first thing we encounter is PLAC
location = None
place = self.__find_place(title, location)
if place is None:
place = self.__create_place(title, location)
state.event.set_place_handle(place.handle)
state.place = Place()
place = state.place
place.set_title(line.data)
sub_state = CurrentState()
sub_state.place = place
sub_state.level = state.level+1
sub_state.pf = self.place_parser
self.__parse_level(sub_state, self.event_place_map,
self.__undefined)
state.msg += sub_state.msg
place_title = place_displayer.display(self.dbase, place)
sub_state.pf.load_place(self.place_import, place, place_title)
self.dbase.commit_place(place, self.trans)
def __event_place_note(self, line, state):
"""
@param line: The current line in GedLine format
@@ -5606,55 +5604,54 @@ class GedcomParser(UpdateCallback):
self.__merge_address(free_form, sub_state.location, line, state)
location = sub_state.location
place_handle = state.event.get_place_handle()
if place_handle:
# We encounter an ADDR having previously encountered a PLAC
old_place = self.dbase.get_place_from_handle(place_handle)
title = old_place.get_title()
if len(old_place.get_alternate_locations()) != 0 and \
not self.__get_first_loc(old_place).is_empty():
# We have perviously found an ADDR, or have populated location
# from PLAC title
self.__add_msg(_("Location already populated; ADDR ignored"),
line, state)
# ignore this second ADDR, and use the old one
location = self.__get_first_loc(old_place)
place = old_place
else:
# This is the first ADDR
refs = list(self.dbase.find_backlink_handles(place_handle))
# We haven't commited the event yet, so the place will not be
# linked to it. If there are any refs they will be from other
# events (etc)
if len(refs) == 0:
place = self.__find_place(title, location)
if place is None:
place = old_place
self.__add_location(place, location)
else:
place.merge(old_place)
self.place_import.remove_location(old_place.handle)
self.dbase.remove_place(place_handle, self.trans)
self.place_names[title].remove(place_handle)
else:
place = self.__find_place(title, location)
if place is None:
place = self.__create_place(title, location)
else:
pass
else:
# The first thing we encounter is ADDR
title = ""
place = self.__find_place(title, location)
if self.addr_is_detail and state.place:
# Commit the enclosing place
place = self.__find_place(state.place.get_title(), None,
state.place.get_placeref_list())
if place is None:
place = self.__create_place(title, location)
place = state.place
self.dbase.add_place(place, self.trans)
self.place_names[place.get_title()].append(place.get_handle())
else:
place.merge(state.place)
self.dbase.commit_place(place, self.trans)
place_title = place_displayer.display(self.dbase, place)
state.pf.load_place(self.place_import, place, place_title)
# Create the Place Details (it is committed with the event)
place_detail = Place()
place_detail.set_name(location.get_street())
place_detail.set_title(location.get_street())
# For RootsMagic etc. Place Details e.g. address, hospital, cemetary
place_detail.set_type((PlaceType.CUSTOM, _("Detail")))
placeref = PlaceRef()
placeref.ref = place.get_handle()
place_detail.set_placeref_list([placeref])
state.place = place_detail
else:
place = state.place
if place:
# We encounter an ADDR having previously encountered a PLAC
if len(place.get_alternate_locations()) != 0 and \
not self.__get_first_loc(place).is_empty():
# We have perviously found an ADDR, or have populated location
# from PLAC title
self.__add_msg(_("Location already populated; ADDR ignored"),
line, state)
# ignore this second ADDR, and use the old one
else:
# This is the first ADDR
place.add_alternate_locations(location)
else:
# The first thing we encounter is ADDR
state.place = Place()
place = state.place
place.add_alternate_locations(location)
# merge notes etc into place
place.merge(sub_state.place)
state.event.set_place_handle(place.get_handle())
self.dbase.commit_place(place, self.trans)
def __add_location(self, place, location):
"""
@param place: A place object we have found or created
@@ -5686,12 +5683,10 @@ class GedcomParser(UpdateCallback):
@param state: The current state
@type state: CurrentState
"""
place_handle = state.event.get_place_handle()
if place_handle:
place = self.dbase.get_place_from_handle(place_handle)
place = state.place
if place:
codes = [place.get_code(), line.data]
place.set_code(' '.join(code for code in codes if code))
self.dbase.commit_place(place, self.trans)
def __event_privacy(self, line, state):
"""
@@ -7003,6 +6998,11 @@ class GedcomParser(UpdateCallback):
self.gedsource = self.gedmap.get_from_source_tag(line.data)
if line.data.strip() in ["FTW", "FTM"]:
self.is_ftw = True
# Some software (e.g. RootsMagic (http://files.rootsmagic.com/PAF-
# Book/RootsMagic-for-PAF-Users-Printable.pdf) use the Addr fields for
# 'Place Details (address, hospital, cemetary)'
if line.data.strip().lower() in ['rootsmagic']:
self.addr_is_detail = True
# We will use the approved system ID as the name of the generating
# software, in case we do not get the name in the proper place
self.genby = line.data
@@ -7654,9 +7654,13 @@ class GedcomParser(UpdateCallback):
sub_state.event_ref = event_ref
sub_state.event = event
sub_state.person = state.person
sub_state.pf = self.place_parser
self.__parse_level(sub_state, event_map, self.__undefined)
state.msg += sub_state.msg
self.__add_place(event, sub_state)
self.dbase.commit_event(event, self.trans)
event_ref.set_reference_handle(event.handle)
@@ -7678,10 +7682,13 @@ class GedcomParser(UpdateCallback):
sub_state.level = state.level+1
sub_state.event = event
sub_state.event_ref = event_ref
sub_state.pf = self.place_parser
self.__parse_level(sub_state, event_map, self.__undefined)
state.msg += sub_state.msg
self.__add_place(event, sub_state)
self.dbase.commit_event(event, self.trans)
event_ref.set_reference_handle(event.handle)
return event_ref
+1 -3
View File
@@ -392,9 +392,7 @@ class GeoGraphyView(OsmGps, NavigationView):
clearmap.show()
menu.append(clearmap)
menu.show()
menu.popup(None, None,
lambda menu, data: (event.get_root_coords()[0],
event.get_root_coords()[1], True),
menu.popup(None, None, None,
None, event.button, event.time)
return 1
+3 -3
View File
@@ -41,7 +41,7 @@ from gramps.gen.lib import PlaceType
class OpensStreetMapService(MapService):
"""Map service using http://openstreetmap.org
Resource: http://wiki.openstreetmap.org/index.php/Name_finder
Resource: http://wiki.openstreetmap.org/wiki/Nominatim
"""
def __init__(self):
MapService.__init__(self)
@@ -64,10 +64,10 @@ class OpensStreetMapService(MapService):
city = location.get(PlaceType.CITY)
country = location.get(PlaceType.COUNTRY)
if city and country:
self.url = "http://open.mapquestapi.com/nominatim/v1/"\
self.url = "http://nominatim.openstreetmap.org/"\
"search.php?q=%s%%2C%s" % (city, country)
return
titledescr = place_displayer.display(self.database, place)
self.url = "http://open.mapquestapi.com/nominatim/v1/"\
self.url = "http://nominatim.openstreetmap.org/"\
"search.php?q=%s" % '+'.join(titledescr.split())
+9 -1
View File
@@ -205,10 +205,18 @@ class DropdownSidebar(BaseSidebar):
self.viewmanager.notebook.set_current_page(page_no)
self.__handlers_unblock()
def cb_menu_position(menu, button):
def cb_menu_position(*args):
"""
Determine the position of the popup menu.
"""
# takes two argument: menu, button
if len(args) == 2:
menu = args[0]
button = args[1]
# broken introspection can't handle MenuPositionFunc annotations corectly
else:
menu = args[0]
button = args[3]
ret_val, x_pos, y_pos = button.get_window().get_origin()
x_pos += button.get_allocation().x
y_pos += button.get_allocation().y + button.get_allocation().height
+9 -1
View File
@@ -218,10 +218,18 @@ class ExpanderSidebar(BaseSidebar):
self.viewmanager.notebook.set_current_page(page_no)
self.__handlers_unblock()
def cb_menu_position(menu, button):
def cb_menu_position(*args):
"""
Determine the position of the popup menu.
"""
# takes two argument: menu, button
if len(args) == 2:
menu = args[0]
button = args[1]
# broken introspection can't handle MenuPositionFunc annotations corectly
else:
menu = args[0]
button = args[3]
ret_val, x_pos, y_pos = button.get_window().get_origin()
x_pos += button.get_allocation().x
y_pos += button.get_allocation().y + button.get_allocation().height
+6 -3
View File
@@ -1949,6 +1949,7 @@ class CheckIntegrity(object):
source = Source()
source.unserialize(info)
new_media_ref_list = []
citation_changed = False
for media_ref in source.get_media_list():
citation_list = media_ref.get_citation_list()
new_citation_list = []
@@ -1971,6 +1972,7 @@ class CheckIntegrity(object):
citation_handle = create_id()
new_citation.set_handle(citation_handle)
self.replaced_sourceref.append(handle)
citation_changed = True
logging.warning(' FAIL: the source "%s" has a media '
'reference with a source citation '
'which is invalid' % (source.gramps_id))
@@ -1980,9 +1982,10 @@ class CheckIntegrity(object):
media_ref.set_citation_list(new_citation_list)
new_media_ref_list.append(media_ref)
source.set_media_list(new_media_ref_list)
self.db.commit_source(source, self.trans)
if citation_changed:
source.set_media_list(new_media_ref_list)
self.db.commit_source(source, self.trans)
if len(self.replaced_sourceref) > 0:
logging.info(' OK: no broken source citations on mediarefs found')
+2 -1
View File
@@ -170,12 +170,13 @@
</child>
<child>
<object class="GtkButton" id="button26">
<property name="label">_Apply</property>
<property name="label" translatable="yes">_Apply</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_apply_clicked" object="filters" swapped="yes"/>
</object>
<packing>
+3 -5
View File
@@ -122,7 +122,6 @@ class Merge(tool.Tool,ManagedWindow):
self.menu.set_active(0)
window = top.toplevel
window.show()
self.set_window(window, top.get_object('title'),
_('Find Possible Duplicate People'))
@@ -164,7 +163,7 @@ class Merge(tool.Tool,ManagedWindow):
try:
self.find_potentials(threshold)
except AttributeError as msg:
RunDatabaseRepair(str(msg))
RunDatabaseRepair(str(msg), parent=self.window)
return
self.options.handler.options_dict['threshold'] = threshold
@@ -186,8 +185,8 @@ class Merge(tool.Tool,ManagedWindow):
def find_potentials(self, thresh):
self.progress = ProgressMeter(_('Find Duplicates'),
_('Looking for duplicate people')
)
_('Looking for duplicate people'),
parent=self.window)
index = 0
males = {}
@@ -550,7 +549,6 @@ class ShowMatches(ManagedWindow):
top = Glade(toplevel="mergelist")
window = top.toplevel
window.show()
self.set_window(window, top.get_object('title'),
_('Potential Merges'))
+2 -1
View File
@@ -3,7 +3,7 @@
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkDialog" id="relcalc">
<property name="visible">True</property>
<property name="visible">False</property>
<property name="can_focus">False</property>
<property name="default_width">600</property>
<property name="default_height">400</property>
@@ -91,6 +91,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">in</property>
<property name="min_content_height">75</property>
<child>
<object class="GtkTextView" id="text1">
<property name="height_request">75</property>
+6 -6
View File
@@ -98,7 +98,7 @@
<property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="halign">3</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
</object>
<packing>
@@ -116,7 +116,7 @@
<property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="halign">3</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
</object>
<packing>
@@ -134,7 +134,7 @@
<property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="halign">3</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
</object>
<packing>
@@ -152,7 +152,7 @@
<property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="halign">3</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
</object>
<packing>
@@ -170,7 +170,7 @@
<property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="halign">3</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
</object>
<packing>
@@ -188,7 +188,7 @@
<property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="halign">3</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
</object>
<packing>
+5 -4
View File
@@ -130,15 +130,15 @@ class TestcaseGenerator(tool.BatchTool):
def __init__(self, dbstate, user, options_class, name, callback=None):
uistate = user.uistate
if uistate:
parent_window = uistate.window
self.parent_window = uistate.window
else:
parent_window = None
self.parent_window = None
self.person = None
if dbstate.db.readonly:
return
tool.BatchTool.__init__(self, dbstate, user, options_class, name,
parent=parent_window)
parent=self.parent_window)
if self.fail:
return
@@ -284,7 +284,8 @@ class TestcaseGenerator(tool.BatchTool):
while Gtk.events_pending():
Gtk.main_iteration()
self.progress = ProgressMeter(_('Generating testcases'),'', parent=self.window)
self.progress = ProgressMeter(_('Generating testcases'),'',
parent=self.parent_window)
self.transaction_count = 0;
if self.options.handler.options_dict['lowlevel']:
+2 -2
View File
@@ -310,7 +310,7 @@ class Verify(tool.Tool, ManagedWindow, UpdateCallback):
self.top.get_object(option).set_value(
self.options.handler.options_dict[option]
)
self.window.show()
self.show()
def build_menu_names(self, obj):
return (_("Tool settings"),self.label)
@@ -539,7 +539,7 @@ class VerifyResults(ManagedWindow):
name_column.set_sort_column_id(VerifyResults.OBJ_NAME_COL)
self.warn_tree.append_column(name_column)
self.window.show()
self.show()
self.window_shown = False
def __dummy(self, obj):
+1 -3
View File
@@ -535,9 +535,7 @@ class GeoClose(GeoGraphyView):
event, lat, lon, prevmark)
itemoption.append(center)
menu.show()
menu.popup(None, None,
lambda menu, data: (event.get_root_coords()[0],
event.get_root_coords()[1], True),
menu.popup(None, None, None,
None, event.button, event.time)
return 0
+1 -3
View File
@@ -369,9 +369,7 @@ class GeoEvents(GeoGraphyView):
bookm.show()
bookm.connect("activate", self.add_bookmark_from_popup, hdle)
itemoption.append(bookm)
menu.popup(None, None,
lambda menu, data: (event.get_root_coords()[0],
event.get_root_coords()[1], True),
menu.popup(None, None, None,
None, event.button, event.time)
return 1
+1 -3
View File
@@ -678,9 +678,7 @@ class GeoFamClose(GeoGraphyView):
event, lat, lon, prevmark)
itemoption.append(center)
menu.show()
menu.popup(None, None,
lambda menu, data: (event.get_root_coords()[0],
event.get_root_coords()[1], True),
menu.popup(None, None, None,
None, event.button, event.time)
return 0
+1 -3
View File
@@ -446,9 +446,7 @@ class GeoFamily(GeoGraphyView):
add_item.show()
menu.append(add_item)
self.add_event_bubble_message(event, lat, lon, prevmark, add_item)
menu.popup(None, None,
lambda menu, data: (event.get_root_coords()[0],
event.get_root_coords()[1], True),
menu.popup(None, None, None,
None, event.button, event.time)
return 1
+1 -3
View File
@@ -610,9 +610,7 @@ class GeoMoves(GeoGraphyView):
bookm.connect("activate", self.add_bookmark_from_popup, hdle)
itemoption.append(bookm)
menu.show()
menu.popup(None, None,
lambda menu, data: (event.get_root_coords()[0],
event.get_root_coords()[1], True),
menu.popup(None, None, None,
None, event.button, event.time)
return 1
+1 -3
View File
@@ -484,9 +484,7 @@ class GeoPerson(GeoGraphyView):
center.connect("activate", self.center_here, event, lat, lon, prevmark)
itemoption.append(center)
menu.show()
menu.popup(None, None,
lambda menu, data: (event.get_root_coords()[0],
event.get_root_coords()[1], True),
menu.popup(None, None, None,
None, event.button, event.time)
return 1
+1 -3
View File
@@ -359,9 +359,7 @@ class GeoPlaces(GeoGraphyView):
bookm.show()
bookm.connect("activate", self.add_bookmark_from_popup, hdle)
itemoption.append(bookm)
menu.popup(None, None,
lambda menu, data: (event.get_root_coords()[0],
event.get_root_coords()[1], True),
menu.popup(None, None, None,
None, event.button, event.time)
return 1
+1 -8
View File
@@ -181,16 +181,9 @@ class MediaView(ListView):
"""
if not sel_data:
return
#modern file managers provide URI_LIST. For Windows split sel_data.data
files = sel_data.get_uris()
for file in files:
if win():
clean_string = conv_to_unicode(
file.replace('\0',' ').replace("\r", " ").strip(),
None)
else:
clean_string = file
protocol, site, mfile, j, k, l = urlparse(clean_string)
protocol, site, mfile, j, k, l = urlparse(file)
if protocol == "file":
name = url2pathname(mfile)
mime = get_type(name)
+1 -1
View File
@@ -987,7 +987,7 @@ class PedigreeView(NavigationView):
rela = lst[2*i+1][1]
line = LineWidget2(1, rela, self.tree_direction)
if lst[i] and lst[i][2]:
if lst[((i+1) // 2) - 1] and lst[((i+1) // 2) - 1][2]:
# Required for popup menu
line.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
line.connect("button-press-event",
+9 -9
View File
@@ -517,8 +517,8 @@ def format_date(date):
cal = date.get_calendar()
mod = date.get_modifier()
quality = date.get_quality()
if quality in libgedcom.DATE_QUALITY:
qual_text = libgedcom.DATE_QUALITY[quality] + " "
if quality in DATE_QUALITY:
qual_text = DATE_QUALITY[quality] + " "
else:
qual_text = ""
if mod == Date.MOD_SPAN:
@@ -5052,14 +5052,14 @@ class DownloadPage(BasePage):
else:
tcell += "&nbsp;"
# clear line for proper styling
# create footer section
footer = self.write_footer()
body += (fullclear, footer)
# clear line for proper styling
# create footer section
footer = self.write_footer()
body += (fullclear, footer)
# send page out for processing
# and close the file
self.XHTMLWriter(downloadpage, of, sio)
# send page out for processing
# and close the file
self.XHTMLWriter(downloadpage, of, sio)
class ContactPage(BasePage):
def __init__(self, report, title):
+1 -1
View File
@@ -18,6 +18,6 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
VERSION_TUPLE = (4, 1, 3)
VERSION_TUPLE = (4, 1, 4)
VERSION = '.'.join(map(str,VERSION_TUPLE))
major_version = "%s.%s" % (VERSION_TUPLE[0], VERSION_TUPLE[1])
+3 -3
View File
@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>Gramps</string>
<key>CFBundleGetInfoString</key>
<string>4.1.2, (C) 1997-2015 The Gramps Team http://www.gramps-project.org</string>
<string>4.1.3, (C) 1997-2015 The Gramps Team http://www.gramps-project.org</string>
<key>CFBundleIconFile</key>
<string>gramps.icns</string>
<key>CFBundleIdentifier</key>
@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>4.1.2-1</string>
<string>4.1.3-1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>4.1.2-1</string>
<string>4.1.3-1</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright 1997 - 2015 The Gramps Team, GNU General Public License.</string>
<key>LSMinimumSystemVersion</key>
+1 -1
View File
@@ -58,7 +58,7 @@ gtk-mac-bundler gtk-osx-build/projects/gramps/gramps.bundle
<!--include href="/Users/john/Development/GTK-OSX/gtk-osx-build/modulesets-stable/gtk-osx.modules"/-->
<distutils id="gramps" autogen-sh="configure">
<branch module="gramps/gramps-4.1.2.tar.gz" version="4.1.2"
<branch module="gramps/gramps-4.1.3.tar.gz" version="4.1.3"
repo="sourceforge">
</branch>
<dependencies>
+1769 -974
View File
File diff suppressed because it is too large Load Diff
+398 -390
View File
File diff suppressed because it is too large Load Diff
+3364 -4135
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -5641,7 +5641,7 @@ msgstr ", "
#: ../gramps/gen/lib/date.py:424
msgid "{number_of} month"
msgid_plural "{number_of} months"
msgstr[0] "{number_of} moi"
msgstr[0] "{number_of} mois"
msgstr[1] "{number_of} mois"
# trunk
@@ -10713,7 +10713,7 @@ msgstr "Parrain"
# trunk
#: ../gramps/gui/editors/displaytabs/placerefembedlist.py:68
msgid "Enclosed By"
msgstr "Lié à"
msgstr "Fait partie de"
#: ../gramps/gui/editors/displaytabs/placerefembedlist.py:137
msgid "Place cycle detected"
+7786 -11470
View File
File diff suppressed because it is too large Load Diff