Compare commits

..
59 Commits
Author SHA1 Message Date
Stéphane Charette 3b5508d997 update for 3.2.5 release
svn: r16200
2010-11-18 06:54:44 +00:00
Jérôme Rapinat 77455f2776 4185: update strings for kinship report (contribution by Robert Jerome)
svn: r16194
2010-11-15 10:33:04 +00:00
Jérôme Rapinat 5ca248aa14 update slovak translation (by Lubo Vasko)
svn: r16190
2010-11-14 10:47:24 +00:00
Jérôme Rapinat d1b9344373 4089: Month names for Russian (contribution)
svn: r16188
2010-11-13 21:27:48 +00:00
Jérôme Rapinat 081c300b75 update polish translation (by Łukasz Rymarczyk)
svn: r16184
2010-11-12 10:45:03 +00:00
Peter Landgren 35d494f49e Fix of issue 4369, parameter msg not always a string object.
svn: r16181
2010-11-11 16:56:56 +00:00
Jérôme Rapinat 658284d692 typo
svn: r16175
2010-11-11 11:58:07 +00:00
Erik De Richter 900edf379c updated nl translation
svn: r16173
2010-11-10 22:28:56 +00:00
Nick Hall 4ceee5b350 4366: Fix bug with event type of Unknown
svn: r16171
2010-11-10 17:02:21 +00:00
Mirko Leonhäuser 3154bbaa50 updated german translation
svn: r16168
2010-11-09 20:18:28 +00:00
Jérôme Rapinat e3147bc8a5 syntax error '''\n' breaks compilation
svn: r16159
2010-11-08 13:44:41 +00:00
Jérôme Rapinat 9fcf2bf560 typo on Norwegian Nynorsk; update french translation
svn: r16158
2010-11-08 10:51:12 +00:00
Peter Landgren 626e1ec24d swedish translation update.
svn: r16157
2010-11-07 21:24:35 +00:00
Espen Berg 9bc9cf6a47 Sigmund Lorentsen revised Norwegian Nynorsk to 100%
svn: r16156
2010-11-07 18:44:06 +00:00
Mirko Leonhäuser 94efebf36c translation of proceed i have taken a backup was to long
svn: r16153
2010-11-07 01:54:38 +00:00
Mirko Leonhäuser f91eb31d88 updated german translation
svn: r16152
2010-11-07 01:41:24 +00:00
Nick Hall 03d5e3f4bc 4354: Bug fix in unused methods
svn: r16151
2010-11-06 16:03:09 +00:00
Jérôme Rapinat 5bc355ad0c update template
svn: r16150
2010-11-06 10:15:58 +00:00
Espen Berg 47ff14af65 Revised Norwegian bokmål to 100% due to the last few new strings
svn: r16149
2010-11-06 09:39:39 +00:00
Benny Malengier 60a4ce9f4a 4301: Got a database error
svn: r16148
2010-11-06 08:32:30 +00:00
Erik De Richter 959693bc84 updated nl translation
svn: r16144
2010-11-05 19:53:23 +00:00
Jérôme Rapinat 395e46aaab 4301: extra questiondialog on db manager
svn: r16142
2010-11-05 09:30:49 +00:00
Benny Malengier c0b534fe1d 4301: Got a database error
svn: r16134
2010-11-04 19:43:07 +00:00
Erik De Richter bdd3a553c0 updated nl translation
svn: r16133
2010-11-04 19:17:36 +00:00
Espen Berg 3418ac3bd2 Revised Norwegian bokmål translation
svn: r16123
2010-11-03 13:15:18 +00:00
Benny Malengier aff06c9b49 4343: Error message at close of address entry
svn: r16120
2010-11-02 20:04:40 +00:00
Benny Malengier bf7182ed8f 4341: Error when adding a new place
svn: r16118
2010-11-02 18:57:06 +00:00
Jérôme Rapinat dc5cfb7f91 2 errors on plural forms, clean-up
svn: r16115
2010-11-02 18:40:46 +00:00
Benny Malengier ea9df739a4 4340: Error when adding source reference
svn: r16110
2010-11-02 13:19:13 +00:00
Benny Malengier e6f6d5d00c 4340: Error when adding source reference
svn: r16109
2010-11-02 13:12:27 +00:00
Benny Malengier 77d3cf1967 4333: memory leak in 3.2
svn: r16104
2010-11-01 20:48:23 +00:00
Benny Malengier e80a74d72a 4333: memory leak in 3.2
svn: r16093
2010-10-31 08:55:42 +00:00
Benny Malengier 1baf7070a3 4333: memory leak in 3.2
svn: r16092
2010-10-31 08:38:05 +00:00
Benny Malengier f1e2d15ebb 4325: Error with 'More Name Details' if window is already opened
svn: r16072
2010-10-28 17:58:47 +00:00
Jérôme Rapinat a8ab3b5f4e #2644: Do not export individual events without primary role
svn: r16031
2010-10-24 07:20:15 +00:00
Peter Landgren 403bea5f2c Issue 4308, missed one parameter when calling Narrator.
svn: r16024
2010-10-22 17:27:41 +00:00
Benny Malengier ca3dba5dd9 4288: Preformatted blocks broken in web report
svn: r16015
2010-10-19 18:30:28 +00:00
Benny Malengier 3f87bdec6e 4292: Error in RTF output
svn: r16012
2010-10-19 15:37:28 +00:00
Jérôme Rapinat 848114ea4e #4264 properly import role and type on family (.gw file)
svn: r16005
2010-10-16 09:12:47 +00:00
Jérôme Rapinat ef37b3c6a6 typo
svn: r16004
2010-10-16 08:50:14 +00:00
Rob G. Healey 0fe26ef415 NarrativeWeb: Part of Bug#4287: Source References's hyperlink in now fixed.
svn: r16003
2010-10-16 08:35:26 +00:00
Rob G. Healey 2f9341dcb8 NarrativeWeb: Part of bug#4287: Description for the individual gallery is now escape so that for one the ampersand is taken care of.
svn: r16001
2010-10-16 08:03:13 +00:00
Rob G. Healey 77f96037fa libhtml: Part of Bug#4287 Adds PUBLIC to all of the DOCTYPE header of the first line in all web documents. Thanks Gerald Britton for the patch file.
svn: r16000
2010-10-16 07:47:05 +00:00
Peter Landgren 1cb6f2f3c8 Issue 4293, problems with LagecyGedcom and empty events.
svn: r15996
2010-10-15 17:55:14 +00:00
Jérôme Rapinat 43fa619ebc #4264: import ignores marriage and divorce dates (.gw file)
svn: r15994
2010-10-15 17:43:43 +00:00
Jérôme Rapinat db4e0aafb8 Update french translation, new template for matching usage argument (cli)
svn: r15989
2010-10-15 16:48:30 +00:00
Peter Landgren 09e9872206 Update #2 (took wrong version) with translation of the cli command --usage.
svn: r15986
2010-10-14 12:25:26 +00:00
Peter Landgren 796b778bf0 Update with translation of the cli command --usage.
svn: r15985
2010-10-14 12:16:42 +00:00
Peter Landgren 174886e40a Issue 4274, Gramps cli commands for user with non latin characters in names. Mostly Windows.
svn: r15983
2010-10-14 11:31:15 +00:00
Rob G. Healey dd1f244d24 Style Sheets: Added comment line to remove the description under the thumbnails in Individual Gallery. Search for line that is: #indivgallery div.thumbnail p, and follow the directions there.
svn: r15982
2010-10-14 00:45:20 +00:00
Doug Blank 0f7623be22 4236: All notes and sources ALWAYS written to GEDCOM file even when no notes are suppose to be written
svn: r15979
2010-10-13 10:56:58 +00:00
Doug Blank 1a27f856c5 typo in comment
svn: r15977
2010-10-13 10:49:07 +00:00
Peter Landgren d3993f57ff Issue 4291, wrong path when cancel.
svn: r15975
2010-10-13 08:45:23 +00:00
Mirko Leonhäuser af788956aa updated german translation
svn: r15974
2010-10-12 18:42:29 +00:00
Jérôme Rapinat 96efc4ee45 Add Relationships handler for Slovenian (by Bernard Banko)
svn: r15973
2010-10-12 06:49:30 +00:00
Jérôme Rapinat 359192efb0 Add Date handler for Slovenian (by Bernard Banko)
svn: r15972
2010-10-12 06:44:58 +00:00
Peter Landgren 8e841be786 Revert so that it will work with python 2.5 for branch32.
svn: r15971
2010-10-12 06:09:35 +00:00
Benny Malengier 9d207fd48f add missing css file to distribution
svn: r15969
2010-10-11 11:49:04 +00:00
Stéphane Charette 924acb11ff bump version strings to 3.2.5
svn: r15966
2010-10-10 23:34:07 +00:00
93 changed files with 20679 additions and 16153 deletions
+10
View File
@@ -1,3 +1,13 @@
Version 3.2.5 -- the "I intend to live forever" bug fix release.
* fix Gramps so it again runs with Python 2.5
* write all notes and sources to gedcom files
* cli fixes
* GeneWeb and LegacyGedcom fixes
* NarrativeWeb fixes
* memory leak fixes
* various other small fixes
* many translation updates
Version 3.2.4 -- the "Tententen" bug fix release.
* fix a crash on newer distro's after an export is finished
* styled notes cleanup and consistency improvement (nar web behaves like the pdf/html output of reports)
+1 -1
View File
@@ -5,7 +5,7 @@ dnl May need to run automake && aclocal first
AC_PREREQ(2.57)
dnl NOTE: arg to macro below becomes the "VERSION"
AC_INIT(gramps, 3.2.4, [gramps-bugs@lists.sourceforge.net])
AC_INIT(gramps, 3.2.5, [gramps-bugs@lists.sourceforge.net])
AC_CONFIG_SRCDIR(configure.in)
AM_INIT_AUTOMAKE([1.6.3 foreign])
+1463 -1257
View File
File diff suppressed because it is too large Load Diff
+985 -844
View File
File diff suppressed because it is too large Load Diff
+663 -548
View File
File diff suppressed because it is too large Load Diff
+4333 -1867
View File
File diff suppressed because it is too large Load Diff
+996 -855
View File
File diff suppressed because it is too large Load Diff
+949 -1032
View File
File diff suppressed because it is too large Load Diff
+3682 -1333
View File
File diff suppressed because it is too large Load Diff
+3318 -3596
View File
File diff suppressed because it is too large Load Diff
+1905 -3924
View File
File diff suppressed because it is too large Load Diff
+796 -591
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -22,6 +22,7 @@ pkgdata_PYTHON = \
_Date_pt.py\
_Date_ru.py\
_Date_sk.py\
_Date_sl.py\
_Date_sr.py\
_Date_sv.py\
_DateDisplay.py\
+56 -57
View File
@@ -187,13 +187,12 @@ class DateDisplayRU(DateDisplay):
"""
Russian language date display class.
"""
# TODO: Translate these month strings:
long_months = ( u"", u"January", u"February", u"March", u"April", u"May",
u"June", u"July", u"August", u"September", u"October",
u"November", u"December" )
long_months = ( u"", u"января", u"февраля", u"марта", u"апреля", u"мая",
u"июня", u"июля", u"августа", u"сентября", u"октября",
u"ноября", u"декабря" )
short_months = ( u"", u"Jan", u"Feb", u"Mar", u"Apr", u"May", u"Jun",
u"Jul", u"Aug", u"Sep", u"Oct", u"Nov", u"Dec" )
short_months = ( u"", u"янв", u"фев", u"мар", u"апр", u"мая", u"июн",
u"июл", u"авг", u"сен", u"окт", u"ноя", u"дек" )
calendar = (
u"",
@@ -202,7 +201,7 @@ class DateDisplayRU(DateDisplay):
u"республиканский",
u"персидский",
u"исламский",
u"Swedish"
u"шведский"
)
_mod_str = (
@@ -222,65 +221,65 @@ class DateDisplayRU(DateDisplay):
)
hebrew = ( u"",
u"Тишрей",
u"Хешван",
u"Кислев",
u"Тевет",
u"Шеват",
u"Адар",
u"Адар бет",
u"Нисан",
u"Ияр",
u"Сиван",
u"Таммуз",
u"Ав",
u"Элул",
u"тишрея",
u"хешвана",
u"кислева",
u"тевета",
u"шевата",
u"адара",
u"адар бета",
u"нисана",
u"ияра",
u"сивана",
u"таммуза",
u"ава",
u"элула",
)
islamic = ( u"",
u"Мухаррам",
u"Сафар",
u"Раби-аль-авваль",
u"Раби-ассани",
u"Джумада-аль-уля",
u"Джумада-аль-ахира",
u"Раджаб",
u"Шаабан",
u"Рамадан",
u"Шавваль",
u"Зуль-каада",
u"Зуль-хиджжа",
u"мухаррама",
u"сафара",
u"раби-аль-авваля",
u"раби-ассани",
u"джумада-аль-уля",
u"джумада-аль-ахира",
u"раджаба",
u"шаабана",
u"рамадана",
u"шаввальа",
u"зуль-каада",
u"зуль-хиджжа",
)
persian = ( u"",
u"Фарвардин",
u"Урдбихишт",
u"Хурдад",
u"Тир",
u"Мурдад",
u"Шахривар",
u"Михр",
u"Абан",
u"Азар",
u"Дай",
u"Бахман",
u"Исфаидармуз",
u"фарвардина",
u"урдбихишта",
u"хурдада",
u"тира",
u"мурдада",
u"шахривара",
u"михра",
u"абана",
u"азара",
u"дайа",
u"бахмана",
u"исфаидармуза",
)
french = ( u"",
u"Вандемьер",
u"Брюмер",
u"Фример",
u"Нивоз",
u"Плювиоз",
u"Вантоз",
u"Жерминаль",
u"Флореаль",
u"Прериаль",
u"Мессидор",
u"Термидор",
u"Фрюктидор",
u"Дополнит."
u"вандемьера",
u"брюмера",
u"фримера",
u"нивоза",
u"плювиоза",
u"вантоза",
u"жерминаля",
u"флореаля",
u"прериаля",
u"мессидора",
u"термидора",
u"фрюктидора",
u"дополнит."
)
def display(self, date):
+313
View File
@@ -0,0 +1,313 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2004-2007 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Slovenian version 2010 by Bernard Banko, based on croatian one by Josip
"""
Slovenian-specific classes for parsing and displaying dates.
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import re
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gen.lib import Date
from _DateParser import DateParser
from _DateDisplay import DateDisplay
from _DateHandler import register_datehandler
#-------------------------------------------------------------------------
#
# Slovenian parser
#
#-------------------------------------------------------------------------
class DateParserSL(DateParser):
"""
Converts a text string into a Date object
"""
month_to_int = DateParser.month_to_int
month_to_int[u"januar"] = 1
month_to_int[u"januarja"] = 1
month_to_int[u"januarjem"] = 1
month_to_int[u"jan"] = 1
month_to_int[u"i"] = 1
month_to_int[u"februar"] = 2
month_to_int[u"februarjem"] = 2
month_to_int[u"februarja"] = 2
month_to_int[u"feb"] = 2
month_to_int[u"ii"] = 2
month_to_int[u"mar"] = 3
month_to_int[u"marcem"] = 3
month_to_int[u"marec"] = 3
month_to_int[u"marca"] = 3
month_to_int[u"iii"] = 3
month_to_int[u"apr"] = 4
month_to_int[u"april"] = 4
month_to_int[u"aprilom"] = 4
month_to_int[u"aprila"] = 4
month_to_int[u"iv"] = 4
month_to_int[u"maj"] = 5
month_to_int[u"maja"] = 5
month_to_int[u"majem"] = 5
month_to_int[u"v"] = 5
month_to_int[u"jun"] = 6
month_to_int[u"junij"] = 6
month_to_int[u"junijem"] = 6
month_to_int[u"junija"] = 6
month_to_int[u"vi"] = 6
month_to_int[u"jul"] = 7
month_to_int[u"julij"] = 7
month_to_int[u"julijem"] = 7
month_to_int[u"julija"] = 7
month_to_int[u"vii"] = 7
month_to_int[u"avg"] = 8
month_to_int[u"avgust"] = 8
month_to_int[u"avgustom"] = 8
month_to_int[u"avgusta"] = 8
month_to_int[u"viii"] = 8
month_to_int[u"sep"] = 9
month_to_int[u"sept"] = 9
month_to_int[u"september"] = 9
month_to_int[u"septembrom"] = 9
month_to_int[u"septembra"] = 9
month_to_int[u"ix"] = 9
month_to_int[u"okt"] = 10
month_to_int[u"oktober"] = 10
month_to_int[u"oktobrom"] = 10
month_to_int[u"oktobra"] = 10
month_to_int[u"x"] = 10
month_to_int[u"nov"] = 11
month_to_int[u"november"] = 11
month_to_int[u"novembrom"] = 11
month_to_int[u"novembra"] = 11
month_to_int[u"xi"] = 11
month_to_int[u"dec"] = 12
month_to_int[u"december"] = 12
month_to_int[u"decembrom"] = 12
month_to_int[u"decembra"] = 12
month_to_int[u"xii"] = 12
modifier_to_int = {
u'pred' : Date.MOD_BEFORE,
u'pr.' : Date.MOD_BEFORE,
u'po' : Date.MOD_AFTER,
u'okoli' : Date.MOD_ABOUT,
u'okrog' : Date.MOD_ABOUT,
u'okr.' : Date.MOD_ABOUT,
u'ok.' : Date.MOD_ABOUT,
u'cca.' : Date.MOD_ABOUT,
u'cca' : Date.MOD_ABOUT,
u'circa' : Date.MOD_ABOUT,
u'ca.' : Date.MOD_ABOUT,
}
calendar_to_int = {
u'gregorijanski' : Date.CAL_GREGORIAN,
u'greg.' : Date.CAL_GREGORIAN,
u'julijanski' : Date.CAL_JULIAN,
u'jul.' : Date.CAL_JULIAN,
u'hebrejski' : Date.CAL_HEBREW,
u'hebr.' : Date.CAL_HEBREW,
u'islamski' : Date.CAL_ISLAMIC,
u'isl.' : Date.CAL_ISLAMIC,
u'francoski republikanski': Date.CAL_FRENCH,
u'franc.' : Date.CAL_FRENCH,
u'perzijski' : Date.CAL_PERSIAN,
u'perz. ' : Date.CAL_PERSIAN,
u'švedski' : Date.CAL_SWEDISH,
u'šved.' : Date.CAL_SWEDISH,
}
quality_to_int = {
u'približno' : Date.QUAL_ESTIMATED,
u'pribl.' : Date.QUAL_ESTIMATED,
u'izračunano' : Date.QUAL_CALCULATED,
u'izrač.' : Date.QUAL_CALCULATED,
}
bce = ["pred našim štetjem", "pred Kristusom",
"p.n.š.", "p. n. š.", "pr.Kr.", "pr. Kr."] + DateParser.bce
def init_strings(self):
"""
compiles regular expression strings for matching dates
"""
DateParser.init_strings(self)
# match 'Day. MONTH year.' format with or without dots
self._text2 = re.compile('(\d+)?\.?\s*?%s\.?\s*((\d+)(/\d+)?)?\s*\.?$'
% self._mon_str, re.IGNORECASE)
# match Day.Month.Year.
self._numeric = re.compile("((\d+)[/\.-])?\s*((\d+)[/\.-])?\s*(\d+)\.?$")
self._span = re.compile("od\s+(?P<start>.+)\s+do\s+(?P<stop>.+)",
re.IGNORECASE)
self._range = re.compile(
u"med\s+(?P<start>.+)\s+in\s+(?P<stop>.+)",
re.IGNORECASE)
self._jtext2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?'\
% self._jmon_str, re.IGNORECASE)
#-------------------------------------------------------------------------
#
# Slovenian display
#
#-------------------------------------------------------------------------
class DateDisplaySL(DateDisplay):
"""
Slovenian language date display class.
"""
long_months = ( u"", u"januarja", u"februarja", u"marca",u"aprila",
u"maja", u"junija", u"julija", u"avgusta", u"septembra",
u"oktobra", u"novembra", u"decembra"
)
short_months = ( u"", u"jan", u"feb", u"mar", u"apr", u"maj", u"jun",
u"jul", u"avg", u"sep", u"okt", u"nov", u"dec"
)
calendar = (
"", u"julijanski", u"hebrejski",
u"francoski republikanski", u"perzijski", u"islamski",
u"švedski"
)
_mod_str = ("", "pred ", "po ", "okrog ", "", "", "")
_qual_str = ("", "približno ", "izračunano ")
_bce_str = "%s p.n.š."
formats = (
"ISO (leto-mm-dd)",
"številčno",
"dan. mes. leto",
"dan. mesec leto"
)
def _display_gregorian(self, date_val):
"""
display gregorian calendar date in different format
"""
year = self._slash_year(date_val[2], date_val[3])
if self.format == 0:
return self.display_iso(date_val)
elif self.format == 1:
# D. M. YYYY
if date_val[3]:
return self.display_iso(date_val)
else:
if date_val[0] == 0 and date_val[1] == 0:
value = str(date_val[2])
else:
value = self._tformat.replace('%m', str(date_val[1]))
value = value.replace('%d', str(date_val[0]))
value = value.replace('%Y', str(date_val[2]))
value = value.replace('-', '. ')
elif self.format == 2:
# D. mon. YYYY
if date_val[0] == 0:
if date_val[1] == 0:
value = year
else:
value = "%s. %s" % (self.short_months[date_val[1]], year)
else:
value = "%d. %s. %s" % (date_val[0],
self.short_months[date_val[1]], year)
else:
# D. month YYYY
if date_val[0] == 0:
if date_val[1] == 0:
value = "%s." % year
else:
value = "%s %s" % (self.long_months[date_val[1]], year)
else:
value = "%d. %s %s" % (
date_val[0],self.long_months[date_val[1]], year)
if date_val[2] < 0:
return self._bce_str % value
else:
return value
def display(self, date):
"""
Return a text string representing the date.
"""
mod = date.get_modifier()
cal = date.get_calendar()
qual = date.get_quality()
start = date.get_start_date()
newyear = date.get_new_year()
qual_str = self._qual_str[qual]
if mod == Date.MOD_TEXTONLY:
return date.get_text()
elif start == Date.EMPTY:
return u""
elif mod == Date.MOD_SPAN:
d_1 = self.display_cal[cal](start)
d_2 = self.display_cal[cal](date.get_stop_date())
scal = self.format_extras(cal, newyear)
return u"%sod %s do %s%s" % (qual_str, d_1, d_2, scal)
elif mod == Date.MOD_RANGE:
d_1 = self.display_cal[cal](start)
d_2 = self.display_cal[cal](date.get_stop_date())
scal = self.format_extras(cal, newyear)
date_string = u"%smed %s in %s%s" % (qual_str, d_1, d_2, scal)
date_string = date_string.replace(u"a ",u"em ") #to correct declination
date_string = date_string.replace(u"lem ",u"lom ")
date_string = date_string.replace(u"rem ",u"rom ")
date_string = date_string.replace(u"tem ",u"tom ")
return date_string
else:
text = self.display_cal[date.get_calendar()](start)
scal = self.format_extras(cal, newyear)
date_string = "%s%s%s%s" % (qual_str, self._mod_str[mod], text, scal)
return date_string
#-------------------------------------------------------------------------
#
# Register classes
#
#-------------------------------------------------------------------------
register_datehandler(("sl", "SL", "sl_SI", "slovenščina", "slovenian", "Slovenian",
"sl_SI.UTF8", "sl_SI.UTF-8", "sl_SI.utf-8", "sl_SI.utf8"),
DateParserSL, DateDisplaySL)
+1
View File
@@ -45,6 +45,7 @@ import _Date_pl
import _Date_pt
import _Date_ru
import _Date_sk
import _Date_sl
import _Date_sr
import _Date_sv
+4 -2
View File
@@ -61,8 +61,10 @@ class GenericFilter(object):
return False
def is_empty(self):
return len(self.flist) == 0 or \
(len(self.flist) == 1 and self.flist[0].is_empty())
return (len(self.flist) == 0 or
(len(self.flist) == 1 and
((self.flist[0].is_empty() and not self.invert) or
(not self.flist[0].is_empty() and self.invert))))
def set_logical_op(self, val):
if val in GenericFilter.logical_functions:
+9 -1
View File
@@ -57,7 +57,15 @@ class SearchBar(object):
self.filter_model = gtk.ListStore(gobject.TYPE_STRING,
gobject.TYPE_INT,
gobject.TYPE_BOOLEAN)
def destroy(self):
"""Unset all things that can block garbage collection.
"""
self.on_apply_callback = None
self.apply_done_callback = None
self.dbstate = None
self.uistate = None
def build( self):
self.filterbar.set_spacing(4)
self.filter_list.connect('changed', self.filter_changed)
+3
View File
@@ -151,4 +151,7 @@ class LRU(object):
"""
Empties LRU
"""
for obj, node in self.data.iteritems():
node.prev = None
node.next = None
self.data.clear()
+2 -2
View File
@@ -187,7 +187,7 @@ class ErrorDialog(gtk.MessageDialog):
class RunDatabaseRepair(ErrorDialog):
def __init__(self, msg, parent=None):
msg = unicode(msg.decode(sys.getfilesystemencoding()))
msg = unicode(str(msg).decode(sys.getfilesystemencoding()))
ErrorDialog.__init__(
self,
_('Error detected in database'),
@@ -199,7 +199,7 @@ class RunDatabaseRepair(ErrorDialog):
class DBErrorDialog(ErrorDialog):
def __init__(self, msg, parent=None):
msg = unicode(msg.decode(sys.getfilesystemencoding()))
msg = unicode(str(msg).decode(sys.getfilesystemencoding()))
ErrorDialog.__init__(
self,
_("Low level database corruption detected"),
+10 -5
View File
@@ -371,21 +371,26 @@ class CommandLineReport(object):
opt = self.options_help[key]
# Make the output nicer to read, assume that tab has 8 spaces
tabs = '\t' if len(key) < 10 else '\t'*2
print " %s%s%s (%s)" % (key, tabs, opt[1], opt[0])
optmsg = " %s%s%s (%s)" % (key, tabs, opt[1], opt[0])
print optmsg.encode(sys.getfilesystemencoding())
else:
print " %s" % key
optmsg = " %s" % key
print optmsg.encode(sys.getfilesystemencoding())
print " Use 'show=option' to see description and acceptable values"
elif self.show in self.options_help:
opt = self.options_help[self.show]
tabs = '\t' if len(self.show) < 10 else '\t'*2
print ' %s%s%s%s' % (self.show, tabs, opt[0], opt[1])
optmsg = ' %s%s%s%s' % (self.show, tabs, opt[0], opt[1])
print optmsg.encode(sys.getfilesystemencoding())
print " Available values are:"
vals = opt[2]
if isinstance(vals, (list, tuple)):
for val in vals:
print " %s" % val
optmsg = " %s" % val
print optmsg.encode(sys.getfilesystemencoding())
else:
print " %s" % opt[2]
optmsg = " %s" % opt[2]
print optmsg.encode(sys.getfilesystemencoding())
else:
#there was a show option given, but the option is invalid
+6 -5
View File
@@ -333,12 +333,12 @@ def get_unicode_path_from_file_chooser(path):
:rtype: unicode
:returns: The Unicode version of path.
"""
# Don't make unicode of unicode
if isinstance(path, unicode):
# make omly unicode of path of type 'str'
if not (isinstance(path, str)):
return path
if constfunc.win():
# in windows filechooser returns officially utf-8, not filesystemencoding
# in windows filechooser returns officially utf-8, not filesystemencoding
try:
return unicode(path)
except:
@@ -360,7 +360,8 @@ def get_unicode_path_from_env_var(path):
:rtype: unicode
:returns: The Unicode version of path.
"""
if isinstance(path, unicode):
# make omly unicode of path of type 'str'
if not (isinstance(path, str)):
return path
if constfunc.win():
@@ -844,7 +845,7 @@ def probably_alive(person, db,
"""
Return true if the person may be alive on current_date.
This works by a process of emlimination. If we can't find a good
This works by a process of elimination. If we can't find a good
reason to believe that someone is dead then we assume they must
be alive.
+27 -10
View File
@@ -94,7 +94,9 @@ class ArgHandler(object):
if self.errorfunc:
self.errorfunc(string)
else:
print string
# Need to convert to str before printing
# For non latin characters in Windows path/file/user names
print string.encode(sys.getfilesystemencoding())
#-------------------------------------------------------------------------
# Argument parser: sorts out given arguments
@@ -115,8 +117,8 @@ class ArgHandler(object):
"""
if value is None:
return None
value = Utils.get_unicode_path_from_env_var(value)
db_path = self.__deduce_db_path(value)
if db_path:
# We have a potential database path.
# Check if it is good.
@@ -134,6 +136,9 @@ class ArgHandler(object):
Handle the "-i" or "--import" option.
Only Files supported by a plugin can be imported, so not Family Trees.
"""
# Need to convert path/filename to unicode before openingh
# For non latin characters in Windows path/file/user names
value = Utils.get_unicode_path_from_env_var(value)
fname = value
fullpath = os.path.abspath(os.path.expanduser(fname))
if not os.path.exists(fullpath):
@@ -168,6 +173,9 @@ class ArgHandler(object):
"""
if self.gui:
return
# Need to covert path/filename to unicode before openingh
# For non latin characters in Windows path/file/user names
value = Utils.get_unicode_path_from_env_var(value)
fname = value
fullpath = os.path.abspath(os.path.expanduser(fname))
if os.path.exists(fullpath):
@@ -176,8 +184,9 @@ class ArgHandler(object):
{'name' : fullpath})
answer = None
while not answer:
answer = raw_input(_('OK to overwrite? (yes/no) '))
if answer.upper() in ('Y', 'YES', _('YES')):
answer = raw_input(_('OK to overwrite? (yes/no) ') \
.encode(sys.getfilesystemencoding()))
if answer.upper() in ('Y', 'YES', _('YES').upper()):
self.__error( _("Will overwrite the existing file: %s")
% fullpath)
else:
@@ -310,7 +319,11 @@ class ArgHandler(object):
self.cl_action(action, options_str)
for expt in self.exports:
print "Exporting: file %s, format %s." % expt
# Need to convert path/filename to str before printing
# For non latin characters in Windows path/file/user names
fn = expt[0].encode(sys.getfilesystemencoding())
fmt = str(expt[1])
print "Exporting: file %s, format %s." % (fn, fmt)
self.cl_export(expt[0], expt[1])
if cleanup:
@@ -356,7 +369,11 @@ class ArgHandler(object):
sys.exit(0)
for imp in self.imports:
print "Importing: file %s, format %s." % imp
# Need to covert path/filename to str before printing
# For non latin characters in Windows path/file/user names
fn = imp[0].encode(sys.getfilesystemencoding())
fmt = str(imp[1])
print "Importing: file %s, format %s." % (fn , fmt)
self.cl_import(imp[0], imp[1])
def __open_action(self):
@@ -480,9 +497,9 @@ class ArgHandler(object):
if len(pdata.id) <= 25:
print " %s%s- %s" % ( pdata.id,
" " * (26 - len(pdata.id)),
pdata.name)
pdata.name.encode(sys.getfilesystemencoding()))
else:
print " %s\t- %s" % (pdata.id, pdata.name)
print " %s\t- %s" % (pdata.id, pdata.name.encode(sys.getfilesystemencoding()) )
elif action == "tool":
try:
@@ -517,9 +534,9 @@ class ArgHandler(object):
if len(pdata.id) <= 25:
print " %s%s- %s" % ( pdata.id,
" " * (26 - len(pdata.id)),
pdata.name)
pdata.name.encode(sys.getfilesystemencoding()))
else:
print " %s\t- %s" % (pdata.id, pdata.name)
print " %s\t- %s" % (pdata.id, pdata.name.encode(sys.getfilesystemencoding()))
else:
print "Unknown action: %s." % action
sys.exit(0)
+87 -5
View File
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
@@ -44,6 +45,7 @@ import logging
#
#-------------------------------------------------------------------------
import const
import Utils
# Note: Make sure to edit const.py POPT_TABLE too!
@@ -68,6 +70,51 @@ Application options
-u, --force-unlock Force unlock of family tree
""")
_USAGE = _("""
Example of usage of Gramps command line interface
1. To import four databases (whose formats can be determined from their names)
and then check the resulting database for errors, one may type:
gramps -i file1.ged -i file2.gpkg -i ~/db3.gramps -i file4.wft -a check
2. To explicitly specify the formats in the above example, append filenames with appropriate -f options:
gramps -i file1.ged -f gedcom -i file2.gpkg -f gramps-pkg -i ~/db3.gramps -f gramps-xml -i file4.wft -f wft -a check
3. To record the database resulting from all imports, supply -e flag
(use -f if the filename does not allow GRAMPS to guess the format):
gramps -i file1.ged -i file2.gpkg -e ~/new-package -f gramps-pkg
4. To save any error messages of the above example into files outfile and errfile, run:
gramps -i file1.ged -i file2.dpkg -e ~/new-package -f gramps-pkg >outfile 2>errfile
5. To import three databases and start interactive GRAMPS session with the result:
gramps -i file1.ged -i file2.gpkg -i ~/db3.gramps
6. To open a database and, based on that data, generate timeline report in PDF format
putting the output into the my_timeline.pdf file:
gramps -O 'Family Tree 1' -a report -p name=timeline,off=pdf,of=my_timeline.pdf
7. To generate a summary of a database:
gramps -O 'Family Tree 1' -a report -p name=summary
8. Listing report options
Use the name=timeline,show=all to find out about all available options for the timeline report.
To find out details of a particular option, use show=option_name , e.g. name=timeline,show=off string.
To learn about available report names, use name=show string.
9. To convert a family tree on the fly to a .gramps xml file:
gramps -O 'Family Tree 1' -e output.gramps -f gramps-xml
10. To generate a web site into an other locale (in german):
LANGUAGE=de_DE; LANG=de_DE.UTF-8 gramps -O 'Family Tree 1' -a report -p name=navwebpage,target=/../de
11. Finally, to start normal interactive session type:
gramps
Note: These examples are for bash shell.
Syntax may be different for other shells and for Windows.
""")
#-------------------------------------------------------------------------
# ArgParser
#-------------------------------------------------------------------------
@@ -121,6 +168,7 @@ class ArgParser(object):
self.list = False
self.list_more = False
self.help = False
self.usage = False
self.force_unlock = False
self.errors = []
@@ -150,14 +198,30 @@ class ArgParser(object):
"""
try:
# Convert arguments to unicode, otherwise getopt will not work
# if a non latin character is used as an option (by mistake).
# getopt will try to treat the first char in an utf-8 sequence. Example:
# -Ärik is '-\xc3\x84rik' and getopt will respond :
# option -\xc3 not recognized
for arg in range(len(self.args) - 1):
self.args[arg+1] = Utils.get_unicode_path_from_env_var(self.args[arg + 1])
options, leftargs = getopt.getopt(self.args[1:],
const.SHORTOPTS, const.LONGOPTS)
except getopt.GetoptError, msg:
# Extract the arguments in the list.
# The % operator replaces the list elements with repr() of the list elemements
# which is OK for latin characters, but not for non latin characters in list elements
cliargs = "[ "
for arg in range(len(self.args) - 1):
cliargs += self.args[arg + 1] + " "
cliargs += "]"
# Must first do str() of the msg object.
msg = unicode(str(msg))
self.errors += [(_('Error parsing the arguments'),
str(msg) + '\n' +
msg + '\n' +
_("Error parsing the arguments: %s \n"
"Type gramps --help for an overview of commands, or "
"read the manual pages.") % self.args[1:])]
"read the manual pages.") % cliargs)]
return
if leftargs:
@@ -214,7 +278,9 @@ class ArgParser(object):
self.help = True
elif option in ('-u', '--force-unlock'):
self.force_unlock = True
elif option in ('--usage'):
self.usage = True
#clean options list
cleandbg.reverse()
for ind in cleandbg:
@@ -222,10 +288,17 @@ class ArgParser(object):
if len(options) > 0 and self.open is None and self.imports == [] \
and not (self.list or self.list_more or self.help):
# Extract and convert to unicode the arguments in the list.
# The % operator replaces the list elements with repr() of the list elemements
# which is OK for latin characters, but not for non latin characters in list elements
cliargs = "[ "
for arg in range(len(self.args) - 1):
cliargs += Utils.get_unicode_path_from_env_var(self.args[arg + 1]) + " "
cliargs += "]"
self.errors += [(_('Error parsing the arguments'),
_("Error parsing the arguments: %s \n"
"To use in the command-line mode," \
"supply at least one input file to process.") % self.args[1:])]
"supply at least one input file to process.") % cliargs)]
#-------------------------------------------------------------------------
# Determine the need for GUI
@@ -262,6 +335,15 @@ class ArgParser(object):
If the user gives the --help or -h option, print the output to terminal.
"""
if self.help:
print _HELP
# Convert Help messages to file system encoding before printing
print _HELP.encode(sys.getfilesystemencoding())
sys.exit(0)
def print_usage(self):
"""
If the user gives the --usage print the output to terminal.
"""
if self.usage:
# Convert Help messages to file system encoding before printing
print _USAGE.encode(sys.getfilesystemencoding())
sys.exit(0)
+14 -4
View File
@@ -297,14 +297,24 @@ def startcli(errors, argparser):
"""
if errors:
#already errors encountered. Show first one on terminal and exit
print _('Error encountered: %s') % errors[0][0]
print _(' Details: %s') % errors[0][1]
# Convert error message to file system encoding before print
errmsg = _('Error encountered: %s') % errors[0][0]
errmsg = errmsg.encode(sys.getfilesystemencoding())
print errmsg
errmsg = _(' Details: %s') % errors[0][1]
errmsg = errmsg.encode(sys.getfilesystemencoding())
print errmsg
sys.exit(1)
if argparser.errors:
print _('Error encountered in argument parsing: %s') \
# Convert error message to file system encoding before print
errmsg = _('Error encountered in argument parsing: %s') \
% argparser.errors[0][0]
print _(' Details: %s') % argparser.errors[0][1]
errmsg = errmsg.encode(sys.getfilesystemencoding())
print errmsg
errmsg = _(' Details: %s') % argparser.errors[0][1]
errmsg = errmsg.encode(sys.getfilesystemencoding())
print errmsg
sys.exit(1)
#we need to keep track of the db state
+2 -2
View File
@@ -42,10 +42,10 @@ from gettext import gettext as _
#-------------------------------------------------------------------------
PROGRAM_NAME = "Gramps"
if "@VERSIONSTRING@" == "@" + "VERSIONSTRING" + "@":
VERSION = "3.2.4"
VERSION = "3.2.5"
else:
VERSION = "@VERSIONSTRING@"
VERSION_TUPLE = (3, 2, 4)
VERSION_TUPLE = (3, 2, 5)
#-------------------------------------------------------------------------
#
+1
View File
@@ -6,6 +6,7 @@ SUBDIRS =
pkgdatadir = $(datadir)/@PACKAGE@/data
dist_pkgdata_DATA = \
ancestortree.css \
authors.xml \
gedcom.xml \
papersize.xml \
+3
View File
@@ -826,6 +826,9 @@ div#addresses table.infolist tbody tr td.ColumnValue {
border:solid 1px #999;
}
#indivgallery div.thumbnail p {
/* ## remove this line and the comment markers from the line below to hide the description in Individual Gallery
display: none; */
font-size:.6em;
text-align:center;
width:80%;
+3
View File
@@ -1119,6 +1119,9 @@ div#Residence table.infolist tr td {
border: solid 1px #000;
}
#indivgallery div.thumbnail p {
/* ## remove this line and the comment markers from the line below to hide the description in Individual Gallery
display: none; */
font:normal .7em/1.4em sans-serif;
text-align:center;
width:80%;
+3
View File
@@ -823,6 +823,9 @@ div#addresses table.infolist tbody tr td.ColumnValue {
border:solid 1px #7C8F7C;
}
#indivgallery div.thumbnail p {
/* ## remove this line and the comment markers from the line below to hide the description in Individual Gallery
display: none; */
font-size:.6em;
text-align:center;
width:80%;
+3
View File
@@ -824,6 +824,9 @@ div#addresses table.infolist tbody tr td.ColumnValue {
border:solid 1px #669;
}
#indivgallery div.thumbnail p {
/* ## remove this line and the comment markers from the line below to hide the description in Individual Gallery
display: none; */
font-size:.6em;
text-align:center;
width:80%;
+3
View File
@@ -825,6 +825,9 @@ div#addresses table.infolist tbody tr td.ColumnValue {
border:solid 1px #8C581C;
}
#indivgallery div.thumbnail p {
/* ## remove this line and the comment markers from the line below to hide the description in Individual Gallery
display: none; */
font-size:.6em;
text-align:center;
width:80%;
+3
View File
@@ -825,6 +825,9 @@ div#addresses table.infolist tbody tr td.ColumnValue {
border:solid 1px #7CA3DD;
}
#indivgallery div.thumbnail p {
/* ## remove this line and the comment markers from the line below to hide the description in Individual Gallery
display: none; */
font-size:.6em;
text-align:center;
width:80%;
+3
View File
@@ -830,6 +830,9 @@ div#addresses table.infolist tbody tr td.ColumnValue {
border:solid 1px #7D5925;
}
#indivgallery div.thumbnail p {
/* ## remove this line and the comment markers from the line below to hide the description in Individual Gallery
display: none; */
font-size:.6em;
text-align:center;
width:80%;
+3
View File
@@ -846,6 +846,9 @@ div#addresses table.infolist tbody tr td.ColumnValue {
border:solid 1px #542;
}
#indivgallery div.thumbnail p {
/* ## remove this line and the comment markers from the line below to hide the description in Individual Gallery
display: none; */
font:normal .7em/1.4em sans-serif;
text-align:center;
width:80%;
+3
View File
@@ -951,6 +951,9 @@ div#addresses table.infolist tbody tr td.ColumnValue {
border:solid 1px #453619;
}
#indivgallery div.thumbnail p {
/* ## remove this line and the comment markers from the line below to hide the description in Individual Gallery
display: none; */
font:normal .7em/1.4em sans-serif;
text-align:center;
width:80%;
+21 -3
View File
@@ -92,6 +92,9 @@ class DbBookmarks(object):
def insert(self, pos, item):
self.bookmarks.insert(pos, item)
def close(self):
del self.bookmarks
#-------------------------------------------------------------------------
#
# GrampsDBReadCursor
@@ -169,7 +172,6 @@ class DbBsddbRead(DbReadBase, Callback):
"""
Create a new DbBsddbRead instance.
"""
DbReadBase.__init__(self)
Callback.__init__(self)
@@ -379,8 +381,24 @@ class DbBsddbRead(DbReadBase, Callback):
The method needs to be overridden in the derived class.
"""
pass
#remove links to functions
self.disconnect_all()
for key in self._tables:
for subkey in self._tables[key]:
self._tables[key][subkey] = None
del self._tables[key][subkey]
self._tables[key] = None
del self._tables
## self.bookmarks = None
## self.family_bookmarks = None
## self.event_bookmarks = None
## self.place_bookmarks = None
## self.source_bookmarks = None
## self.repo_bookmarks = None
## self.media_bookmarks = None
## self.note_bookmarks = None
def is_open(self):
"""
Return 1 if the database has been opened.
+4
View File
@@ -414,6 +414,10 @@ class DbUndoBSDDB(DbUndo):
Close the undo/redo database
"""
self.undodb.close()
self.undodb = None
self.mapbase = None
self.db = None
try:
os.remove(self.path)
except OSError:
+18 -1
View File
@@ -1000,7 +1000,6 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
def close(self):
if not self.db_is_open:
return
self.env.txn_checkpoint()
self.__close_metadata()
@@ -1045,6 +1044,24 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
self.env = None
self.metadata = None
self.db_is_open = False
DbBsddbRead.close(self)
self.person_map = None
self.family_map = None
self.repository_map = None
self.note_map = None
self.place_map = None
self.source_map = None
self.media_map = None
self.event_map = None
self.reference_map_primary_map = None
self.reference_map_referenced_map = None
self.reference_map = None
self.undo_callback = None
self.redo_callback = None
self.undo_history_callback = None
self.undodb = None
try:
clear_lock_file(self.get_save_path())
+5 -1
View File
@@ -41,6 +41,10 @@ def gettext(msgid):
:returns: Translation or the original.
:rtype: unicode
"""
# If msgid =="" then gettext will return po file header
# and that's not what we want.
if len(msgid.strip()) == 0:
return msgid
return unicode(pgettext.gettext(msgid))
def ngettext(singular, plural, n):
@@ -82,4 +86,4 @@ def sgettext(msgid, sep='|'):
if msgval == msgid:
sep_idx = msgid.rfind(sep)
msgval = msgid[sep_idx+1:]
return unicode(msgval)
return unicode(msgval)
+8 -8
View File
@@ -628,56 +628,56 @@ class ProxyDbBase(DbReadBase):
Returns True if the handle exists in the current Person database.
"""
return self.gfilter(self.include_person,
self.db.get_person_from_gramps_id(val)) is not None
self.db.get_person_from_handle(handle)) is not None
def has_family_handle(self, handle):
"""
Returns True if the handle exists in the current Family database.
"""
return self.gfilter(self.include_family,
self.db.get_family_from_gramps_id(val)) is not None
self.db.get_family_from_handle(handle)) is not None
def has_event_handle(self, handle):
"""
returns True if the handle exists in the current Event database.
"""
return self.gfilter(self.include_event,
self.db.get_event_from_gramps_id(val)) is not None
self.db.get_event_from_handle(handle)) is not None
def has_source_handle(self, handle):
"""
returns True if the handle exists in the current Source database.
"""
return self.gfilter(self.include_source,
self.db.get_source_from_gramps_id(val)) is not None
self.db.get_source_from_handle(handle)) is not None
def has_place_handle(self, handle):
"""
returns True if the handle exists in the current Place database.
"""
return self.gfilter(self.include_place,
self.db.get_place_from_gramps_id(val)) is not None
self.db.get_place_from_handle(handle)) is not None
def has_object_handle(self, handle):
"""
returns True if the handle exists in the current MediaObjectdatabase.
"""
return self.gfilter(self.include_media_object,
self.db.get_object_from_gramps_id(val)) is not None
self.db.get_object_from_handle(handle)) is not None
def has_repository_handle(self, handle):
"""
returns True if the handle exists in the current Repository database.
"""
return self.gfilter(self.include_repository,
self.db.get_repository_from_gramps_id(val)) is not None
self.db.get_repository_from_handle(handle)) is not None
def has_note_handle(self, handle):
"""
returns True if the handle exists in the current Note database.
"""
return self.gfilter(self.include_note,
self.db.get_note_from_gramps_id(val)) is not None
self.db.get_note_from_handle(handle)) is not None
def get_mediapath(self):
"""returns the default media path of the database"""
+11 -2
View File
@@ -40,6 +40,7 @@ import sys
import types
import traceback
import inspect
import copy
log = sys.stderr.write
@@ -311,8 +312,16 @@ class Callback(object):
": %s with key: %s\n" % (signal_name,
str(key)))
self.__callback_map[signal_name].remove(cb)
def disconnect_all(self):# Find the key in the callback map.
for signal_name in self.__callback_map:
keymap = copy.copy(self.__callback_map[signal_name])
for key in keymap:
self.__callback_map[signal_name].remove(key)
self.__callback_map[signal_name] = None
self.__callback_map = None
del self.__callback_map
def emit(self, signal_name, args=tuple()):
"""
Emit the signal called signal_name. The args must be a tuple of
+10 -6
View File
@@ -38,14 +38,18 @@ import ConfigParser
import errno
import copy
try:
from ast import literal_eval as safe_eval
except:
# PYTHON2.5 COMPATIBILITY: no ast present
# not as safe as literal_eval, but works for python2.5:
def safe_eval(exp):
def safe_eval(exp):
# restrict eval to empty environment
return eval(exp, {})
##try:
## from ast import literal_eval as safe_eval
## # this leaks memory !!
##except:
## # PYTHON2.5 COMPATIBILITY: no ast present
## # not as safe as literal_eval, but works for python2.5:
## def safe_eval(exp):
## # restrict eval to empty environment
## return eval(exp, {})
#---------------------------------------------------------------
#
+1
View File
@@ -181,6 +181,7 @@ def run():
else:
#CLI use of GRAMPS
argpars.print_help()
argpars.print_usage()
from cli.grampscli import startcli
startcli(error, argpars)
+2 -10
View File
@@ -86,14 +86,7 @@ class DbLoader(CLIDbLoader):
return 1
def _dberrordialog(self, msg):
import traceback
exc = traceback.format_exc()
try:
DBErrorDialog(str(msg.value))
_LOG.error(str(msg.value))
except:
DBErrorDialog(str(msg))
_LOG.error(str(msg) +"\n" + exc)
DBErrorDialog(str(msg.value))
def _begin_progress(self):
self.uistate.set_busy_cursor(1)
@@ -319,9 +312,8 @@ class DbLoader(CLIDbLoader):
except Errors.DbError, msg:
self.dbstate.no_database()
self._dberrordialog(msg)
except Exception as newerror:
except Exception:
self.dbstate.no_database()
self._dberrordialog(str(newerror))
self._end_progress()
return True
+31 -1
View File
@@ -68,7 +68,7 @@ import pango
# gramps modules
#
#-------------------------------------------------------------------------
from QuestionDialog import ErrorDialog, QuestionDialog
from QuestionDialog import ErrorDialog, QuestionDialog, QuestionDialog2
from gen.db import DbBsddb
from gui.pluginmanager import GuiPluginManager
from cli.clidbman import CLIDbManager, NAME_FILE, time_val
@@ -627,6 +627,36 @@ class DbManager(CLIDbManager):
"""
store, node = self.selection.get_selected()
dirname = store[node][1]
#First ask user if he is really sure :-)
yes_no = QuestionDialog2(
_("Repair family tree?"),
_(
"If you click <b>Proceed</b>, Gramps will attempt to recover your family tree"
" from the last good backup. There are several ways this can cause unwanted"
" effects, so <b>backup</b> the family tree first.\n"
"The Family tree you have selected is stored in %s.\n\n"
"Before doing a repair, verify that the Family Tree can really no longer be "
" opened, as the database back-end can recover from some errors automatically.\n\n"
"<b>Details:</b> Repairing a Family Tree actually uses the last backup of"
" the Family Tree, which Gramps stored on last use. If you have worked for"
" several hours/days without closing Gramps, then all this information will"
" be lost! If the repair fails, then the original family tree will be lost"
" forever, hence a backup is needed. If the repair fails, or too much"
" information is lost, you can fix the original family tree manually."
" For details, see the webpage\n"
"http://gramps-project.org/wiki/index.php?title=Recover_corrupted_family_tree\n"
"Before doing a repair, try to open the family tree in the normal manner."
" Several errors that trigger the repair button can be fixed automatically."
" If this is the case, you can disable the repair button by removing the"
" file <i>need_recover</i> in the family tree directory."
) % dirname,
_("Proceed, I have taken a backup"),
_("Stop"))
prompt = yes_no.run()
if not prompt:
return
opened = store[node][5]
if opened:
self.dbstate.no_database()
+8 -3
View File
@@ -66,7 +66,7 @@ class BackRefList(EmbeddedList):
EmbeddedList.__init__(self, dbstate, uistate, track,
_('_References'), refmodel)
self._callback = callback
self.model.connect('row-inserted', self.update_label)
self.connectid = self.model.connect('row-inserted', self.update_label)
self.track_ref_for_deletion("model")
def update_label(self, *obj):
@@ -78,8 +78,13 @@ class BackRefList(EmbeddedList):
def right_click(self, obj, event):
return
def close(self):
self.model.close()
def _cleanup_local_connects(self):
self.model.disconnect(self.connectid)
def _cleanup_on_exit(self):
# model may be destroyed already in closing managedwindow
if hasattr(self, 'model'):
self.model.destroy()
def is_empty(self):
return self.model.count == 0
+9 -1
View File
@@ -54,10 +54,18 @@ class BackRefModel(gtk.ListStore):
self.count = 0
self.idle = gobject.idle_add(self.load_model().next)
def close(self):
def destroy(self):
gobject.source_remove(self.idle)
def load_model(self):
"""
Objects can have very large backreferences. To avoid blocking the
interface up to the moment that the model is created, this method is
called via gobject.idle_add.
WARNING: a consequence of above is that loading can still be happening
while the GUI using this model is no longer used. Disconnect any
methods before closing the GUI.
"""
self.count = 0
for ref in self.sref_list:
self.count += 1
@@ -69,6 +69,7 @@ class EmbeddedList(ButtonTab):
move_buttons, jump_button)
self.changed = False
self.model = None
self.build_model = build_model
# handle the selection
@@ -466,6 +467,9 @@ class EmbeddedList(ButtonTab):
selectedpath = None
if node:
selectedpath = model.get_path(node)
if self.model and hasattr(self.model, 'destroy'):
self.tree.set_model(None)
self.model.destroy()
try:
self.model = self.construct_model()
except AttributeError, msg:
@@ -78,6 +78,8 @@ class NameEmbedList(GroupEmbeddedList):
]
def __init__(self, dbstate, uistate, track, data, person, callback):
"""callback is the function to call when preferred name changes
on the namelist """
self.data = data
self.person = person
self.callback = callback
@@ -86,6 +88,14 @@ class NameEmbedList(GroupEmbeddedList):
NameModel, move_buttons=True)
self.tree.expand_all()
def _cleanup_on_exit(self):
"""Unset all things that can block garbage collection.
Finalize rest
"""
self.person = None
self.callback = None
self.data = None
def get_data(self):
return ([self.person.get_primary_name()],
self.data)
+7 -7
View File
@@ -129,15 +129,15 @@ class EditAddress(EditSecondary):
notebook = gtk.Notebook()
self.srcref_list = self._add_tab(
notebook,
SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj))
self.srcref_list = SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj)
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = self._add_tab(
notebook,
NoteTab(self.dbstate, self.uistate, self.track,
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype=NoteType.ADDRESS))
notetype=NoteType.ADDRESS)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs( notebook)
notebook.show_all()
+7 -7
View File
@@ -107,15 +107,15 @@ class EditAttribute(EditSecondary):
def _create_tabbed_pages(self):
notebook = gtk.Notebook()
self.srcref_list = self._add_tab(
notebook,
SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj))
self.srcref_list = SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj)
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = self._add_tab(
notebook,
NoteTab(self.dbstate, self.uistate, self.track,
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype = NoteType.ATTRIBUTE))
notetype = NoteType.ATTRIBUTE)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs( notebook)
notebook.show_all()
+7 -7
View File
@@ -144,15 +144,15 @@ class EditChildRef(EditSecondary):
"""
notebook = gtk.Notebook()
self.srcref_list = self._add_tab(
notebook,
SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj))
self.srcref_list = SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj)
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = self._add_tab(
notebook,
NoteTab(self.dbstate, self.uistate, self.track,
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype=NoteType.CHILDREF))
notetype=NoteType.CHILDREF)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs( notebook)
notebook.show_all()
-3
View File
@@ -213,9 +213,6 @@ class EditEvent(EditPrimary):
self.track_ref_for_deletion("attr_list")
self.track_ref_for_deletion("backref_list")
def _cleanup_on_exit(self):
self.backref_list.close()
def build_menu_names(self, event):
return (_('Edit Event'), self.get_menu_title())
+9
View File
@@ -425,6 +425,15 @@ class EditFamily(EditPrimary):
else:
self.add_parent = False
def _cleanup_on_exit(self):
"""Unset all things that can block garbage collection.
Finalize rest
"""
#FIXME, we rebind show_all below, this prevents garbage collection of
# the dialog, fix the rebind
self.window.show_all = None
EditPrimary._cleanup_on_exit(self)
def empty_object(self):
return gen.lib.Family()
+22 -14
View File
@@ -198,6 +198,7 @@ class EditLdsOrd(EditSecondary):
if item[0] in self._get_types()],
self.db.readonly,
changed=self.ord_type_changed)
self.track_ref_for_deletion('type_menu')
self.temple_menu = MonitoredStrMenu(
self.top.get_object('temple'),
@@ -205,6 +206,7 @@ class EditLdsOrd(EditSecondary):
self.obj.get_temple,
LdsUtils.TEMPLES.name_code_data(),
self.db.readonly)
self.track_ref_for_deletion('temple_menu')
self.status_menu = MonitoredMenu(
self.top.get_object('status'),
@@ -213,6 +215,7 @@ class EditLdsOrd(EditSecondary):
[(item[1],item[0]) for item in gen.lib.LdsOrd._STATUS_MAP
if item[0] in _DATA_MAP[self.obj.get_type()] ],
self.db.readonly)
self.track_ref_for_deletion('status_menu')
self.ord_type_changed()
self.update_parent_label()
@@ -236,15 +239,16 @@ class EditLdsOrd(EditSecondary):
def _create_tabbed_pages(self):
notebook = gtk.Notebook()
self.srcref_list = self._add_tab(
notebook,
SourceEmbedList(self.dbstate,self.uistate, self.track,self.obj))
self.srcref_list = SourceEmbedList(self.dbstate, self.uistate,
self.track, self.obj)
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = self._add_tab(
notebook,
NoteTab(self.dbstate, self.uistate, self.track,
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype=gen.lib.NoteType.LDS))
notetype=gen.lib.NoteType.LDS)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs( notebook)
notebook.show_all()
@@ -304,6 +308,7 @@ class EditLdsOrd(EditSecondary):
"""
if self.callback:
self.callback(self.obj)
self.callback = None
self.close()
#-------------------------------------------------------------------------
@@ -378,6 +383,7 @@ class EditFamilyLdsOrd(EditSecondary):
[(item[1],item[0]) for item in gen.lib.LdsOrd._TYPE_MAP
if item[0] in self._get_types()],
self.db.readonly)
self.track_ref_for_deletion('type_menu')
self.temple_menu = MonitoredStrMenu(
self.top.get_object('temple'),
@@ -385,6 +391,7 @@ class EditFamilyLdsOrd(EditSecondary):
self.obj.get_temple,
LdsUtils.TEMPLES.name_code_data(),
self.db.readonly)
self.track_ref_for_deletion('temple_menu')
self.status_menu = MonitoredMenu(
self.top.get_object('status'),
@@ -393,18 +400,19 @@ class EditFamilyLdsOrd(EditSecondary):
[(item[1],item[0]) for item in gen.lib.LdsOrd._STATUS_MAP
if item[0] in _DATA_MAP[self.obj.get_type()]],
self.db.readonly)
self.track_ref_for_deletion('status_menu')
def _create_tabbed_pages(self):
notebook = gtk.Notebook()
self.srcref_list = self._add_tab(
notebook,
SourceEmbedList(self.dbstate,self.uistate, self.track,self.obj))
self.srcref_list = SourceEmbedList(self.dbstate,self.uistate, self.track,self.obj)
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = self._add_tab(
notebook,
NoteTab(self.dbstate, self.uistate, self.track,
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype=gen.lib.NoteType.LDS))
notetype=gen.lib.NoteType.LDS)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
notebook.show_all()
self.top.get_object('vbox').pack_start(notebook,True)
-3
View File
@@ -293,9 +293,6 @@ class EditMedia(EditPrimary):
self.callback(self.obj)
self.close()
def _cleanup_on_exit(self):
self.backref_list.close()
def data_has_changed(self):
"""
A date comparison can fail incorrectly because we have made the
+44 -35
View File
@@ -82,17 +82,21 @@ class EditMediaRef(EditReference):
self.top.get_object("label428").set_text(_("Y coordinate|Y"))
tblref = self.top.get_object('table50')
notebook = self.top.get_object('notebook_ref')
self.notebook_ref = self.top.get_object('notebook_ref')
self.track_ref_for_deletion("notebook_ref")
#recreate start page as GrampsTab
notebook.remove_page(0)
self.notebook_ref.remove_page(0)
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
_('General'), tblref)
self.track_ref_for_deletion("reftab")
tblref = self.top.get_object('table2')
notebook = self.top.get_object('notebook_shared')
self.notebook_shared = self.top.get_object('notebook_shared')
#recreate start page as GrampsTab
notebook.remove_page(0)
self.notebook_shared.remove_page(0)
self.track_ref_for_deletion("notebook_shared")
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
_('_General'), tblref)
self.track_ref_for_deletion("primtab")
def draw_preview(self):
"""
@@ -140,6 +144,7 @@ class EditMediaRef(EditReference):
self.rectangle = coord
self.subpixmap = self.top.get_object("subpixmap")
self.track_ref_for_deletion("subpixmap")
self.draw_preview()
@@ -161,24 +166,28 @@ class EditMediaRef(EditReference):
self.set_corner1_x,
self.get_corner1_x,
self.db.readonly)
self.track_ref_for_deletion("corner1_x_spinbutton")
self.corner1_y_spinbutton = MonitoredSpinButton(
self.top.get_object("corner1_y"),
self.set_corner1_y,
self.get_corner1_y,
self.db.readonly)
self.track_ref_for_deletion("corner1_y_spinbutton")
self.corner2_x_spinbutton = MonitoredSpinButton(
self.top.get_object("corner2_x"),
self.set_corner2_x,
self.get_corner2_x,
self.db.readonly)
self.track_ref_for_deletion("corner2_x_spinbutton")
self.corner2_y_spinbutton = MonitoredSpinButton(
self.top.get_object("corner2_y"),
self.set_corner2_y,
self.get_corner2_y,
self.db.readonly)
self.track_ref_for_deletion("corner2_y_spinbutton")
self.descr_window = MonitoredEntry(
self.top.get_object("description"),
@@ -493,44 +502,44 @@ class EditMediaRef(EditReference):
self._add_tab(notebook_src, self.primtab)
self._add_tab(notebook_ref, self.reftab)
self.srcref_list = self._add_tab(
notebook_ref,
SourceEmbedList(self.dbstate,self.uistate,self.track,
self.source_ref))
self.srcref_list = SourceEmbedList(self.dbstate,self.uistate,self.track,
self.source_ref)
self._add_tab(notebook_ref, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.attr_list = self._add_tab(
notebook_ref,
AttrEmbedList(self.dbstate,self.uistate,self.track,
self.source_ref.get_attribute_list()))
self.attr_list = AttrEmbedList(self.dbstate,self.uistate,self.track,
self.source_ref.get_attribute_list())
self._add_tab(notebook_ref, self.attr_list)
self.track_ref_for_deletion("attr_list")
self.backref_list = self._add_tab(
notebook_src,
MediaBackRefList(self.dbstate,self.uistate,self.track,
self.backref_list = MediaBackRefList(self.dbstate,self.uistate,self.track,
self.db.find_backlink_handles(self.source.handle),
self.enable_warnbox
))
)
self._add_tab(notebook_src, self.backref_list)
self.track_ref_for_deletion("backref_list")
self.note_ref_tab = self._add_tab(
notebook_ref,
NoteTab(self.dbstate, self.uistate, self.track,
self.source_ref.get_note_list(),
notetype=NoteType.MEDIAREF))
self.note_ref_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.source_ref.get_note_list(),
notetype=NoteType.MEDIAREF)
self._add_tab(notebook_ref, self.note_ref_tab)
self.track_ref_for_deletion("note_ref_tab")
self.src_srcref_list = self._add_tab(
notebook_src,
SourceEmbedList(self.dbstate,self.uistate,self.track,
self.source))
self.src_srcref_list = SourceEmbedList(self.dbstate,self.uistate,
self.track, self.source)
self._add_tab(notebook_src, self.src_srcref_list)
self.track_ref_for_deletion("src_srcref_list")
self.src_attr_list = self._add_tab(
notebook_src,
AttrEmbedList(self.dbstate,self.uistate,self.track,
self.source.get_attribute_list()))
self.src_attr_list = AttrEmbedList(self.dbstate,self.uistate,self.track,
self.source.get_attribute_list())
self._add_tab(notebook_src, self.src_attr_list)
self.track_ref_for_deletion("src_attr_list")
self.src_note_ref_tab = self._add_tab(
notebook_src,
NoteTab(self.dbstate, self.uistate, self.track,
self.source.get_note_list(),
notetype=NoteType.MEDIA))
self.src_note_ref_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.source.get_note_list(),
notetype=NoteType.MEDIA)
self._add_tab(notebook_src, self.src_note_ref_tab)
self.track_ref_for_deletion("src_note_ref_tab")
self._setup_notebook_tabs(notebook_src)
self._setup_notebook_tabs(notebook_ref)
@@ -569,5 +578,5 @@ class EditMediaRef(EditReference):
#call callback if given
if self.update:
self.update(self.source_ref,self.source)
self.update = None
self.close()
+13 -7
View File
@@ -35,6 +35,7 @@ from gen.ggettext import gettext as _
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
import gobject
import gtk
#-------------------------------------------------------------------------
@@ -171,6 +172,7 @@ class EditName(EditSecondary):
self.obj.get_sort_as,
format_list,
self.db.readonly)
self.track_ref_for_deletion("sort_as")
self.display_as = MonitoredMenu(
self.top.get_object('display_as'),
@@ -178,6 +180,7 @@ class EditName(EditSecondary):
self.obj.get_display_as,
format_list,
self.db.readonly)
self.track_ref_for_deletion("display_as")
self.given_field = MonitoredEntry(
self.top.get_object("alt_given"),
@@ -248,16 +251,17 @@ class EditName(EditSecondary):
notebook = self.top.get_object("notebook")
self._add_tab(notebook, self.gennam)
self.track_ref_for_deletion("gennam")
self.srcref_list = self._add_tab(
notebook,
SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj))
self.srcref_list = SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj)
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = self._add_tab(
notebook,
NoteTab(self.dbstate, self.uistate, self.track,
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype=NoteType.PERSONNAME))
notetype=NoteType.PERSONNAME)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs( notebook)
@@ -423,6 +427,7 @@ class EditName(EditSecondary):
if closeit:
if self.callback:
self.callback(self.obj)
self.callback = None
self.close()
def _cleanup_on_exit(self):
@@ -436,3 +441,4 @@ class EditName(EditSecondary):
# can't use group_over, see Note in gen/lib/name/Name.set_group_as().
if not self.group_as.obj.get_editable():
self.obj.set_group_as("")
EditSecondary._cleanup_on_exit(self)
+9 -1
View File
@@ -754,6 +754,7 @@ class EditPerson(EditPrimary):
self.close()
if self.callback:
self.callback(self.obj)
self.callback = None
def _edit_name_clicked(self, obj):
"""
@@ -763,8 +764,11 @@ class EditPerson(EditPrimary):
on the main form (not in the names tab).
"""
EditName(self.dbstate, self.uistate, self.track,
try:
EditName(self.dbstate, self.uistate, self.track,
self.pname, self._update_name)
except Errors.WindowActiveError:
pass
def _update_name(self, name):
"""
@@ -886,10 +890,14 @@ class EditPerson(EditPrimary):
return child_ref_list
def _cleanup_on_exit(self):
"""Unset all things that can block garbage collection.
Finalize rest
"""
config.set('interface.prefix-suffix', self.prefix_suffix.active_key)
config.set('interface.patro-title', self.patro_title.active_key)
config.save()
EditPrimary._cleanup_on_exit(self)
class GenderDialog(gtk.MessageDialog):
def __init__(self, parent=None):
+13 -11
View File
@@ -141,19 +141,20 @@ class EditPersonRef(EditSecondary):
notebook = gtk.Notebook()
self.srcref_list = self._add_tab(
notebook,
SourceEmbedList(self.dbstate,self.uistate,self.track,self.obj))
self.note_tab = self._add_tab(
notebook,
NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype=NoteType.ASSOCIATION))
self.srcref_list = SourceEmbedList(self.dbstate, self.uistate,
self.track, self.obj)
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self._setup_notebook_tabs( notebook)
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype=NoteType.ASSOCIATION)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs(notebook)
notebook.show_all()
self.top.get_object('vbox').pack_start(notebook,True)
self.top.get_object('vbox').pack_start(notebook, True)
def build_menu_names(self, obj):
return (_('Person Reference'),_('Person Reference Editor'))
@@ -167,6 +168,7 @@ class EditPersonRef(EditSecondary):
if self.obj.ref:
if self.callback:
self.callback(self.obj)
self.callback = None
self.close()
else:
from QuestionDialog import ErrorDialog
+1 -4
View File
@@ -278,9 +278,6 @@ class EditPlace(EditPrimary):
self._setup_notebook_tabs(notebook)
def _cleanup_on_exit(self):
self.backref_tab.close()
def save(self, *obj):
self.ok_button.set_sensitive(False)
if self.object_is_empty():
@@ -315,9 +312,9 @@ class EditPlace(EditPrimary):
msg = _("Edit Place (%s)") % self.obj.get_title()
self.db.transaction_commit(trans, msg)
self.close()
if self.callback:
self.callback(self.obj)
self.close()
#-------------------------------------------------------------------------
#
+33 -2
View File
@@ -151,7 +151,13 @@ class EditPrimary(ManagedWindow.ManagedWindow, DbGUIElement):
return page
def _cleanup_on_exit(self):
pass
"""Unset all things that can block garbage collection.
Finalize rest
"""
for tab in self.__tabs:
if hasattr(tab, '_cleanup_on_exit'):
tab._cleanup_on_exit()
self.__tabs = None
def object_is_empty(self):
return cmp(self.obj.serialize()[1:],
@@ -172,8 +178,14 @@ class EditPrimary(ManagedWindow.ManagedWindow, DbGUIElement):
def _do_close(self, *obj):
self._cleanup_db_connects()
self.dbstate.disconnect(self.dbstate_connect_key)
self._cleanup_connects()
self._cleanup_on_exit()
self.get_from_handle = None
self.get_from_gramps_id = None
ManagedWindow.ManagedWindow.close(self)
self.dbstate = None
self.uistate = None
self.db = None
def _cleanup_db_connects(self):
"""
@@ -187,6 +199,23 @@ class EditPrimary(ManagedWindow.ManagedWindow, DbGUIElement):
for tab in self.__tabs:
if hasattr(tab, 'callman'):
tab._cleanup_callbacks()
def _cleanup_connects(self):
"""
Connects to interface elements to things outside the element should be
removed before destroying the interface
"""
self._cleanup_local_connects()
for tab in [tab for tab in self.__tabs if hasattr(tab, '_cleanup_local_connects')]:
tab._cleanup_local_connects()
def _cleanup_local_connects(self):
"""
Connects to interface elements to things outside the element should be
removed before destroying the interface. This methods cleans connects
of the main interface, not of the displaytabs.
"""
pass
def check_for_close(self, handles):
"""
@@ -236,7 +265,9 @@ class EditPrimary(ManagedWindow.ManagedWindow, DbGUIElement):
self.obj.serialize()[1:]) != 0
def save(self, *obj):
pass
""" Save changes and close. Inheriting classes must implement this
"""
self.close()
def set_contexteventbox(self, eventbox):
"""Set the contextbox that grabs button presses if not grabbed
+35 -2
View File
@@ -186,7 +186,6 @@ class EditReference(ManagedWindow.ManagedWindow, DbGUIElement):
button.connect('clicked',self.close_and_cancel)
def close_and_cancel(self, obj):
self._cleanup_on_exit()
self.close(obj)
def check_for_close(self, handles):
@@ -205,11 +204,28 @@ class EditReference(ManagedWindow.ManagedWindow, DbGUIElement):
button.set_sensitive(True)
def _cleanup_on_exit(self):
pass
"""Unset all things that can block garbage collection.
Finalize rest
"""
for tab in self.__tabs:
if hasattr(tab, '_cleanup_on_exit'):
tab._cleanup_on_exit()
self.__tabs = None
self.dbstate = None
self.uistate = None
self.source_ref = None
self.source = None
self.update = None
self.warn_box = None
self.db = None
self.callman.database = None
self.callman = None
def close(self,*obj):
self._cleanup_db_connects()
self._cleanup_connects()
ManagedWindow.ManagedWindow.close(self)
self._cleanup_on_exit()
def _cleanup_db_connects(self):
"""
@@ -222,3 +238,20 @@ class EditReference(ManagedWindow.ManagedWindow, DbGUIElement):
self._cleanup_callbacks()
for tab in [tab for tab in self.__tabs if hasattr(tab, 'callman')]:
tab._cleanup_callbacks()
def _cleanup_connects(self):
"""
Connects to interface elements to things outside the element should be
removed before destroying the interface
"""
self._cleanup_local_connects()
for tab in [tab for tab in self.__tabs if hasattr(tab, '_cleanup_local_connects')]:
tab._cleanup_local_connects()
def _cleanup_local_connects(self):
"""
Connects to interface elements to things outside the element should be
removed before destroying the interface. This methods cleans connects
of the main interface, not of the displaytabs.
"""
pass
-3
View File
@@ -190,9 +190,6 @@ class EditRepository(EditPrimary):
self.db.transaction_commit(trans, msg)
self.close()
def _cleanup_on_exit(self):
self.backref_list.close()
class DeleteRepositoryQuery(object):
def __init__(self, dbstate, uistate, repository, sources):
self.obj = repository
+33 -2
View File
@@ -106,7 +106,20 @@ class EditSecondary(ManagedWindow.ManagedWindow, DbGUIElement):
return page
def _cleanup_on_exit(self):
pass
"""Unset all things that can block garbage collection.
Finalize rest
"""
for tab in self.__tabs:
if hasattr(tab, '_cleanup_on_exit'):
tab._cleanup_on_exit()
self.__tabs = None
self.dbstate = None
self.uistate = None
self.obj = None
self.db = None
self.callback = None
self.callman.database = None
self.callman = None
def define_ok_button(self,button,function):
button.connect('clicked',function)
@@ -121,8 +134,9 @@ class EditSecondary(ManagedWindow.ManagedWindow, DbGUIElement):
def close(self,*obj):
self._cleanup_db_connects()
self._cleanup_on_exit()
self._cleanup_connects()
ManagedWindow.ManagedWindow.close(self)
self._cleanup_on_exit()
def _cleanup_db_connects(self):
"""
@@ -135,3 +149,20 @@ class EditSecondary(ManagedWindow.ManagedWindow, DbGUIElement):
self._cleanup_callbacks()
for tab in [tab for tab in self.__tabs if hasattr(tab, 'callman')]:
tab._cleanup_callbacks()
def _cleanup_connects(self):
"""
Connects to interface elements to things outside the element should be
removed before destroying the interface
"""
self._cleanup_local_connects()
for tab in [tab for tab in self.__tabs if hasattr(tab, '_cleanup_local_connects')]:
tab._cleanup_local_connects()
def _cleanup_local_connects(self):
"""
Connects to interface elements to things outside the element should be
removed before destroying the interface. This methods cleans connects
of the main interface, not of the displaytabs.
"""
pass
-3
View File
@@ -208,9 +208,6 @@ class EditSource(EditPrimary):
self.db.transaction_commit(trans, msg)
self.close()
def _cleanup_on_exit(self):
self.backref_tab.close()
class DeleteSrcQuery(object):
def __init__(self, dbstate, uistate, source, the_lists):
self.source = source
+29 -29
View File
@@ -158,39 +158,39 @@ class EditSourceRef(EditReference):
self._add_tab(notebook_src, self.primtab)
self._add_tab(notebook_ref, self.reftab)
self.note_tab = self._add_tab(
notebook_src,
NoteTab(self.dbstate, self.uistate, self.track,
self.source.get_note_list(),
notetype=gen.lib.NoteType.SOURCE))
self.gallery_tab = self._add_tab(
notebook_src,
GalleryTab(self.dbstate, self.uistate, self.track,
self.source.get_media_list()))
self.data_tab = self._add_tab(
notebook_src,
DataEmbedList(self.dbstate, self.uistate, self.track,
self.source))
self.repo_tab = self._add_tab(
notebook_src,
RepoEmbedList(self.dbstate, self.uistate, self.track,
self.source.get_reporef_list()))
self.srcref_list = self._add_tab(
notebook_src,
SourceBackRefList(self.dbstate,self.uistate, self.track,
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.source.get_note_list(),
notetype=gen.lib.NoteType.SOURCE)
self._add_tab(notebook_src, self.note_tab)
self.track_ref_for_deletion("note_tab")
self.gallery_tab = GalleryTab(self.dbstate, self.uistate, self.track,
self.source.get_media_list())
self._add_tab(notebook_src, self.gallery_tab)
self.track_ref_for_deletion("gallery_tab")
self.data_tab = DataEmbedList(self.dbstate, self.uistate, self.track,
self.source)
self._add_tab(notebook_src, self.data_tab)
self.track_ref_for_deletion("data_tab")
self.repo_tab = RepoEmbedList(self.dbstate, self.uistate, self.track,
self.source.get_reporef_list())
self._add_tab(notebook_src, self.repo_tab)
self.track_ref_for_deletion("repo_tab")
self.srcref_list = SourceBackRefList(self.dbstate,self.uistate, self.track,
self.db.find_backlink_handles(self.source.handle),
self.enable_warnbox
))
)
self._add_tab(notebook_src, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.comment_tab = self._add_tab(
notebook_ref,
NoteTab(self.dbstate, self.uistate, self.track,
self.comment_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.source_ref.get_note_list(),
notetype=gen.lib.NoteType.SOURCEREF))
notetype=gen.lib.NoteType.SOURCEREF)
self._add_tab(notebook_ref, self.comment_tab)
self.track_ref_for_deletion("comment_tab")
self._setup_notebook_tabs( notebook_src)
self._setup_notebook_tabs( notebook_ref)
+31 -4
View File
@@ -69,9 +69,12 @@ class BaseSelector(ManagedWindow.ManagedWindow):
ManagedWindow.ManagedWindow.__init__(self, uistate, track, self)
self.renderer = gtk.CellRendererText()
self.track_ref_for_deletion("renderer")
self.renderer.set_property('ellipsize',pango.ELLIPSIZE_END)
self.db = dbstate.db
self.tree = None
self.model = None
self.glade = Glade()
@@ -103,6 +106,7 @@ class BaseSelector(ManagedWindow.ManagedWindow):
self.skip_list=skip
self.build_tree()
self.selection = self.tree.get_selection()
self.track_ref_for_deletion("selection")
self._local_init()
self._set_size()
@@ -152,14 +156,15 @@ class BaseSelector(ManagedWindow.ManagedWindow):
def run(self):
val = self.window.run()
result = None
if val == gtk.RESPONSE_OK:
id_list = self.get_selected_ids()
self.close()
if id_list and id_list[0]:
return self.get_from_handle_func()(id_list[0])
result = self.get_from_handle_func()(id_list[0])
self.close()
elif val != gtk.RESPONSE_DELETE_EVENT:
self.close()
return None
return result
def _on_row_activated(self, treeview, path, view_col):
self.window.response(gtk.RESPONSE_OK)
@@ -255,6 +260,7 @@ class BaseSelector(ManagedWindow.ManagedWindow):
self.add_columns(self.tree)
#reset the model with correct sorting
self.clear_model()
self.model = self.get_model_class()(self.db, self.sort_col,
self.sortorder,
sort_map=self.column_order(),
@@ -299,7 +305,7 @@ class BaseSelector(ManagedWindow.ManagedWindow):
def show_toggle(self, obj):
filter_info = None if obj.get_active() else self.filter
self.clear_model()
self.model = self.get_model_class()(self.db, self.sort_col,
self.sortorder,
sort_map=self.column_order(),
@@ -307,3 +313,24 @@ class BaseSelector(ManagedWindow.ManagedWindow):
search=filter_info)
self.tree.set_model(self.model)
self.tree.grab_focus()
def clear_model(self):
if self.model:
self.tree.set_model(None)
if hasattr(self.model, 'destroy'):
self.model.destroy()
self.model = None
def _cleanup_on_exit(self):
"""Unset all things that can block garbage collection.
Finalize rest
"""
self.clear_model()
self.db = None
self.tree = None
self.columns = None
self.search_bar.destroy()
def close(self, *obj):
ManagedWindow.ManagedWindow.close(self)
self._cleanup_on_exit()
+3
View File
@@ -258,6 +258,9 @@ class ListView(NavigationView):
filter_info = (False, value, value[0] in self.exact_search())
if self.dirty or not self.model:
if self.model:
self.list.set_model(None)
self.model.destroy()
self.model = self.make_model(self.dbstate.db, self.sort_col,
search=filter_info,
sort_map=self.column_order())
+11
View File
@@ -101,6 +101,17 @@ class EventModel(FlatBaseModel):
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=9,
search=search, skip=skip, sort_map=sort_map)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
self.db = None
self.gen_cursor = None
self.map = None
self.fmap = None
self.smap = None
FlatBaseModel.destroy(self)
def on_get_n_columns(self):
return len(self.fmap)+1
+11
View File
@@ -90,6 +90,17 @@ class FamilyModel(FlatBaseModel):
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=6,
search=search, skip=skip, sort_map=sort_map)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
self.db = None
self.gen_cursor = None
self.map = None
self.fmap = None
self.smap = None
FlatBaseModel.destroy(self)
def marker_column(self):
"""
Return the column for marker colour.
+20
View File
@@ -122,6 +122,14 @@ class FlatNodeMap(object):
self._reverse = False
self.__corr = (0, 1)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
self._index2hndl = None
self._fullhndl = None
self._hndl2index = None
def set_path_map(self, index2hndllist, fullhndllist, identical=True,
reverse=False):
"""
@@ -414,6 +422,18 @@ class FlatBaseModel(gtk.GenericTreeModel):
_LOG.debug(self.__class__.__name__ + ' __init__ ' +
str(time.clock() - cput) + ' sec')
def destroy(self):
"""
Unset all elements that prevent garbage collection
"""
self.db = None
self.sort_func = None
if self.node_map:
self.node_map.destroy()
self.node_map = None
self.rebuild_data = None
self.search = None
def set_search(self, search):
"""
Change the search function that filters the data in the model.
+11
View File
@@ -83,6 +83,17 @@ class MediaModel(FlatBaseModel):
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=7,
search=search, skip=skip, sort_map=sort_map)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
self.db = None
self.gen_cursor = None
self.map = None
self.fmap = None
self.smap = None
FlatBaseModel.destroy(self)
def on_get_n_columns(self):
return len(self.fmap)+1
+11
View File
@@ -78,6 +78,17 @@ class NoteModel(FlatBaseModel):
FlatBaseModel.__init__(self, db, scol, order, search=search,
skip=skip, sort_map=sort_map)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
self.db = None
self.gen_cursor = None
self.map = None
self.fmap = None
self.smap = None
FlatBaseModel.destroy(self)
def marker_column(self):
"""
Return the column for marker colour.
+27 -1
View File
@@ -146,6 +146,17 @@ class PeopleBaseModel(object):
self.lru_bdate = LRU(PeopleBaseModel._CACHE_SIZE)
self.lru_ddate = LRU(PeopleBaseModel._CACHE_SIZE)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
self.db = None
self.gen_cursor = None
self.map = None
self.fmap = None
self.smap = None
self.clear_local_cache()
def marker_column(self):
"""
Return the column for marker colour.
@@ -454,7 +465,6 @@ class PersonListModel(PeopleBaseModel, FlatBaseModel):
"""
def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None,
skip=set(), sort_map=None):
PeopleBaseModel.__init__(self, db)
FlatBaseModel.__init__(self, db, search=search, skip=skip,
tooltip_column=12,
@@ -464,6 +474,13 @@ class PersonListModel(PeopleBaseModel, FlatBaseModel):
""" Clear the LRU cache """
PeopleBaseModel.clear_local_cache(self, handle)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
PeopleBaseModel.destroy(self)
FlatBaseModel.destroy(self)
class PersonTreeModel(PeopleBaseModel, TreeBaseModel):
"""
Hierarchical people model.
@@ -475,6 +492,15 @@ class PersonTreeModel(PeopleBaseModel, TreeBaseModel):
TreeBaseModel.__init__(self, db, 12, search=search, skip=skip,
scol=scol, order=order, sort_map=sort_map)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
PeopleBaseModel.destroy(self)
self.hmap = None
self.number_items = None
TreeBaseModel.destroy(self)
def _set_base_data(self):
"""See TreeBaseModel, we also set some extra lru caches
"""
+26
View File
@@ -117,6 +117,16 @@ class PlaceBaseModel(object):
self.column_handle,
]
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
self.db = None
self.gen_cursor = None
self.map = None
self.fmap = None
self.smap = None
def on_get_n_columns(self):
return len(self.fmap)+1
@@ -218,6 +228,13 @@ class PlaceListModel(PlaceBaseModel, FlatBaseModel):
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=14,
search=search, skip=skip, sort_map=sort_map)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
PlaceBaseModel.destroy(self)
FlatBaseModel.destroy(self)
def column_name(self, data):
return unicode(data[2])
@@ -240,6 +257,15 @@ class PlaceTreeModel(PlaceBaseModel, TreeBaseModel):
nrgroups = 3,
group_can_have_handle = True)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
PlaceBaseModel.destroy(self)
self.hmap = None
self.number_items = None
TreeBaseModel.destroy(self)
def _set_base_data(self):
"""See TreeBaseModel, for place, most have been set in init of
PlaceBaseModel
+12
View File
@@ -94,6 +94,18 @@ class RepositoryModel(FlatBaseModel):
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=14,
search=search, skip=skip, sort_map=sort_map)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
self.db = None
self.gen_cursor = None
self.get_handles = None
self.map = None
self.fmap = None
self.smap = None
FlatBaseModel.destroy(self)
def on_get_n_columns(self):
return len(self.fmap)+1
+11
View File
@@ -77,6 +77,17 @@ class SourceModel(FlatBaseModel):
FlatBaseModel.__init__(self,db,scol, order,tooltip_column=7,search=search,
skip=skip, sort_map=sort_map)
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
self.db = None
self.gen_cursor = None
self.map = None
self.fmap = None
self.smap = None
FlatBaseModel.destroy(self)
def on_get_n_columns(self):
return len(self.fmap)+1
+27
View File
@@ -173,6 +173,17 @@ class NodeMap(object):
"""
def __init__(self):
self.id2node = {}
def destroy(self):
"""
Unset all elements that can prevent garbage collection
"""
## for key, item in self.id2node.iteritems():
## item.prev = None
## item.next = None
## item.parent = None
## item.children = []
self.id2node.clear()
def add_node(self, node):
"""
@@ -321,6 +332,22 @@ class TreeBaseModel(gtk.GenericTreeModel):
_LOG.debug(self.__class__.__name__ + ' __init__ ' +
str(time.clock() - cput) + ' sec')
def destroy(self):
"""
Unset all elements that prevent garbage collection
"""
self.db = None
self.sort_func = None
if self.nodemap:
self.nodemap.destroy()
self.nodemap = None
self.rebuild_data = None
self._build_data = None
self.search = None
self.current_filter = None
self.clear_cache()
self.lru_data = None
def _set_base_data(self):
"""
This method must be overwritten in the inheriting class, setting
+1 -1
View File
@@ -485,7 +485,7 @@ class RTFDoc(BaseDoc,TextDoc):
else:
self.text += i
def process_spaces (self, line, format):
def process_spaces(line, format):
"""
Function to process spaces in text lines for flowed and pre-formatted notes.
line : text to process
+5
View File
@@ -618,6 +618,11 @@ class GedcomWriter(UpdateCallback):
continue
val = libgedcom.personalConstantEvents.get(etype, "").strip()
role = int(event_ref.get_role())
if role != gen.lib.EventRoleType.PRIMARY:
continue
if val and val.strip():
if val in NEEDS_PARAMETER:
+7
View File
@@ -431,9 +431,11 @@ class GeneWebParser(object):
field = fields[idx]
idx += 1
if field.startswith("+"):
field = field[1:]
mar_date = self.parse_date(self.decode(field))
LOG.debug(" Married at: %s" % field)
elif field.startswith("-"):
field = field[1:]
div_date = self.parse_date(self.decode(field))
LOG.debug(" Div at: %s" % field)
elif field == "#mp" and idx < len(fields):
@@ -465,13 +467,17 @@ class GeneWebParser(object):
gen.lib.EventType.MARRIAGE, None, mar_date, mar_place, mar_source)
mar_ref = gen.lib.EventRef()
mar_ref.set_reference_handle(mar.get_handle())
mar_ref.set_role(gen.lib.EventRoleType.FAMILY)
self.current_family.add_event_ref(mar_ref)
self.current_family.set_relationship(
gen.lib.FamilyRelType(gen.lib.FamilyRelType.MARRIED))
if div_date:
div = self.create_event(
gen.lib.EventType.DIVORCE, None, div_date, None, None)
div_ref = gen.lib.EventRef()
div_ref.set_reference_handle(div.get_handle())
div_ref.set_role(gen.lib.EventRoleType.FAMILY)
self.current_family.add_event_ref(div_ref)
if sep_date or engaged:
@@ -479,6 +485,7 @@ class GeneWebParser(object):
gen.lib.EventType.ENGAGEMENT, None, sep_date, None, None)
sep_ref = gen.lib.EventRef()
sep_ref.set_reference_handle(sep.get_handle())
sep_ref.set_role(gen.lib.EventRoleType.FAMILY)
self.current_family.add_event_ref(sep_ref)
if not married:
+7 -1
View File
@@ -118,6 +118,7 @@ import LdsUtils
import Utils
from DateHandler._DateParser import DateParser
from gen.db.dbconst import EVENT_KEY
from QuestionDialog import WarningDialog
#-------------------------------------------------------------------------
#
@@ -5433,7 +5434,12 @@ class GedcomParser(UpdateCallback):
"""
if state.genby == "GRAMPS":
self.gedsource = self.gedmap.get_from_source_tag(line.data)
if state.genby.upper() == "LEGACY":
fname = os.path.basename(self.filename)
WarningDialog(_("Import of GEDCOM file %s with DEST=%s, could cause errors in the resulting database!") % \
(fname, state.genby), _("Look for nameless events."))
def __header_plac(self, line, state):
"""
@param line: The current line in GedLine format
+5 -3
View File
@@ -427,7 +427,8 @@ class Html(list):
)
self[0:0] = [xmldecl]
#
def addDOCTYPE(self, name='html', external_id=_XHTML10_STRICT, *args):
def addDOCTYPE(self, name='html', public='PUBLIC',
external_id=_XHTML10_STRICT, *args):
"""
Add a DOCTYPE statement to the start of the list
@@ -440,8 +441,9 @@ class Html(list):
:param args: 0 or more positional parameters to be added to this
DOCTYPE.
"""
doctype = '<!DOCTYPE %s %s%s>' % (
name,
doctype = '<!DOCTYPE %s %s %s%s>' % (
name,
public,
external_id,
' %s'*len(args) % args
)
+1 -1
View File
@@ -119,7 +119,7 @@ def process_spaces(intext, format):
outtext += char
elif state == SPACEHOLD:
if char == " ":
outtext += "&nbsp; "
outtext += " &nbsp;"
state = NORMAL
elif char == "<":
outtext += " "+char
+2 -1
View File
@@ -21,7 +21,8 @@ pkgdata_PYTHON = \
rel_pl.py\
rel_pt.py\
rel_ru.py\
rel_sk.py\
rel_sk.py\
rel_sl.py\
rel_sv.py
pkgpyexecdir = @pkgpyexecdir@/plugins/rel
+337
View File
@@ -0,0 +1,337 @@
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2005 Donald N. Allingham
# Copyright (C) 2008 Brian G. Matherly
# Copyright (C) 2009-2010 Andrew I Baznikin
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id:rel_sl.py 9912 2008-01-22 09:17:46Z acraphae $
# Written by Bernard Banko, inspired from rel_ru.py by Alex Roitman.
"""
Slovenian-specific definitions of relationships
"""
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
import gen.lib
import Relationship
#-------------------------------------------------------------------------
_ancestors = [ u"", u"starš", u"stari starš", u"prastari starš" ]
_fathers = [ u"", u"oče", u"ded", u"praded", u"prapraded" ]
_mothers = [ u"", u"mati", u"babica", u"prababica", u"praprababica" ]
_descendants = [
u"", u"otrok", u"vnuk(inja)", u"pravnuk(inja)", u"prapravnuk(inja)" ]
_sons = [ u"", u"sin", u"vnuk", u"pravnuk", u"prapravnuk" ]
_daughters = [ u"", u"hči", u"vnukinja", u"pravnukinja", u"prapravnukinja" ]
_maleCousins = [ u"", u"brat", u"bratranec", u"mali bratranec" ]
_femaleCousins = [ u"", u"sestra", u"sestrična", u"mala sestrična" ]
_someCousins = [ u"", u"brat ali sestra", u"bratranec ali sestrična",
u"mali bratranec ali mala sestrična" ]
_aunts = [ u"", u"teta", u"stara teta", u"prateta", u"praprateta" ]
_uncles = [ u"", u"stric", u"stari stric", u"prastric", u"praprastric" ]
_nieces = [ u"", u"nečakinja", u"pranečakinja", u"prapranečakinja" ]
_nephews = [ u"", u"nečak", u"pranečak", u"prapranečak" ]
#plural
_children = [ u"", u"otroci", u"vnuki", u"pravnuki", u"prapravnuki" ]
_parents = [ u"", u"starši", u"stari starši", u"prastarši", u"praprastarši" ]
_siblings = [ u"", u"sorojenci", u"strici", u"stari strici", u"prastrici",
u"praprastrici" ]
_neph_niec = [ u"", u"nečaki", u"pranečaki", u"prapranečaki" ]
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
class RelationshipCalculator(Relationship.RelationshipCalculator):
"""
RelationshipCalculator Class
"""
def __init__(self):
Relationship.RelationshipCalculator.__init__(self)
def getAncestor(self, level):
if level > len(_ancestors)-1:
return u"%s-krat-pra-prednik" % (level-2)
else:
return _ancestors[level]
def getFather(self, level):
if level > len(_fathers)-1:
return u"%s-krat-pra-ded" % (level-2)
else:
return _fathers[level]
def getMother(self, level):
if level > len(_mothers)-1:
return u"%s-krat-pra-babica" % (level-2)
else:
return _mothers[level]
def getSon(self, level):
if level > len(_sons)-1:
return u"%s-krat-pra-vnuk" % (level-2)
else:
return _sons[level]
def getDaughter(self, level):
if level > len(_daughters)-1:
return u"%s-krat-pra-vnukinja" % (level-2)
else:
return _daughters[level]
def getDescendant(self, level):
if level > len(_descendants)-1:
return u"%s-krat-pra-vnuk(inja)" % (level-2)
else:
return _descendants[level]
def getMaleCousin(self, level):
if level > len(_maleCousins)-1:
return u"bratranec v %s. kolenu" % (level*2)
else:
return _maleCousins[level]
def getFemaleCousin(self, level):
if level > len(_femaleCousins)-1:
return u"sestrična v %s. kolenu" % (level*2)
else:
return _femaleCousins[level]
def getSomeCousin(self, level):
if level > len(_someCousins)-1:
return u"bratranec ali sestrična v %s. kolenu" % (level*2)
else:
return _someCousins[level]
def getSuffix(self, distance, level):
# distance-level = 2Gb <=> Gb=1
if distance-level == 2 or distance < 6:
return u""
else:
return u" v %s. kolenu" % (distance)
def getAunt(self, distance, level):
if distance == 5 and level == 1:
return u"mala teta"
elif level > len(_aunts)-1:
return u"%s-krat-pra-teta%s" % (level-2, self.getSuffix(distance, level))
else:
return u"%s%s" % (_aunts[level], self.getSuffix(distance, level))
def getUncle(self, distance, level):
if distance == 5 and level == 1:
return u"mali stric"
elif level > len(_uncles)-1:
return u"%s-krat-pra-stric%s" % (level-2, self.getSuffix(distance, level))
else:
return u"%s%s" % (_uncles[level], self.getSuffix(distance, level))
def getNiece(self, distance, level):
if distance == 5 and level == 1:
return u"mala nečakinja"
elif level > len(_nieces)-1:
return u"%s-krat-pra-nečakinja%s" % (level-1, self.getSuffix(distance, level))
else:
return u"%s%s" % (_nieces[level], self.getSuffix(distance, level))
def getNephew(self, distance, level):
if distance == 5 and level == 1:
return u"mali nečak"
elif level > len(_nephews)-1:
return u"%s-krat-pra-nečak%s" % (level-1, self.getSuffix(distance, level))
else:
return u"%s%s" % (_nephews[level], self.getSuffix(distance, level))
def get_single_relationship_string(
self, Ga, Gb, gender_a, gender_b, reltocommon_a, reltocommon_b,
only_birth=True, in_law_a=False, in_law_b=False):
"""
Provide a string that describes the relationsip between a person, and
another person. E.g. "grandparent" or "child".
To be used as: 'person b is the grandparent of a', this will
be in translation string :
'person b is the %(relation)s of a'
Note that languages with gender should add 'the' inside the
translation, so eg in french:
'person b est %(relation)s de a'
where relation will be here: le grandparent
Ga and Gb can be used to mathematically calculate the relationship.
See the Wikipedia entry for more information:
http://en.wikipedia.org/wiki/Cousin#Mathematical_definitions
"""
if Gb == 0:
if Ga == 0: rel_str = "ista oseba"
elif gender_b == gen.lib.Person.MALE:
rel_str = (self.getFather(Ga))
elif gender_b == gen.lib.Person.FEMALE:
rel_str = (self.getMother(Ga))
else:
rel_str = (self.getAncestor(Ga))
elif Ga == 0:
if gender_b == gen.lib.Person.MALE:
rel_str = (self.getSon(Gb))
elif gender_b == gen.lib.Person.FEMALE:
rel_str = (self.getDaughter(Gb))
else:
rel_str = (self.getDescendant(Gb))
elif Ga == Gb:
if gender_b == gen.lib.Person.MALE:
rel_str = (self.getMaleCousin(Gb))
elif gender_b == gen.lib.Person.FEMALE:
rel_str = (self.getFemaleCousin(Gb))
else:
rel_str = (self.getSomeCousin(Gb))
elif Ga > Gb:
if gender_b == gen.lib.Person.FEMALE:
rel_str = (self.getAunt(Ga+Gb, Ga-Gb))
else:
rel_str = (self.getUncle(Ga+Gb, Ga-Gb)) # we'll use male for unknown sex
else: #Ga < Gb
if gender_b == gen.lib.Person.FEMALE:
rel_str = (self.getNiece(Ga+Gb, Gb-Ga))
else:
rel_str = (self.getNephew(Ga+Gb, Gb-Ga)) # we'll use male for unknown sex
return rel_str
def get_sibling_relationship_string(self, sib_type, gender_a, gender_b,
in_law_a=False, in_law_b=False):
""" Determine the string giving the relation between two siblings of
type sib_type.
Eg: b is the brother of a
Here 'brother' is the string we need to determine
This method gives more details about siblings than
get_single_relationship_string can do.
DON'T TRANSLATE THIS PROCEDURE IF LOGIC IS EQUAL IN YOUR LANGUAGE,
AND SAME METHODS EXIST (get_uncle, get_aunt, get_sibling
"""
gender = gender_b #we don't need gender_a
inlaw = in_law_a or in_law_b
if sib_type == self.HALF_SIB_MOTHER or sib_type == self.HALF_SIB_FATHER:
prefix = u"pol"
else:
prefix = u""
if sib_type < self.STEP_SIB:
# ie. NORM_SIB or one of HALF_SIBs
if not inlaw:
if gender == gen.lib.Person.MALE:
rel_str = u"%sbrat" % (prefix)
elif gender == gen.lib.Person.FEMALE:
rel_str = u"%ssestra" % (prefix)
else:
rel_str = u"%sbrat ali %ssestra" % (prefix, prefix)
else:
if gender == gen.lib.Person.MALE:
rel_str = u"%ssvak" % (prefix)
elif gender == gen.lib.Person.FEMALE:
rel_str = u"%ssvakinja" % (prefix)
else:
rel_str = u"%ssvak ali %ssvakinja" % (prefix, prefix)
else:
rel_str = u""
return rel_str
def get_plural_relationship_string(
self, Ga, Gb, reltocommon_a='', reltocommon_b='', only_birth=True,
in_law_a=False, in_law_b=False):
distance = Ga+Gb
rel_str = u"sorodniki v %s. kolenu" % (distance)
if Ga == 0:
# These are descendants
if Gb < len(_children):
rel_str = _children[Gb]
else:
rel_str = u"%s-krat-pra-vnuki" % (Gb-2)
elif Gb == 0:
# These are parents/grand parents
if Ga < len(_parents):
rel_str = _parents[Ga]
else:
rel_str = u"%s-krat-pra-starši" % (Ga-2)
elif Gb == 1:
# These are siblings/aunts/uncles
if Ga < len(_siblings):
rel_str = _siblings[Ga]
else:
rel_str = u"%s-krat-pra-strici" % (Ga-2)
elif Ga == 1:
# These are nieces/nephews
if Gb < len(_neph_niec):
rel_str = _neph_niec[Gb]
else:
rel_str = u"%s-krat-pra-nečaki" % (Gb-1)
elif Ga == Gb:
# These are cousins in the same generation
if Ga == 2:
rel_str = u"bratranci"
elif Ga == 3:
rel_str = u"mali bratranci"
else:
rel_str = u"bratranci v %s. kolenu" % (distance)
elif Ga > Gb:
# These are cousins in different generations with the second person
# being in a higher generation from the common ancestor than the
# first person.
level = Ga - Gb
if distance == 5:
rel_str = u"mali strici"
elif level < len(_siblings)-1:
# len-1 and level+1 to skip the siblings in uncles' levels
rel_str = u"%s v %s. kolenu" % (_siblings[level+1], distance)
else:
rel_str = u"%s-krat-pra-strici v %s. kolenu" % (level-2, distance)
else: #Gb > Ga:
# These are cousins in different generations with the second person
# being in a lower generation from the common ancestor than the
# first person.
level = Gb - Ga
if distance == 5:
rel_str = u"mali nečaki"
elif level < len(_neph_niec):
rel_str = u"%s v %s. kolenu" % (_neph_niec[level], distance)
else:
rel_str = u"%s-krat-pra-nečaki v %s. kolenu" % (level-1, distance)
if in_law_b == True:
rel_str = "zakonci, ki jih imajo %s" % rel_str
return rel_str
if __name__ == "__main__":
"""TRANSLATORS, copy this if statement at the bottom of your
rel_xx.py module, and test your work with:
python src/plugins/rel/rel_xx.py
"""
from Relationship import test
RC = RelationshipCalculator()
test(RC, True)
#
#from PluginMgr import register_relcalc
# register_relcalc(RelationshipCalculatorClass,["sl","sl_SI","sl-SI","slovenian","Slovenian","slovenščina"])
+14
View File
@@ -253,6 +253,20 @@ plg.relcalcclass = 'RelationshipCalculator'
plg.lang_list = ["sk", "SK", "sk_SK", "slovensky", "slovak", "Slovak",
"sk_SK.UTF8", "sk_SK.UTF-8", "sk_SK.utf-8", "sk_SK.utf8"]
# sl
plg = newplugin()
plg.id = 'relcalc_sl'
plg.name = _("Slovenian Relationship Calculator")
plg.description = _("Calculates relationships between people")
plg.version = '1.0'
plg.gramps_target_version = '3.2'
plg.status = STABLE
plg.fname = 'rel_sl.py'
plg.ptype = RELCALC
plg.relcalcclass = 'RelationshipCalculator'
plg.lang_list = ["sl", "SL", "sl_SI", "slovenščina", "slovenian", "Slovenian",
"sl_SI.UTF8", "sl_SI.UTF-8", "sl_SI.utf-8", "sl_SI.utf8"]
# sv
plg = newplugin()
plg.id = 'relcalc_sv'
+1 -1
View File
@@ -102,7 +102,7 @@ class AncestorReport(Report):
language = menu.get_option_by_name('trans').get_value()
translator = Translator(language)
self._ = translator.gettext
self.__narrator = Narrator(self.database,
self.__narrator = Narrator(self.database, use_fulldate=True,
translator=translator)
def apply_filter(self, person_handle, index, generation=1):
+1
View File
@@ -97,6 +97,7 @@ GROUP_DICT = {FACTS: [EventType.ADOPT,
EventType.PROBATE,
EventType.RELIGION,
EventType.RETIREMENT,
EventType.UNKNOWN,
EventType.WILL],
FAMILY: [EventType.ANNULMENT,
EventType.BLESS,
+6 -2
View File
@@ -30,6 +30,7 @@
#-------------------------------------------------------------------------
from __future__ import with_statement
import os
import sys
import cStringIO
from gen.ggettext import gettext as _
@@ -552,8 +553,10 @@ class CheckIntegrity(object):
photo_name = Utils.media_path_full(self.db, obj.get_path())
if photo_name is not None and photo_name != "" and not Utils.find_file(photo_name):
if cl:
# Convert to file system encoding before prining
fn = os.path.basename(photo_name).encode(sys.getfilesystemencoding())
print "Warning: media file %s was not found." \
% os.path.basename(photo_name)
% fn
self.bad_photo.append(ObjectId)
else:
if missmedia_action == 0:
@@ -1627,7 +1630,8 @@ class Report(ManagedWindow.ManagedWindow):
def __init__(self, uistate, text, cl=0):
if cl:
print text
# Convert to file system encoding before prining
print text.encode(sys.getfilesystemencoding())
return
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self)
+23 -21
View File
@@ -716,15 +716,20 @@ class BasePage(object):
# return table to its callers
return table
def source_link(self, handle, name, gid = None, up = False):
def source_link(self, handle, name, cindex, gid = None, up = False):
"""
creates a link to the source
"""
url = self.report.build_url_fname_html(handle, "src", up)
name = html_escape( name )
# begin hyperlink
hyper = Html("a", html_escape(name), href = url, title = html_escape(name))
hyper = Html( "a", name, href = url, title = name )
# if cindex has a value, then add the name attribute to the hyperlink
if cindex is not None:
hyper.attr += ' name = "sref%d"' % cindex
# add GRAMPS ID
if not self.noid and gid:
@@ -1506,7 +1511,7 @@ class BasePage(object):
mime_type = photo.get_mime_type()
# get media description
descr = photo.get_description()
descr = html_escape( photo.get_description() )
if mime_type:
try:
@@ -1538,8 +1543,7 @@ class BasePage(object):
newpath = newpath.replace('\\',"/")
# begin hyperlink
section += self.media_link(photo_handle, newpath, descr,
True, True)
section += self.media_link(photo_handle, newpath, descr, True, True)
except (IOError, OSError), msg:
WarningDialog(_("Could not add photo to page"), str(msg))
@@ -1712,13 +1716,8 @@ class BasePage(object):
# Add this source and its references to the page
source = db.get_source_from_handle(shandle)
title = source.get_title()
list = Html("li") + (
Html("a",
self.source_link(source.handle, title, source.gramps_id,
up=True),
name="sref%d" % cindex,
inline=True)
)
list = Html("li") + \
self.source_link( shandle, title, cindex, source.gramps_id, up = True)
ordered1 = Html("ol")
citation_ref_list = citation.get_ref_list()
@@ -3299,6 +3298,7 @@ class SourceListPage(BasePage):
def __init__(self, report, title, handle_set):
BasePage.__init__(self, report, title)
db = report.database
cindex = None
handle_list = list(handle_set)
source_dict = {}
@@ -3335,12 +3335,13 @@ class SourceListPage(BasePage):
thead += trow
header_row = [
(None, "RowLabel"),
("&nbsp;", "RowLabel"),
(_("Source Name|Name"), "Name") ]
trow.extend(
Html("th", label or "&nbsp;", class_ = "Column" + colclass, inline = True)
for (label, colclass) in header_row)
Html("th", label, class_ = "Column" + colclass, inline = True)
for (label, colclass) in header_row
)
# begin table body
tbody = Html("tbody")
@@ -3349,14 +3350,15 @@ class SourceListPage(BasePage):
for index, key in enumerate(keys):
(source, handle) = source_dict[key]
trow = ( Html("tr") +
trow = Html("tr")
trow.extend(
Html("td", index + 1, class_ = "ColumnRowLabel", inline = True)
)
)
tbody += trow
trow += Html("td",
self.source_link(handle, source.get_title(),
source.gramps_id),
class_ = "ColumnName")
trow += Html("td", self.source_link( handle, source.get_title(),
cindex, source.gramps_id), class_ = "ColumnName")
# add clearline for proper styling
# add footer section