Compare commits
56 Commits
Author | SHA1 | Date | |
---|---|---|---|
de4a0766e7 | |||
078cafc0c8 | |||
c5b68976e1 | |||
d9edb0bd9c | |||
c99cd60e81 | |||
e4a677f57d | |||
7d8f3c7dfb | |||
bda1ace41f | |||
493be971c2 | |||
aa1fb05e26 | |||
7115f24e54 | |||
97900a087d | |||
cd8579654a | |||
b614f650d0 | |||
6eb7599b68 | |||
2110e52171 | |||
5dd1e197d1 | |||
e97199cba3 | |||
bb2e2fd1cc | |||
aceb486b79 | |||
85fa8c09ea | |||
f283347987 | |||
2e7ad59d01 | |||
31650baf2c | |||
bfa94869bc | |||
447191f427 | |||
fdda045607 | |||
5ce490e3fa | |||
d77174143d | |||
ebfbdce49b | |||
1fc782a60e | |||
01e6dedae9 | |||
0cb7d90257 | |||
1ab9c7c6d8 | |||
d120265624 | |||
811014e1c2 | |||
d15f8ffe07 | |||
e177fe4030 | |||
175ee0f498 | |||
63dbb12bfa | |||
2fa9ffc7fe | |||
745585d93c | |||
27e22a5b21 | |||
b444385631 | |||
6dd80f4955 | |||
0b8985216c | |||
e3431e1d98 | |||
59fb9bbb64 | |||
e09a5741b7 | |||
db9b15a18c | |||
9273ca6886 | |||
1e81e32965 | |||
32b8401167 | |||
59d4cfa35e | |||
3ed52a7ed6 | |||
a109d25c0b |
gramps2
ChangeLogNEWSconfigure.in
example
gedcom
src
ArgHandler.pyAutoComp.pyChooseParents.pyDateDisplay.pyDateHandler.pyDateParser.pyDbPrompter.pyEditPerson.pyEditPlace.pyEditSource.pyErrors.pyFamilyView.pyGrampsBSDDB.pyGrampsDbBase.pyImageSelect.pyMergePeople.pyNameDisplay.pyPeopleModel.pyPeopleView.pyReadGedcom.pyReadGrdb.pySelectChild.pySort.pySourceView.pyUtils.pyWriteGedcom.pyWriteXML.pyconst.py.in
dates
gramps_main.pyplugins
Checkpoint.pyFamilyGroup.pyMakefile.amScratchPad.pyStatisticsChart.pyTestcaseGenerator.pyWebPage.pyscratchpad.glade
po
@ -1,3 +1,191 @@
|
||||
2005-06-04 Don Allingham <don@gramps-project.org>
|
||||
* src/DateHandler.py: handle generic "en", "fr" cases as a fallback
|
||||
if the unknown "yy_XX" code is passed. Try yy if yy_XX fails.
|
||||
* src/dates/Date_*.py: add a default xx case
|
||||
|
||||
* Release: Version 2.0.2 "Little fermented curd will do the trick"
|
||||
released.
|
||||
|
||||
2005-06-03 Don Allingham <don@gramps-project.org>
|
||||
* src/DateHandler.py: add more English locales
|
||||
* src/dates/Date_fi.py: fix estimated/calculated, handle span
|
||||
properly
|
||||
* src/dates/Makefile.am: remove Date_fi for 2.0.2
|
||||
|
||||
2005-06-04 Eero Tamminen <eerot@sf>
|
||||
* src/po/fi.po: Updated translation to 2.0.2 template.pot.
|
||||
Everything except for a few dozen tips is translated.
|
||||
|
||||
2005-06-03 Julio Sanchez <jsanchez@users.sourceforge.net>
|
||||
* src/po/es.po: Translation update for version 2.0.2.
|
||||
|
||||
2005-06-03 Don Allingham <don@gramps-project.org>
|
||||
* src/EditPerson.py: Don't add empty strings to pdmap
|
||||
* src/AutoComp.py: don't add empty strings to completion
|
||||
|
||||
2005-06-03 Alexander Roitman <shura@gramps-project.org>
|
||||
* src/Utils.py (bold_label,unbold_label,temp_label): optionally
|
||||
set cursor.
|
||||
* src/EditSource.py (__init__,on_switch_page): Call
|
||||
display_references using idle_add; (display_references): set
|
||||
cursor when done.
|
||||
* src/EditPlace (__init__,on_switch_page): Call
|
||||
display_references using idle_add; (display_references): set
|
||||
cursor when done.
|
||||
* src/ImageSelect (__init__,on_switch_page): Call
|
||||
display_references using idle_add; (display_references): set
|
||||
cursor when done.
|
||||
|
||||
* src/EditPlace.py, src/EditSource.py: Detect new objects by
|
||||
handle.
|
||||
* src/const.py.in (save_frel): Return English strings.
|
||||
* src/plugins/FamilyGroup.py (parse_user_options): Only select
|
||||
spouse if there is any.
|
||||
|
||||
2005-06-03 Jens Arvidsson <jya@sverige.nu>
|
||||
* src/po/sv.po: Minor fixes found via pochkpyvar.pl.
|
||||
|
||||
2005-06-03 Jens Arvidsson <jya@sverige.nu>
|
||||
* src/po/sv.po: Translation update for version 2.0.2.
|
||||
|
||||
2005-06-02 Don Allingham <don@gramps-project.org>
|
||||
* src/dates/Date_fi.py: Finnish date parser
|
||||
* src/dates/Makefile.am: added Date_fi.py
|
||||
* src/ChooseParents.py: fixed all_males filtering problem, display
|
||||
all people when a person is blocked by the likely filter
|
||||
|
||||
2005-06-02 Alex Roitman <shura@gramps-project.org>
|
||||
* src/ReadGedcom.py (get_next): Use single space to split the line
|
||||
into level, tag, and the field contents; strip extra white space
|
||||
off the tag name.
|
||||
* src/po/ru.po: Update for 2.0.2.
|
||||
* NEWS: Update.
|
||||
|
||||
2005-06-01 Martin Hawlisch <Martin.Hawlisch@gmx.de>
|
||||
* src/Utils.py (probably_alive): If no year is given it now treats
|
||||
people as dead when they have a death event instead of counting them
|
||||
as alive in the curent year when they died in the current year.
|
||||
|
||||
2005-06-01 Anton Huber <anton_huber@gmx.de>
|
||||
* src/po/de.po: Updated translation
|
||||
|
||||
2005-06-01 Don Allingham <don@gramps-project.org>
|
||||
* src/PeopleModel.py: Improve rebuid times by using database cursor,
|
||||
caching sort names, and replacing loops with map/lamba
|
||||
* src/PeopleView.py: prevent goto_active_person reentrancy, use get_selected_objects
|
||||
instead of selected_foreach, combine row_changed and set_dnd_target into the same
|
||||
callback, rebuild only affected surname on person-update if pissible
|
||||
|
||||
2005-06-01 Alex Roitman <shura@gramps-project.org>
|
||||
* src/plugins/Makefile.am: Don't ship NavWebPage yet.
|
||||
* src/po/template.po: Update for 2.0.2.
|
||||
|
||||
2005-05-31 Don Allingham <don@gramps-project.org>
|
||||
* src/plugins/Checkpoint.py: add support for custom command
|
||||
|
||||
2005-05-30 Martin Hawlisch <Martin.Hawlisch@gmx.de>
|
||||
* src/DbPrompter.py: Properly return False if opening a file failed
|
||||
|
||||
2005-05-31 Anton Huber <anton_huber@gmx.de>
|
||||
* src/po/de.po: Updated translation
|
||||
|
||||
2005-05-30 Don Allingham <don@gramps-project.org>
|
||||
* src/plugins/Checkpoint.py: Start of a checkpoint tool
|
||||
|
||||
2005-05-30 Martin Hawlisch <Martin.Hawlisch@gmx.de>
|
||||
* src/ArgHandler.py (handle_args) Exit if opening a file failed
|
||||
* src/Errors.py: New exception type "FileVersionError"
|
||||
* src/GrampsDbBase.py (version_supported): New method
|
||||
* src/GrampsBSDDB.py (version_supported): New method
|
||||
* src/gramps_main.py (read_file) catch FileVersionError;
|
||||
(post_load): only load if version_supported()
|
||||
* src/ReadGrdb.py (importData): only load if version_supported()
|
||||
|
||||
2005-05-30 Matt Brubeck <mbrubeck@cs.hmc.edu>
|
||||
* src/DbPrompter.py: fix handling of spaces when creating a new
|
||||
file - use open instead of "touch"
|
||||
|
||||
2005-05-30 Alex Roitman <shura@gramps-project.org>
|
||||
* src/po/sv.po: Typo (closes 1211150).
|
||||
|
||||
2005-05-28 Martin Hawlisch <Martin.Hawlisch@gmx.de>
|
||||
* src/gramps_main.py (read_file): Optimize exception handling of
|
||||
load_database errors.
|
||||
* src/ArgHandler.py (auto_save_load): Return actual status of
|
||||
read_file instead of always 1. This will now open the select database
|
||||
dialog on autoload errors.
|
||||
|
||||
2005-05-28 Alex Roitman <shura@gramps-project.org>
|
||||
* configure.in: Bump up the version number after 2.0.1.
|
||||
|
||||
2005-05-28 Martin Hawlisch <Martin.Hawlisch@gmx.de>
|
||||
* src/gramps_main.py (change_active_person): Dont change to the
|
||||
current active person again.
|
||||
* src/FamilyView.py (drag_data_received): Allow reordering of childs
|
||||
when they were not correctly ordered before.
|
||||
|
||||
2005-05-23 Jens Arvidsson <jya@sverige.nu>
|
||||
* src/po/sv.po: A few fixes to the Swedish translation.
|
||||
|
||||
2005-05-26 Don Allingham <don@gramps-project.org>
|
||||
* src/PeopleView.py: back port anti-flicker code from HEAD
|
||||
* src/dates/Date_de.py: use "etwa" instead of "circa"
|
||||
* src/DateDisplay.py: don't mark date formats as translatable
|
||||
|
||||
2005-05-25 Don Allingham <don@gramps-project.org>
|
||||
* src/DateDisplay.py: properly encode french republican dates as unicode
|
||||
|
||||
2005-05-26 Martin Hawlisch <Martin.Hawlisch@gmx.de>
|
||||
* src/EditSource.py (DelSrcQuery.query_response),
|
||||
src/EditPlace.py (DeletePlaceQuery.query_response),
|
||||
src/ImageSelect.py (DeleteMediaQuery.query_response): Block
|
||||
signals while removing the references of the to be deleted
|
||||
object to get much more speed.
|
||||
* src/plugins/TestcaseGenerator.py: Add place, media and source
|
||||
references.
|
||||
* src/SourceView.py (button_press): Handle case of no selection.
|
||||
|
||||
2005-05-25 Alex Roitman <shura@gramps-project.org>
|
||||
* src/WriteGedcom.py (write_person): Typo.
|
||||
|
||||
* src/NameDisplay.py (sorted): Use sorted name, not display name flag.
|
||||
* src/Sort.py (by_sorted_name): Add method.
|
||||
* src/WebPage (dump_index): Proper sorting, for both last name
|
||||
sections and the names within each section.
|
||||
|
||||
2005-05-25 Richard Taylor <rjt-gramps@thegrindstone.me.uk>
|
||||
* src/plugins/ScratchPad.py: disabled search because it does not do
|
||||
what the user expects.
|
||||
|
||||
2005-05-25 Richard Taylor <rjt-gramps@thegrindstone.me.uk>
|
||||
* src/plugins/ScratchPad.py: rename on_scratch_pad_delete_event for consistency
|
||||
* src/plugins/scratchpad.glade: add on_scratch_pad_delete_event to fix bug
|
||||
when window is close using the window manager close button.
|
||||
|
||||
2005-05-23 Don Allingham <don@gramps-project.org>
|
||||
* src/MergePeople.py: clean up and refactoring of code.
|
||||
* Release: Version 2.0.1 "None shall pass" released.
|
||||
|
||||
2005-05-23 Alex Roitman <shura@gramps-project.org>
|
||||
* src/po/ru.po: More tranlsated tips.
|
||||
|
||||
2005-05-23 Eero Tamminen <eerot@sf>
|
||||
* src/po/fi.po: Translate all fuzzy strings. Tips are still to be
|
||||
translated
|
||||
* src/plugins/StatisticsChart.py: Fix a typo in one string
|
||||
(I actually changed the string, but now it should actually be
|
||||
understandable i.e. something people can localize)
|
||||
* src/dates/Makefile.am, src/dates/Date_fi.py: Remove Finnish date
|
||||
parser. Unfortunately I don't have time either to fix DateParser.py
|
||||
regexps matches to be position independent or write the required
|
||||
(almost) duplicate code to Date_fi.py directly
|
||||
|
||||
2005-05-23 Jens Arvidsson <jya@sverige.nu>
|
||||
* src/po/sv.po: Translation update for version 2.0.1.
|
||||
|
||||
2005-05-22 Don Allingham <don@gramps-project.org>
|
||||
* src/MergePeople.py: merge improvements, merge data not merged before.
|
||||
|
||||
2005-05-22 Alex Roitman <shura@gramps-project.org>
|
||||
* src/ImageSelect.py (item_event): Do nothing if nothing is selected.
|
||||
* src/EditSource.py (button_press): Return if no data.
|
||||
|
@ -1,3 +1,8 @@
|
||||
Version 2.0.2 -- the "Little fermented curd will do the trick" release
|
||||
* Updated German translation (Anton Huber).
|
||||
* Usability improvements for large databases.
|
||||
* Bug fixes
|
||||
|
||||
Version 2.0.1 -- the "None shall pass" release
|
||||
* Example database function is back.
|
||||
* Entering incestuous relations is possible (with the warning).
|
||||
|
@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
dnl May need to run automake && aclocal first
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT(gramps, 2.0.1, gramps-bugs@lists.sourceforge.net)
|
||||
AC_INIT(gramps, 2.0.2, gramps-bugs@lists.sourceforge.net)
|
||||
AC_CONFIG_SRCDIR(src/gramps.py)
|
||||
AM_INIT_AUTOMAKE(1.6.3)
|
||||
RELEASE=0.CVS$(head -c 10 ${srcdir}/ChangeLog | tr -d '-')
|
||||
|
@ -102,6 +102,7 @@
|
||||
2 DATE BET. 1794 - 1796
|
||||
2 PLAC Tommarp, Kristianstad Lan, Sweden
|
||||
1 DEAT
|
||||
2 DATE deceased
|
||||
2 PLAC Sweden
|
||||
1 REFN 366
|
||||
1 FAMS @F03@
|
||||
|
@ -228,20 +228,17 @@ class ArgHandler:
|
||||
import GrampsBSDDB
|
||||
self.parent.db.close()
|
||||
self.parent.db = GrampsBSDDB.GrampsBSDDB()
|
||||
self.parent.read_file(filename)
|
||||
return 1
|
||||
return self.parent.read_file(filename)
|
||||
elif filetype == const.app_gramps_xml:
|
||||
import GrampsXMLDB
|
||||
self.parent.db.close()
|
||||
self.parent.db = GrampsXMLDB.GrampsXMLDB()
|
||||
self.parent.read_file(filename)
|
||||
return 1
|
||||
return self.parent.read_file(filename)
|
||||
elif filetype == const.app_gedcom:
|
||||
import GrampsGEDDB
|
||||
self.parent.db.close()
|
||||
self.parent.db = GrampsGEDDB.GrampsGEDDB()
|
||||
self.parent.read_file(filename)
|
||||
return 1
|
||||
return self.parent.read_file(filename)
|
||||
else:
|
||||
return 0
|
||||
|
||||
@ -307,6 +304,8 @@ class ArgHandler:
|
||||
# Add the file to the recent items
|
||||
RecentFiles.recent_files(filename,filetype)
|
||||
self.parent.build_recent_menu()
|
||||
else:
|
||||
os._exit(1)
|
||||
return
|
||||
|
||||
if self.open:
|
||||
|
@ -32,7 +32,8 @@ def fill_combo(combo,data_list):
|
||||
store = gtk.ListStore(gobject.TYPE_STRING)
|
||||
|
||||
for data in data_list:
|
||||
store.append(row=[data])
|
||||
if data:
|
||||
store.append(row=[data])
|
||||
|
||||
combo.set_model(store)
|
||||
combo.set_text_column(0)
|
||||
@ -45,7 +46,8 @@ def fill_combo(combo,data_list):
|
||||
def fill_entry(entry,data_list):
|
||||
store = gtk.ListStore(gobject.TYPE_STRING)
|
||||
for data in data_list:
|
||||
store.append(row=[data])
|
||||
if data:
|
||||
store.append(row=[data])
|
||||
|
||||
completion = gtk.EntryCompletion()
|
||||
completion.set_model(store)
|
||||
@ -56,7 +58,8 @@ def fill_entry(entry,data_list):
|
||||
def fill_option_text(combobox,data):
|
||||
store = gtk.ListStore(str)
|
||||
for item in data:
|
||||
store.append(row=[item])
|
||||
if item:
|
||||
store.append(row=[item])
|
||||
combobox.set_model(store)
|
||||
combobox.set_active(0)
|
||||
|
||||
|
@ -93,7 +93,7 @@ class ChooseParents:
|
||||
db.connect('person-add', self.redraw)
|
||||
db.connect('person-update', self.redraw)
|
||||
db.connect('person-delete', self.redraw)
|
||||
db.connect('person-rebuild', self.redraw2)
|
||||
db.connect('person-rebuild', self.redraw)
|
||||
|
||||
# set default filters
|
||||
self.all_males_filter = GenericFilter.GenericFilter()
|
||||
@ -286,14 +286,6 @@ class ChooseParents:
|
||||
def redraw(self,handle_list):
|
||||
self.redrawf()
|
||||
self.redrawm()
|
||||
# self.father_model.rebuild_data()
|
||||
# self.mother_model.rebuild_data()
|
||||
|
||||
def redraw2(self):
|
||||
self.redrawf()
|
||||
self.redrawm()
|
||||
# self.father_model.rebuild_data()
|
||||
# self.mother_model.rebuild_data()
|
||||
|
||||
def redrawf(self):
|
||||
"""Redraws the potential father list"""
|
||||
@ -326,7 +318,7 @@ class ChooseParents:
|
||||
|
||||
def showallf_toggled(self,obj):
|
||||
if self.father_filter == self.likely_males_filter:
|
||||
self.father_filter = self.all_females_filter
|
||||
self.father_filter = self.all_males_filter
|
||||
else:
|
||||
self.father_filter = self.likely_males_filter
|
||||
self.redrawf()
|
||||
@ -529,11 +521,13 @@ class ChooseParents:
|
||||
self.father_selection.select_path(path)
|
||||
self.father_list.scroll_to_cell(path,None,1,0.5,0)
|
||||
except KeyError:
|
||||
WarningDialog(_("Added person is not visible"),
|
||||
_("The person you added is currently "
|
||||
"not visible due to the chosen filter. "
|
||||
"This may occur if you did not specify "
|
||||
"a birth date."))
|
||||
self.father_filter = self.all_males_filter
|
||||
self.showallf_toggled(None)
|
||||
path = self.father_model.on_get_path(handle)
|
||||
top_path = self.father_model.on_get_path(name)
|
||||
self.father_list.expand_row(top_path,0)
|
||||
self.father_selection.select_path(path)
|
||||
self.father_list.scroll_to_cell(path,None,1,0.5,0)
|
||||
else:
|
||||
try:
|
||||
path = self.mother_model.on_get_path(handle)
|
||||
@ -542,11 +536,13 @@ class ChooseParents:
|
||||
self.mother_selection.select_path(path)
|
||||
self.mother_list.scroll_to_cell(path,None,1,0.5,0)
|
||||
except:
|
||||
WarningDialog(_("Added person is not visible"),
|
||||
_("The person you added is currently "
|
||||
"not visible due to the chosen filter. "
|
||||
"This may occur if you did not specify "
|
||||
"a birth date."))
|
||||
self.mother_filter = self.all_females_filter
|
||||
self.showallm_toggled(None)
|
||||
path = self.mother_model.on_get_path(handle)
|
||||
top_path = self.mother_model.on_get_path(name)
|
||||
self.mother_list.expand_row(top_path,0)
|
||||
self.mother_selection.select_path(path)
|
||||
self.mother_list.scroll_to_cell(path,None,1,0.5,0)
|
||||
|
||||
def add_parent_clicked(self,obj):
|
||||
"""Called with the Add New Person button is pressed. Calls the QuickAdd
|
||||
|
@ -83,11 +83,20 @@ class DateDisplay:
|
||||
)
|
||||
|
||||
_french = (
|
||||
'', u'Vend\xc3\xa9miaire', 'Brumaire',
|
||||
'Frimaire', u'Niv\xc3\xb4se', u'Pluvi\xc3\xb4se',
|
||||
u'Vent\xc3\xb4se', 'Germinal', u'Flor\xc3\xa9al',
|
||||
'Prairial', 'Messidor', 'Thermidor',
|
||||
'Fructidor', 'Extra'
|
||||
'',
|
||||
unicode("Vend<EFBFBD>miaire",'latin-1'),
|
||||
'Brumaire',
|
||||
'Frimaire',
|
||||
unicode("Niv<EFBFBD>se",'latin-1'),
|
||||
unicode("Pluvi<EFBFBD>se",'latin-1'),
|
||||
unicode("Vent<EFBFBD>se",'latin-1'),
|
||||
'Germinal',
|
||||
unicode("Flor<EFBFBD>al",'latin-1'),
|
||||
'Prairial',
|
||||
'Messidor',
|
||||
'Thermidor',
|
||||
'Fructidor',
|
||||
'Extra'
|
||||
)
|
||||
|
||||
_persian = (
|
||||
@ -271,9 +280,9 @@ class DateDisplay:
|
||||
if date_val[1] == 0:
|
||||
return year
|
||||
else:
|
||||
return "%s %d" % (month_list[date_val[1]],year)
|
||||
return u"%s %d" % (month_list[date_val[1]],year)
|
||||
else:
|
||||
return "%s %d, %s" % (month_list[date_val[1]],date_val[0],year)
|
||||
return u"%s %d, %s" % (month_list[date_val[1]],date_val[0],year)
|
||||
|
||||
def _display_french(self,date_val):
|
||||
return self._display_calendar(date_val,self._french)
|
||||
@ -293,8 +302,8 @@ class DateDisplayEn(DateDisplay):
|
||||
"""
|
||||
|
||||
formats = (
|
||||
_("YYYY-MM-DD (ISO)"), _("Numerical"), _("Month Day, Year"),
|
||||
_("MON DAY, YEAR"), _("Day Month Year"), _("DAY MON YEAR")
|
||||
"YYYY-MM-DD (ISO)", "Numerical", "Month Day, Year",
|
||||
"MON DAY, YEAR", "Day Month Year", "DAY MON YEAR"
|
||||
)
|
||||
|
||||
def __init__(self,format=None):
|
||||
|
@ -46,24 +46,18 @@ import DateDisplay
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
_lang = locale.getlocale(locale.LC_TIME)[0]
|
||||
if _lang:
|
||||
_lang_short = _lang.split('_')[0]
|
||||
else:
|
||||
_lang_short = "C"
|
||||
|
||||
_lang_to_parser = {
|
||||
'C' : DateParser.DateParser,
|
||||
'en_US' : DateParser.DateParser,
|
||||
'en_GB' : DateParser.DateParser,
|
||||
'en_AU' : DateParser.DateParser,
|
||||
'en_CA' : DateParser.DateParser,
|
||||
'en_SE' : DateParser.DateParser,
|
||||
'en' : DateParser.DateParser,
|
||||
}
|
||||
|
||||
_lang_to_display = {
|
||||
'C' : DateDisplay.DateDisplayEn,
|
||||
'en_US' : DateDisplay.DateDisplayEn,
|
||||
'en_GB' : DateDisplay.DateDisplayEn,
|
||||
'en_AU' : DateDisplay.DateDisplayEn,
|
||||
'en_CA' : DateDisplay.DateDisplayEn,
|
||||
'en_SE' : DateDisplay.DateDisplayEn,
|
||||
'en' : DateDisplay.DateDisplayEn,
|
||||
'zh_CN' : DateDisplay.DateDisplay,
|
||||
'zh_TW' : DateDisplay.DateDisplay,
|
||||
@ -123,7 +117,10 @@ load_plugins(datesDir)
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
try:
|
||||
parser = _lang_to_parser[_lang]()
|
||||
if _lang_to_parser.has_key(_lang):
|
||||
parser = _lang_to_parser[_lang]
|
||||
else:
|
||||
parser = _lang_to_parser[_lang_short]
|
||||
except:
|
||||
print "Date parser for",_lang,"not available, using default"
|
||||
parser = _lang_to_parser["C"]()
|
||||
@ -138,7 +135,11 @@ except:
|
||||
val = 0
|
||||
|
||||
try:
|
||||
displayer = _lang_to_display[_lang](val)
|
||||
if _lang_to_display.has_key(_lang):
|
||||
displayer = _lang_to_display[_lang](val)
|
||||
else:
|
||||
displayer = _lang_to_display[_lang_short](val)
|
||||
except:
|
||||
print "Date displayer for",_lang,"not available, using default"
|
||||
displayer = _lang_to_display["C"](val)
|
||||
|
||||
|
@ -257,9 +257,9 @@ class DateParser:
|
||||
re.IGNORECASE)
|
||||
self._qual = re.compile("%s\s+(.+)" % self._qual_str,
|
||||
re.IGNORECASE)
|
||||
self._span = re.compile("(from)\s+(.+)\s+(to)\s+(.+)",
|
||||
self._span = re.compile("(from)\s+(?P<start>.+)\s+to\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(bet|bet.|between)\s+(.+)\s+(and)\s+(.+)",
|
||||
self._range = re.compile("(bet|bet.|between)\s+(?P<start>.+)\s+and\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
self._modifier = re.compile('%s\s+(.*)' % self._mod_str,
|
||||
re.IGNORECASE)
|
||||
@ -452,10 +452,9 @@ class DateParser:
|
||||
"""
|
||||
match = self._span.match(text)
|
||||
if match:
|
||||
grps = match.groups()
|
||||
text_parser = self.parser[cal]
|
||||
start = self._parse_subdate(grps[1],text_parser)
|
||||
stop = self._parse_subdate(grps[3],text_parser)
|
||||
start = self._parse_subdate(match.group('start'),text_parser)
|
||||
stop = self._parse_subdate(match.group('stop'),text_parser)
|
||||
date.set(qual,Date.MOD_SPAN,cal,start + stop)
|
||||
return 1
|
||||
return 0
|
||||
@ -468,10 +467,9 @@ class DateParser:
|
||||
"""
|
||||
match = self._range.match(text)
|
||||
if match:
|
||||
grps = match.groups()
|
||||
text_parser = self.parser[cal]
|
||||
start = self._parse_subdate(grps[1],text_parser)
|
||||
stop = self._parse_subdate(grps[3],text_parser)
|
||||
start = self._parse_subdate(match.group('start'),text_parser)
|
||||
stop = self._parse_subdate(match.group('stop'),text_parser)
|
||||
date.set(qual,Date.MOD_RANGE,cal,start + stop)
|
||||
return 1
|
||||
return 0
|
||||
|
@ -193,17 +193,19 @@ class ExistingDbPrompter:
|
||||
filetype = get_mime_type(filename)
|
||||
(the_path,the_file) = os.path.split(filename)
|
||||
choose.destroy()
|
||||
try:
|
||||
if open_native(self.parent,filename,filetype):
|
||||
return True
|
||||
except db.DBInvalidArgError, msg:
|
||||
QuestionDialog.ErrorDialog(
|
||||
_("Could not open file: %s") % filename, msg[1])
|
||||
return False
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
return False
|
||||
if filetype in [const.app_gramps,const.app_gramps_xml,
|
||||
const.app_gedcom]:
|
||||
|
||||
try:
|
||||
return open_native(self.parent,filename,filetype)
|
||||
except db.DBInvalidArgError, msg:
|
||||
QuestionDialog.ErrorDialog(
|
||||
_("Could not open file: %s") % filename, msg[1])
|
||||
return False
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
return False
|
||||
|
||||
# The above native formats did not work, so we need to
|
||||
# look up the importer for this format
|
||||
@ -472,7 +474,8 @@ class NewSaveasDbPrompter:
|
||||
continue
|
||||
filetype = type_selector.get_value()
|
||||
if filetype == 'auto':
|
||||
os.system('touch %s' % filename)
|
||||
new_file = open(filename, "w")
|
||||
new_file.close()
|
||||
filetype = get_mime_type(filename)
|
||||
(the_path,the_file) = os.path.split(filename)
|
||||
choose.destroy()
|
||||
@ -531,17 +534,14 @@ def open_native(parent,filename,filetype):
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration()
|
||||
|
||||
parent.read_file(filename,update_msg)
|
||||
success = parent.read_file(filename,update_msg)
|
||||
msg_top.destroy()
|
||||
success = True
|
||||
elif filetype == const.app_gramps_xml:
|
||||
parent.db = GrampsXMLDB.GrampsXMLDB()
|
||||
parent.read_file(filename)
|
||||
success = True
|
||||
success = parent.read_file(filename)
|
||||
elif filetype == const.app_gedcom:
|
||||
parent.db = GrampsGEDDB.GrampsGEDDB()
|
||||
parent.read_file(filename)
|
||||
success = True
|
||||
success = parent.read_file(filename)
|
||||
|
||||
if success:
|
||||
# Add the file to the recent items
|
||||
|
@ -537,7 +537,8 @@ class EditPerson:
|
||||
cursor = self.db.get_place_cursor()
|
||||
data = cursor.next()
|
||||
while data:
|
||||
self.pdmap[data[1][2]] = data[0]
|
||||
if data[1][2]:
|
||||
self.pdmap[data[1][2]] = data[0]
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
@ -620,7 +621,7 @@ class EditPerson:
|
||||
self.close_child_windows()
|
||||
self.remove_itself_from_winsmenu()
|
||||
self.window.destroy()
|
||||
|
||||
|
||||
def add_itself_to_winsmenu(self):
|
||||
self.parent.child_windows[self.orig_handle] = self
|
||||
win_menu_label = self.name_display.display(self.person)
|
||||
|
@ -61,21 +61,22 @@ class EditPlace:
|
||||
|
||||
def __init__(self,parent,place,parent_window=None):
|
||||
self.parent = parent
|
||||
if place.get_handle():
|
||||
if place and place.get_handle():
|
||||
if self.parent.child_windows.has_key(place.get_handle()):
|
||||
self.parent.child_windows[place.get_handle()].present(None)
|
||||
return
|
||||
else:
|
||||
self.win_key = place.get_handle()
|
||||
self.ref_not_loaded = 1
|
||||
else:
|
||||
self.win_key = self
|
||||
self.ref_not_loaded = 0
|
||||
self.name_display = NameDisplay.displayer.display
|
||||
self.place = place
|
||||
self.db = parent.db
|
||||
self.child_windows = {}
|
||||
self.path = parent.db.get_save_path()
|
||||
self.not_loaded = 1
|
||||
self.ref_not_loaded = 1
|
||||
self.lists_changed = 0
|
||||
if place:
|
||||
self.srcreflist = place.get_source_references()
|
||||
@ -237,12 +238,15 @@ class EditPlace:
|
||||
|
||||
self.redraw_url_list()
|
||||
self.redraw_location_list()
|
||||
self.display_references()
|
||||
if parent_window:
|
||||
self.top.set_transient_for(parent_window)
|
||||
self.add_itself_to_menu()
|
||||
self.top_window.get_widget('ok').set_sensitive(not self.db.readonly)
|
||||
self.top.show()
|
||||
if self.ref_not_loaded:
|
||||
Utils.temp_label(self.refs_label,self.top)
|
||||
gobject.idle_add(self.display_references)
|
||||
self.ref_not_loaded = 0
|
||||
|
||||
def on_delete_event(self,obj,b):
|
||||
self.glry.close()
|
||||
@ -407,7 +411,8 @@ class EditPlace:
|
||||
self.glry.load_images()
|
||||
elif page == 6 and self.ref_not_loaded:
|
||||
self.ref_not_loaded = 0
|
||||
self.display_references()
|
||||
Utils.temp_label(self.refs_label,self.top)
|
||||
gobject.idle_add(self.display_references)
|
||||
text = unicode(self.note_buffer.get_text(self.note_buffer.get_start_iter(),
|
||||
self.note_buffer.get_end_iter(),False))
|
||||
if text:
|
||||
@ -544,9 +549,9 @@ class EditPlace:
|
||||
|
||||
self.refinfo.get_buffer().set_text(msg)
|
||||
if any:
|
||||
Utils.bold_label(self.refs_label)
|
||||
|
||||
self.ref_not_loaded = 0
|
||||
Utils.bold_label(self.refs_label,self.top)
|
||||
else:
|
||||
Utils.unbold_label(self.refs_label,self.top)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -577,9 +582,9 @@ class DeletePlaceQuery:
|
||||
|
||||
def query_response(self):
|
||||
trans = self.db.transaction_begin()
|
||||
self.db.disable_signals()
|
||||
|
||||
place_handle = self.place.get_handle()
|
||||
self.db.remove_place(place_handle,trans)
|
||||
|
||||
for handle in self.db.get_person_handles(sort_handles=False):
|
||||
person = self.db.get_person_from_handle(handle)
|
||||
@ -599,5 +604,7 @@ class DeletePlaceQuery:
|
||||
event.remove_handle_references('Place',place_handle)
|
||||
self.db.commit_event(event,trans)
|
||||
|
||||
self.db.enable_signals()
|
||||
self.db.remove_place(place_handle,trans)
|
||||
self.db.transaction_commit(trans,
|
||||
_("Delete Place (%s)") % self.place.get_title())
|
||||
|
@ -32,6 +32,7 @@ from gettext import gettext as _
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gobject
|
||||
import gtk.glade
|
||||
import gnome
|
||||
|
||||
@ -60,6 +61,10 @@ class EditSource:
|
||||
self.source = source
|
||||
else:
|
||||
self.source = RelLib.Source()
|
||||
if self.source.get_handle():
|
||||
self.ref_not_loaded = 1
|
||||
else:
|
||||
self.ref_not_loaded = 0
|
||||
self.db = db
|
||||
self.parent = parent
|
||||
self.name_display = NameDisplay.displayer.display
|
||||
@ -74,7 +79,6 @@ class EditSource:
|
||||
self.child_windows = {}
|
||||
self.path = db.get_save_path()
|
||||
self.not_loaded = 1
|
||||
self.ref_not_loaded = 1
|
||||
self.lists_changed = 0
|
||||
self.gallery_ok = 0
|
||||
mode = not self.db.readonly
|
||||
@ -180,11 +184,14 @@ class EditSource:
|
||||
|
||||
self.top_window.get_widget('ok').set_sensitive(not self.db.readonly)
|
||||
|
||||
self.display_references()
|
||||
if parent_window:
|
||||
self.top.set_transient_for(parent_window)
|
||||
self.add_itself_to_menu()
|
||||
self.top.show()
|
||||
if self.ref_not_loaded:
|
||||
self.ref_not_loaded = 0
|
||||
Utils.temp_label(self.refs_label,self.top)
|
||||
gobject.idle_add(self.display_references)
|
||||
self.data_sel = self.datalist.get_selection()
|
||||
|
||||
def on_add_data_clicked(self,widget):
|
||||
@ -343,9 +350,9 @@ class EditSource:
|
||||
self.model.add([_("Media"),gramps_id,name],(5,handle))
|
||||
|
||||
if any:
|
||||
Utils.bold_label(self.refs_label)
|
||||
Utils.bold_label(self.refs_label,self.top)
|
||||
else:
|
||||
Utils.unbold_label(self.refs_label)
|
||||
Utils.unbold_label(self.refs_label,self.top)
|
||||
|
||||
self.ref_not_loaded = 0
|
||||
|
||||
@ -403,7 +410,8 @@ class EditSource:
|
||||
self.gallery.load_images()
|
||||
elif page == 3 and self.ref_not_loaded:
|
||||
self.ref_not_loaded = 0
|
||||
self.display_references()
|
||||
Utils.temp_label(self.refs_label,self.top)
|
||||
gobject.idle_add(self.display_references)
|
||||
text = unicode(self.notes_buffer.get_text(self.notes_buffer.get_start_iter(),
|
||||
self.notes_buffer.get_end_iter(),False))
|
||||
if text:
|
||||
@ -420,6 +428,7 @@ class DelSrcQuery:
|
||||
|
||||
def query_response(self):
|
||||
trans = self.db.transaction_begin()
|
||||
self.db.disable_signals()
|
||||
|
||||
(person_list,family_list,event_list,
|
||||
place_list,source_list,media_list) = self.the_lists
|
||||
@ -456,6 +465,7 @@ class DelSrcQuery:
|
||||
media.remove_source_references(src_handle_list)
|
||||
self.db.commit_media_object(media,trans)
|
||||
|
||||
self.db.enable_signals()
|
||||
self.db.remove_source(self.source.get_handle(),trans)
|
||||
self.db.transaction_commit(
|
||||
trans,_("Delete Source (%s)") % self.source.get_title())
|
||||
|
@ -90,3 +90,15 @@ class GConfSchemaError(Exception):
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
class FileVersionError(Exception):
|
||||
"""
|
||||
Error used to report that a file could not be read because
|
||||
it is written in an unsupported version of the file format.
|
||||
"""
|
||||
def __init__(self,value):
|
||||
Exception.__init__(self)
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
@ -790,6 +790,7 @@ class FamilyView:
|
||||
self.parent.db.commit_family(family,trans)
|
||||
self.parent.db.commit_person(person,trans)
|
||||
|
||||
# TODO: Add child ordered by birth day
|
||||
family.add_child_handle(new_person.get_handle())
|
||||
new_person.add_parent_family_handle(family.get_handle(),
|
||||
RelLib.Person.CHILD_REL_BIRTH,
|
||||
@ -1467,11 +1468,15 @@ class FamilyView:
|
||||
src = spath[0]
|
||||
child_list = self.family.get_child_handle_list()
|
||||
|
||||
# Check if the children were in order before the attempt to reorder
|
||||
was_ordered = self.birth_dates_in_order(child_list)
|
||||
|
||||
obj = child_list[src]
|
||||
child_list.remove(obj)
|
||||
child_list.insert(row,obj)
|
||||
|
||||
if self.birth_dates_in_order(child_list) == 0:
|
||||
# abort if a valid order was attempt to destroy
|
||||
if was_ordered and self.birth_dates_in_order(child_list) == False:
|
||||
WarningDialog(_("Attempt to Reorder Children Failed"),
|
||||
_("Children must be ordered by their birth dates."))
|
||||
return
|
||||
|
@ -111,6 +111,9 @@ class GrampsBSDDB(GrampsDbBase):
|
||||
def get_media_cursor(self):
|
||||
return GrampsBSDDBCursor(self.media_map)
|
||||
|
||||
def version_supported(self):
|
||||
return self.metadata.get('version',0) <= _DBVERSION
|
||||
|
||||
def need_upgrade(self):
|
||||
return not self.readonly and self.metadata.get('version',0) < _DBVERSION
|
||||
|
||||
@ -407,6 +410,7 @@ class GrampsBSDDB(GrampsDbBase):
|
||||
"Sponsored", "Foster", "Unknown", "Other", ]
|
||||
|
||||
version = self.metadata.get('version',0)
|
||||
|
||||
if version < 2:
|
||||
self.upgrade_2(child_rel_notrans)
|
||||
if version < 3:
|
||||
|
@ -191,6 +191,10 @@ class GrampsDbBase(GrampsDBCallback.GrampsDBCallback):
|
||||
self.place2title = {}
|
||||
self.name_group = {}
|
||||
|
||||
def version_supported(self):
|
||||
""" Returns True when the file has a supported version"""
|
||||
return True
|
||||
|
||||
def need_upgrade(self):
|
||||
return False
|
||||
|
||||
|
@ -892,14 +892,16 @@ class GlobalMediaProperties:
|
||||
self.win_key = self
|
||||
self.child_windows = {}
|
||||
self.obj = obj
|
||||
self.alist = self.obj.get_attribute_list()[:]
|
||||
self.lists_changed = 0
|
||||
self.db = db
|
||||
self.refs = 0
|
||||
if obj:
|
||||
self.date_object = Date.Date(self.obj.get_date_object())
|
||||
self.alist = self.obj.get_attribute_list()[:]
|
||||
self.refs = 0
|
||||
else:
|
||||
self.date_object = Date.Date()
|
||||
self.alist = []
|
||||
self.refs = 1
|
||||
|
||||
self.path = self.db.get_save_path()
|
||||
self.change_dialog = gtk.glade.XML(const.imageselFile,
|
||||
@ -1012,11 +1014,13 @@ class GlobalMediaProperties:
|
||||
self.change_dialog.get_widget(name).set_sensitive(mode)
|
||||
|
||||
self.redraw_attr_list()
|
||||
self.display_refs()
|
||||
if parent_window:
|
||||
self.window.set_transient_for(parent_window)
|
||||
self.add_itself_to_menu()
|
||||
self.window.show()
|
||||
if not self.refs:
|
||||
Utils.temp_label(self.refs_label,self.window)
|
||||
gobject.idle_add(self.display_refs)
|
||||
|
||||
def on_delete_event(self,obj,b):
|
||||
self.close_child_windows()
|
||||
@ -1090,8 +1094,6 @@ class GlobalMediaProperties:
|
||||
return
|
||||
|
||||
def display_refs(self):
|
||||
if self.refs == 1:
|
||||
return
|
||||
self.refs = 1
|
||||
|
||||
(person_list,family_list,event_list,place_list,source_list
|
||||
@ -1135,13 +1137,14 @@ class GlobalMediaProperties:
|
||||
self.refmodel.add([_("Source"),gramps_id,name])
|
||||
|
||||
if any:
|
||||
Utils.bold_label(self.refs_label)
|
||||
Utils.bold_label(self.refs_label,self.window)
|
||||
else:
|
||||
Utils.unbold_label(self.refs_label)
|
||||
Utils.unbold_label(self.refs_label,self.window)
|
||||
|
||||
def on_notebook_switch_page(self,obj,junk,page):
|
||||
if page == 3:
|
||||
self.display_refs()
|
||||
if page == 3 and not self.refs:
|
||||
Utils.temp_label(self.refs_label,self.window)
|
||||
gobject.idle_add(self.display_refs)
|
||||
t = self.notes.get_buffer()
|
||||
text = unicode(t.get_text(t.get_start_iter(),t.get_end_iter(),False))
|
||||
if text:
|
||||
@ -1243,6 +1246,7 @@ class DeleteMediaQuery:
|
||||
|
||||
def query_response(self):
|
||||
trans = self.db.transaction_begin()
|
||||
self.db.disable_signals()
|
||||
|
||||
(person_list,family_list,event_list,
|
||||
place_list,source_list) = self.the_lists
|
||||
@ -1282,6 +1286,7 @@ class DeleteMediaQuery:
|
||||
source.set_media_list(new_list)
|
||||
self.db.commit_source(source,trans)
|
||||
|
||||
self.db.enable_signals()
|
||||
self.db.remove_object(self.media_handle,trans)
|
||||
self.db.transaction_commit(trans,_("Remove Media Object"))
|
||||
|
||||
|
@ -291,17 +291,64 @@ class MergePeople:
|
||||
for h,m1,m2 in person.get_parent_family_handle_list():
|
||||
print " - parent family %s" % h
|
||||
|
||||
def merge(self):
|
||||
"""
|
||||
Perform the actual merge. A new person is created to store the
|
||||
merged data. First, the person information is merged. This is a
|
||||
very straight forward process. Second, the families associated
|
||||
with the merged people must be modified to handle the family
|
||||
information. This process can be tricky.
|
||||
|
||||
Finally, the merged person is delete from the database and the
|
||||
entire transaction is committed.
|
||||
"""
|
||||
self.debug_person(self.p1, "P1")
|
||||
self.debug_person(self.p2, "P2")
|
||||
|
||||
new = RelLib.Person()
|
||||
trans = self.db.transaction_begin()
|
||||
|
||||
self.merge_person_information(new,trans)
|
||||
self.merge_family_information(new,trans)
|
||||
self.db.commit_person(new,trans)
|
||||
self.debug_person(new, "NEW")
|
||||
self.db.remove_person(self.old_handle,trans)
|
||||
self.db.transaction_commit(trans,"Merge Person")
|
||||
|
||||
def merge_person_information(self,new,trans):
|
||||
"""
|
||||
Merging the person's individual information is pretty simple. The
|
||||
person 'new' is a new, empty person. The data is loaded in this
|
||||
new person. The idea is that all information that can possibly be
|
||||
preserved is preserved.
|
||||
"""
|
||||
self.old_handle = self.p2.get_handle()
|
||||
self.new_handle = self.p1.get_handle()
|
||||
|
||||
|
||||
# Choose the handle from the target person. Since this is internal
|
||||
# only information, no user visible information is lost.
|
||||
new.set_handle(self.new_handle)
|
||||
|
||||
# The gender is chosen from the primary person. This is one case
|
||||
# where data may be lost if you merge the data from two people of
|
||||
# opposite genders.
|
||||
new.set_gender(self.p1.get_gender())
|
||||
|
||||
# copy the GRAMPS Ids
|
||||
self.merge_gramps_ids(new)
|
||||
|
||||
# copy names
|
||||
self.merge_names(new)
|
||||
|
||||
# copy the birth event
|
||||
self.merge_birth(new,trans)
|
||||
|
||||
# copy the death event
|
||||
self.merge_death(new,trans)
|
||||
|
||||
# merge the event lists
|
||||
self.merge_event_lists(new)
|
||||
|
||||
# copy attributes
|
||||
new.set_attribute_list(self.p1.get_attribute_list() +
|
||||
self.p2.get_attribute_list())
|
||||
@ -325,80 +372,346 @@ class MergePeople:
|
||||
for photo in self.p2.get_media_list():
|
||||
new.add_media_reference(photo)
|
||||
|
||||
|
||||
# note
|
||||
note1 = self.p1.get_note_object()
|
||||
note2 = self.p2.get_note_object()
|
||||
new.set_note_object(self.merge_notes(note1,note2))
|
||||
|
||||
def merge(self):
|
||||
def merge_gramps_ids(self,new):
|
||||
"""
|
||||
Merges the GRAMPS IDs. The new GRAMPS ID is taken from
|
||||
destination person. The GRAMPS ID of the other person is added
|
||||
to the merged person as an attribute.
|
||||
"""
|
||||
# copy of GRAMPS ID as an attribute
|
||||
attr = RelLib.Attribute()
|
||||
attr.set_type('Merged GRAMPS ID')
|
||||
attr.set_value(self.p2.get_gramps_id())
|
||||
new.add_attribute(attr)
|
||||
|
||||
self.debug_person(self.p1, "P1")
|
||||
self.debug_person(self.p2, "P2")
|
||||
new = RelLib.Person()
|
||||
trans = self.db.transaction_begin()
|
||||
# store GRAMPS ID of the destination person
|
||||
new.set_gramps_id(self.p1.get_gramps_id())
|
||||
|
||||
self.merge_person_information(new,trans)
|
||||
self.merge_family_information(new,trans)
|
||||
self.db.commit_person(new,trans)
|
||||
self.debug_person(new, "NEW")
|
||||
self.db.remove_person(self.old_handle,trans)
|
||||
self.db.transaction_commit(trans,"Merge Person")
|
||||
def merge_names(self, new):
|
||||
"""
|
||||
Merges the names of the two people into the destination. The
|
||||
primary name of the destination person is kept as the primary
|
||||
name.
|
||||
|
||||
def convert_child_ids(self, family_id, id1, id2, trans):
|
||||
new_list = []
|
||||
change = False
|
||||
family = self.db.get_family_from_handle(family_id)
|
||||
The other person's name is stored as an alternate name if it is
|
||||
not entirely identical to the destination person's primary name.
|
||||
|
||||
for child_id in family.get_child_handle_list():
|
||||
if child_id == id2:
|
||||
if id1 not in new_list:
|
||||
new_list.append(id1)
|
||||
change = True
|
||||
elif child_id not in new_list:
|
||||
new_list.append(child_id)
|
||||
#if change:
|
||||
family.set_child_handle_list(new_list)
|
||||
self.db.commit_family(family,trans)
|
||||
|
||||
In the current implementation, If only one person has a
|
||||
nickname, it is assigned as the merged person's nickname. If
|
||||
both people have nicknames, then the nickname of the second
|
||||
person is lost.
|
||||
|
||||
Remaining alternate names are then added to the merged
|
||||
person's alternate names.
|
||||
"""
|
||||
p1_name = self.p1.get_primary_name()
|
||||
p2_name = self.p2.get_primary_name()
|
||||
|
||||
new.set_primary_name(self.p1.get_primary_name())
|
||||
if not p2_name.is_equal(p1_name):
|
||||
new.add_alternate_name(p2_name)
|
||||
|
||||
if self.p1.get_nick_name() == "":
|
||||
new.set_nick_name(self.p2.get_nick_name())
|
||||
else:
|
||||
new.set_nick_name(self.p1.get_nick_name())
|
||||
|
||||
for name in self.p1.get_alternate_names():
|
||||
new.add_alternate_name(name)
|
||||
for name in self.p2.get_alternate_names():
|
||||
new.add_alternate_name(name)
|
||||
|
||||
def merge_birth(self, new,trans):
|
||||
"""
|
||||
Merges the birth events of the two people. If the primary
|
||||
person does not have a birth event, then the birth event from
|
||||
the secodnary person is selected. If the primary person has
|
||||
a birth date, then the merged person gets the primary person's
|
||||
birth event, and the secondary person's birth event is added
|
||||
as a 'Alternate Birth' event.
|
||||
"""
|
||||
handle1 = self.p1.get_birth_handle()
|
||||
handle2 = self.p2.get_birth_handle()
|
||||
|
||||
if handle1:
|
||||
new.set_birth_handle(handle1)
|
||||
if handle2:
|
||||
event = self.db.get_event_from_handle(handle2)
|
||||
event.set_name('Alternate Birth')
|
||||
self.db.add_event(event,trans)
|
||||
new.add_event_handle(event.get_handle())
|
||||
elif not handle1 and handle2:
|
||||
new.set_birth_handle(handle2)
|
||||
|
||||
def merge_death(self, new, trans):
|
||||
"""
|
||||
Merges the death events of the two people. If the primary
|
||||
person does not have a death event, then the death event from
|
||||
the secodnary person is selected. If the primary person has
|
||||
a death date, then the merged person gets the primary person's
|
||||
death event, and the secondary person's death event is added
|
||||
as a 'Alternate Death' event.
|
||||
"""
|
||||
handle1 = self.p1.get_death_handle()
|
||||
handle2 = self.p2.get_death_handle()
|
||||
|
||||
if handle1:
|
||||
new.set_death_handle(handle1)
|
||||
if handle2:
|
||||
event = self.db.get_event_from_handle(handle2)
|
||||
event.set_handle(Utils.create_id())
|
||||
event.set_name('Alternate Death')
|
||||
new.add_event_handle(event.get_handle())
|
||||
self.db.add_event(event,trans)
|
||||
elif not handle1 and handle2:
|
||||
new.set_death_handle(handle2)
|
||||
|
||||
def merge_event_lists(self, new):
|
||||
"""
|
||||
Merges the events from the two people into the destination
|
||||
person. Duplicates are not transferred.
|
||||
"""
|
||||
data_list = new.get_event_list()
|
||||
for handle in self.p1.get_event_list():
|
||||
if handle not in data_list:
|
||||
data_list.append(handle)
|
||||
for handle in self.p2.get_event_list():
|
||||
if handle not in data_list:
|
||||
data_list.append(handle)
|
||||
new.set_event_list(data_list)
|
||||
|
||||
def merge_family_information(self, new, trans):
|
||||
"""
|
||||
Merge the parent families and the relationship families of the
|
||||
selected people.
|
||||
"""
|
||||
self.merge_parents(new, trans)
|
||||
self.merge_relationships(new, trans)
|
||||
|
||||
def merge_parents(self, new, trans):
|
||||
f1_list = self.p1.get_parent_family_handle_list()
|
||||
f2_list = self.p2.get_parent_family_handle_list()
|
||||
"""
|
||||
Merging the parent list is not too difficult. We grab the
|
||||
parent list of the destination person. We then loop through
|
||||
the parent list of the secondary person, adding to the parent
|
||||
list any parents that are not already there. This eliminates
|
||||
any duplicates.
|
||||
|
||||
parent_list = f1_list
|
||||
Once this has been completed, we loop through each family,
|
||||
converting any child handles referring to the secondary person
|
||||
to the destination person.
|
||||
"""
|
||||
parent_list = self.p1.get_parent_family_handle_list()
|
||||
|
||||
for fid in f2_list:
|
||||
# copy handles of families that are not common between the
|
||||
# two lists
|
||||
for fid in self.p2.get_parent_family_handle_list():
|
||||
if fid not in parent_list:
|
||||
parent_list.append(fid)
|
||||
for fid in parent_list:
|
||||
self.convert_child_ids(fid[0], self.new_handle, self.old_handle, trans)
|
||||
new.add_parent_family_handle(fid[0],fid[1],fid[2])
|
||||
|
||||
def merge_family_information(self, new, trans):
|
||||
self.merge_parents(new, trans)
|
||||
self.merge_families(new, trans)
|
||||
|
||||
def find_family(self,family):
|
||||
if __debug__:
|
||||
print "SourceFamily: %s" % family.get_handle()
|
||||
if self.p1.get_gender() == RelLib.Person.MALE:
|
||||
mother_handle = family.get_mother_handle()
|
||||
father_handle = self.p1.get_handle()
|
||||
else:
|
||||
father_handle = family.get_father_handle()
|
||||
mother_handle = self.p1.get_handle()
|
||||
|
||||
for myfamily_handle in self.db.get_family_handles():
|
||||
myfamily = self.db.get_family_from_handle(myfamily_handle)
|
||||
if (myfamily.get_father_handle() == father_handle and
|
||||
myfamily.get_mother_handle() == mother_handle and
|
||||
myfamily_handle != family.get_handle()):
|
||||
# loop through the combined list, converting the child handles
|
||||
# of the families, and adding the families to the merged
|
||||
# person
|
||||
|
||||
for (family_handle,mrel,frel) in parent_list:
|
||||
self.convert_child_ids(family_handle, self.new_handle,
|
||||
self.old_handle, trans)
|
||||
new.add_parent_family_handle(family_handle, mrel, frel)
|
||||
|
||||
def convert_child_ids(self, fhandle, new_handle, old_handle, trans):
|
||||
"""
|
||||
Search the family associated with fhandle, and replace all
|
||||
child handles that match old_handle with new_handle.
|
||||
"""
|
||||
family = self.db.get_family_from_handle(fhandle)
|
||||
new_child_list = []
|
||||
orig_list = family.get_child_handle_list()
|
||||
|
||||
# loop through original child list. If a handle matches the
|
||||
# old handle, replace it with the new handle if the new handle
|
||||
# is not already in the list
|
||||
for child_id in orig_list:
|
||||
if child_id == old_handle:
|
||||
if new_handle not in new_child_list:
|
||||
new_child_list.append(new_handle)
|
||||
elif child_id not in new_child_list:
|
||||
new_child_list.append(child_id)
|
||||
|
||||
# compare the new list with the original list. If this list
|
||||
# is different, we need to save the changes to the database.
|
||||
if new_child_list != orig_list:
|
||||
family.set_child_handle_list(new_child_list)
|
||||
self.db.commit_family(family,trans)
|
||||
|
||||
def merge_relationships(self,new,trans):
|
||||
"""
|
||||
Merges the relationships associated with the merged people.
|
||||
"""
|
||||
|
||||
family_num = 0
|
||||
family_list = self.p1.get_family_handle_list()
|
||||
|
||||
for src_handle in self.p2.get_family_handle_list():
|
||||
|
||||
src_family = self.db.get_family_from_handle(src_handle)
|
||||
family_num += 1
|
||||
|
||||
if not src_family or src_family in family_list:
|
||||
continue
|
||||
|
||||
tgt_family = self.find_modified_family(src_family)
|
||||
|
||||
# existing family is found
|
||||
if tgt_family:
|
||||
# The target family is already a family in the person's
|
||||
# family list.
|
||||
if tgt_family.get_handle() in self.p1.get_family_handle_list():
|
||||
self.merge_existing_family(new, src_family, tgt_family, trans)
|
||||
continue
|
||||
|
||||
# This is the case the family is not already in the person's
|
||||
# family list.
|
||||
else:
|
||||
self.merge_family_pair(tgt_family,src_family,trans)
|
||||
|
||||
# change parents of the family to point to the new
|
||||
# family
|
||||
self.adjust_family_pointers(tgt_family, src_family, trans)
|
||||
|
||||
new.remove_family_handle(src_handle)
|
||||
self.db.remove_family(src_handle,trans)
|
||||
if __debug__:
|
||||
print "Deleted src_family %s" % src_handle
|
||||
else:
|
||||
for fid in self.p1.get_family_handle_list():
|
||||
if fid not in new.get_family_handle_list():
|
||||
new.add_family_handle(fid)
|
||||
|
||||
if src_handle in new.get_family_handle_list():
|
||||
continue
|
||||
src_family = self.db.get_family_from_handle(src_handle)
|
||||
new.add_family_handle(src_handle)
|
||||
if src_family.get_father_handle() == self.old_handle:
|
||||
src_family.set_father_handle(self.new_handle)
|
||||
if __debug__:
|
||||
print "TargetFamily: %s" % myfamily.get_handle()
|
||||
return myfamily
|
||||
print "Family %s now has father %s" % (
|
||||
src_handle, self.new_handle)
|
||||
if src_family.get_mother_handle() == self.old_handle:
|
||||
src_family.set_mother_handle(self.new_handle)
|
||||
if __debug__:
|
||||
print "Family %s now has mother %s" % (
|
||||
src_handle, self.new_handle)
|
||||
self.db.commit_family(src_family,trans)
|
||||
|
||||
# a little debugging here
|
||||
|
||||
cursor = self.db.get_family_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
fam = RelLib.Family()
|
||||
fam.unserialize(data[1])
|
||||
if self.p2 in fam.get_child_handle_list():
|
||||
fam.remove_child_handle(self.p2)
|
||||
fam.add_child_handle(self.p1)
|
||||
if self.p2 == fam.get_father_handle():
|
||||
fam.set_father_handle(self.p1)
|
||||
if self.p2 == fam.get_mother_handle():
|
||||
fam.set_mother_handle(self.p1)
|
||||
if fam.get_father_handle() == None and fam.get_mother_handle() == None:
|
||||
self.delete_empty_family(fam,trans)
|
||||
data = cursor.next()
|
||||
|
||||
def find_modified_family(self,family):
|
||||
"""
|
||||
Look for a existing family that matches the merged person. This means
|
||||
looking at the current family, and replacing the secondary person's
|
||||
handle with the merged person's handle. Search the family table for
|
||||
a family that matches this new mother/father pair.
|
||||
|
||||
If no family is found, return None
|
||||
"""
|
||||
|
||||
family_handle = family.get_handle()
|
||||
|
||||
if __debug__:
|
||||
print "TargetFamily: None"
|
||||
return None
|
||||
print "SourceFamily: %s" % family_handle
|
||||
|
||||
# Determine the mother and father handles for the search.
|
||||
# This is determined by replacing the secodnary person's
|
||||
# handle with the primary person's handle in the mother/father
|
||||
# pair.
|
||||
|
||||
mhandle = family.get_mother_handle()
|
||||
if mhandle == self.old_handle:
|
||||
mhandle = self.new_handle
|
||||
|
||||
fhandle = family.get_father_handle()
|
||||
if fhandle == self.old_handle:
|
||||
fhandle = self.new_handle
|
||||
|
||||
# loop through the families using a cursor. Check the handles
|
||||
# for a mother/father match.
|
||||
|
||||
cursor = self.db.get_family_cursor()
|
||||
node = cursor.next()
|
||||
myfamily = None
|
||||
while node:
|
||||
# data[2] == father_handle field, data[2] == mother_handle field
|
||||
(thandle,data) = node
|
||||
if data[2] == fhandle and data[3] == mhandle and thandle != family_handle:
|
||||
myfamily = RelLib.Family()
|
||||
myfamily.unserialize(data)
|
||||
break
|
||||
node = cursor.next()
|
||||
|
||||
if __debug__:
|
||||
if myfamily:
|
||||
print "TargetFamily: %s" % myfamily.get_handle()
|
||||
else:
|
||||
print "TargetFamily: None"
|
||||
|
||||
cursor.close()
|
||||
return myfamily
|
||||
|
||||
def merge_existing_family(self, new, src_family, tgt_family, trans):
|
||||
|
||||
src_family_handle = src_family.get_handle()
|
||||
|
||||
father_id = tgt_family.get_father_handle()
|
||||
father = self.db.get_person_from_handle(father_id)
|
||||
|
||||
mother_id = tgt_family.get_mother_handle()
|
||||
mother = self.db.get_person_from_handle(mother_id)
|
||||
|
||||
if father and src_family_handle in father.get_family_handle_list():
|
||||
father.remove_family_handle(src_family_handle)
|
||||
if __debug__:
|
||||
print "Removed family %s from father %s" % (src_family_handle, father_id)
|
||||
self.db.commit_person(father,trans)
|
||||
if mother and src_family_handle in mother.get_family_handle_list():
|
||||
mother.remove_family_handle(src_family_handle)
|
||||
if __debug__:
|
||||
print "Removed family %s from mother %s" % (src_family_handle, mother_id)
|
||||
self.db.commit_person(mother,trans)
|
||||
|
||||
self.merge_family_pair(tgt_family,src_family,trans)
|
||||
|
||||
for child_handle in src_family.get_child_handle_list():
|
||||
if child_handle != self.new_handle:
|
||||
child = self.db.get_person_from_handle(child_handle)
|
||||
if child.remove_parent_family_handle(src_family_handle):
|
||||
self.db.commit_person(child,trans)
|
||||
|
||||
# delete the old source family
|
||||
self.db.remove_family(src_family_handle,trans)
|
||||
if __debug__:
|
||||
print "Deleted src_family %s" % src_family_handle
|
||||
self.db.commit_family(tgt_family,trans)
|
||||
new.add_family_handle(tgt_family.get_handle())
|
||||
|
||||
def merge_family_pair(self,tgt_family,src_family,trans):
|
||||
|
||||
@ -447,156 +760,48 @@ class MergePeople:
|
||||
for photo in src_family.get_media_list():
|
||||
tgt_family.add_media_reference(photo)
|
||||
|
||||
def merge_families(self,new,trans):
|
||||
def adjust_family_pointers(self, tgt_family, src_family, trans):
|
||||
"""
|
||||
Remove the people from one family and merge them into the other.
|
||||
It is not necessary to remove from the src_family, since the
|
||||
src_family is going to be removed.
|
||||
"""
|
||||
src_family_handle = src_family.get_handle()
|
||||
tgt_family_handle = tgt_family.get_handle()
|
||||
|
||||
family_num = 0
|
||||
family_list = self.p1.get_family_handle_list()
|
||||
|
||||
for src_family_handle in self.p2.get_family_handle_list():
|
||||
father_handle = src_family.get_father_handle()
|
||||
if father_handle:
|
||||
father = self.db.get_person_from_handle(father_handle)
|
||||
|
||||
src_family = self.db.get_family_from_handle(src_family_handle)
|
||||
family_num += 1
|
||||
# add to new family
|
||||
father.add_family_handle(tgt_family_handle)
|
||||
if __debug__:
|
||||
print "Added family %s to father %s" % (
|
||||
tgt_family_handle, father_handle)
|
||||
|
||||
if not src_family or src_family in family_list:
|
||||
continue
|
||||
# commit the change
|
||||
self.db.commit_person(father,trans)
|
||||
|
||||
tgt_family = self.find_family(src_family)
|
||||
mother_handle = src_family.get_mother_handle()
|
||||
if mother_handle:
|
||||
mother = self.db.get_person_from_handle(mother_handle)
|
||||
|
||||
#
|
||||
# This is the case where a new family to be added to the
|
||||
# p1 as a result of the merge already exists as a
|
||||
# family. In this case, we need to remove the old source
|
||||
# family (with the pre-merge identity of the p1) from
|
||||
# both the parents
|
||||
#
|
||||
# add to new family
|
||||
mother.add_family_handle(tgt_family_handle)
|
||||
if __debug__:
|
||||
print "Added family %s to mother %s" % (
|
||||
tgt_family_handle, mother_handle)
|
||||
|
||||
if tgt_family:
|
||||
tgt_family_handle = tgt_family.get_handle()
|
||||
if tgt_family_handle in self.p1.get_family_handle_list():
|
||||
|
||||
father_id = tgt_family.get_father_handle()
|
||||
father = self.db.get_person_from_handle(father_id)
|
||||
|
||||
mother_id = tgt_family.get_mother_handle()
|
||||
mother = self.db.get_person_from_handle(mother_id)
|
||||
# commit the change
|
||||
self.db.commit_person(mother,trans)
|
||||
|
||||
if father and src_family_handle in father.get_family_handle_list():
|
||||
father.remove_family_handle(src_family_handle)
|
||||
if __debug__:
|
||||
print "Removed family %s from father %s" % (src_family_handle, father_id)
|
||||
self.db.commit_person(father,trans)
|
||||
if mother and src_family_handle in mother.get_family_handle_list():
|
||||
mother.remove_family_handle(src_family_handle)
|
||||
if __debug__:
|
||||
print "Removed family %s from mother %s" % (src_family_handle, mother_id)
|
||||
self.db.commit_person(mother,trans)
|
||||
|
||||
self.merge_family_pair(tgt_family,src_family,trans)
|
||||
|
||||
for child_handle in src_family.get_child_handle_list():
|
||||
if child_handle != self.new_handle:
|
||||
child = self.db.get_person_from_handle(child_handle)
|
||||
if child.remove_parent_family_handle(src_family_handle):
|
||||
self.db.commit_person(child,trans)
|
||||
# remove the children from the old family
|
||||
for child_handle in src_family.get_child_handle_list():
|
||||
if child_handle != self.new_handle:
|
||||
child = self.db.get_person_from_handle(child_handle)
|
||||
if child.remove_parent_family_handle(src_family_handle):
|
||||
self.db.commit_person(child,trans)
|
||||
|
||||
# delete the old source family
|
||||
self.db.remove_family(src_family_handle,trans)
|
||||
if __debug__:
|
||||
print "Deleted src_family %s" % src_family_handle
|
||||
self.db.commit_family(tgt_family,trans)
|
||||
|
||||
new.add_family_handle(tgt_family_handle)
|
||||
|
||||
continue
|
||||
|
||||
# This is the case where a new family to be added
|
||||
# and it is not already in the list.
|
||||
|
||||
else:
|
||||
|
||||
# tgt_family a duplicate family, transfer children from
|
||||
# the p2 family, and delete the family. Not sure
|
||||
# what to do about marriage/divorce date/place yet.
|
||||
|
||||
# transfer child to new family, alter children to
|
||||
# point to the correct family
|
||||
|
||||
self.merge_family_pair(tgt_family,src_family,trans)
|
||||
|
||||
# change parents of the family to point to the new
|
||||
# family
|
||||
|
||||
father_handle = src_family.get_father_handle()
|
||||
if father_handle:
|
||||
father = self.db.get_person_from_handle(father_handle)
|
||||
father.remove_family_handle(src_family_handle)
|
||||
if __debug__:
|
||||
print "Removed family %s from father %s" % (src_family_handle, father_handle)
|
||||
father.add_family_handle(tgt_family_handle)
|
||||
if __debug__:
|
||||
print "Added family %s to father %s" % (tgt_family_handle, father_handle)
|
||||
self.db.commit_person(father,trans)
|
||||
|
||||
mother_handle = src_family.get_mother_handle()
|
||||
if mother_handle:
|
||||
mother = self.db.get_person_from_handle(mother_handle)
|
||||
mother.remove_family_handle(src_family_handle)
|
||||
if __debug__:
|
||||
print "Removed family %s from mother %s" % (src_family_handle, mother_handle)
|
||||
mother.add_family_handle(tgt_family_handle)
|
||||
if __debug__:
|
||||
print "Added family %s to mother %s" % (tgt_family_handle, mother_handle)
|
||||
self.db.commit_person(mother,trans)
|
||||
|
||||
for child_handle in src_family.get_child_handle_list():
|
||||
if child_handle != self.new_handle:
|
||||
child = self.db.get_person_from_handle(child_handle)
|
||||
if child.remove_parent_family_handle(src_family_handle):
|
||||
self.db.commit_person(child,trans)
|
||||
|
||||
new.remove_family_handle(src_family_handle)
|
||||
self.db.remove_family(src_family_handle,trans)
|
||||
if __debug__:
|
||||
print "Deleted src_family %s" % src_family_handle
|
||||
else:
|
||||
|
||||
for fid in self.p1.get_family_handle_list():
|
||||
if fid not in new.get_family_handle_list():
|
||||
new.add_family_handle(fid)
|
||||
|
||||
# for src_family_handle in self.p2.get_family_handle_list():
|
||||
if src_family_handle in new.get_family_handle_list():
|
||||
continue
|
||||
src_family = self.db.get_family_from_handle(src_family_handle)
|
||||
new.add_family_handle(src_family_handle)
|
||||
if src_family.get_father_handle() == self.old_handle:
|
||||
src_family.set_father_handle(self.new_handle)
|
||||
if __debug__:
|
||||
print "Family %s now has father %s" % (src_family_handle, self.new_handle)
|
||||
if src_family.get_mother_handle() == self.old_handle:
|
||||
src_family.set_mother_handle(self.new_handle)
|
||||
if __debug__:
|
||||
print "Family %s now has mother %s" % (src_family_handle, self.new_handle)
|
||||
self.db.commit_family(src_family,trans)
|
||||
|
||||
|
||||
# a little debugging here
|
||||
|
||||
cursor = self.db.get_family_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
fam = RelLib.Family()
|
||||
fam.unserialize(data[1])
|
||||
if self.p2 in fam.get_child_handle_list():
|
||||
fam.remove_child_handle(self.p2)
|
||||
fam.add_child_handle(self.p1)
|
||||
if self.p2 == fam.get_father_handle():
|
||||
fam.set_father_handle(self.p1)
|
||||
if self.p2 == fam.get_mother_handle():
|
||||
fam.set_mother_handle(self.p1)
|
||||
if fam.get_father_handle() == None and fam.get_mother_handle() == None:
|
||||
self.delete_empty_family(fam,trans)
|
||||
data = cursor.next()
|
||||
|
||||
def remove_marriage(self,family,person,trans):
|
||||
if person:
|
||||
@ -617,13 +822,6 @@ class MergePeople:
|
||||
if __debug__:
|
||||
print "Deleted empty family %s" % family_handle
|
||||
|
||||
def merge_gramps_ids(self,new):
|
||||
new.set_gramps_id(self.p1.get_gramps_id())
|
||||
attr = RelLib.Attribute()
|
||||
attr.set_type('Merged GRAMPS ID')
|
||||
attr.set_value(self.p2.get_gramps_id())
|
||||
new.add_attribute(attr)
|
||||
|
||||
def merge_notes(self, note1, note2):
|
||||
if note1 and not note2:
|
||||
return note1
|
||||
@ -635,49 +833,3 @@ class MergePeople:
|
||||
return note1
|
||||
return None
|
||||
|
||||
def merge_names(self, new):
|
||||
new.set_primary_name(self.p1.get_primary_name())
|
||||
new.add_alternate_name(self.p2.get_primary_name())
|
||||
if self.p1.get_nick_name() == "":
|
||||
new.set_nick_name(self.p2.get_nick_name())
|
||||
else:
|
||||
new.set_nick_name(self.p1.get_nick_name())
|
||||
|
||||
def merge_death(self, new, trans):
|
||||
handle1 = self.p1.get_death_handle()
|
||||
handle2 = self.p2.get_death_handle()
|
||||
|
||||
if handle1:
|
||||
new.set_death_handle(handle1)
|
||||
if handle2:
|
||||
event = self.db.get_event_from_handle(handle2)
|
||||
event.set_handle(Utils.create_id())
|
||||
event.set_name('Alternate Death')
|
||||
new.add_event_handle(event.get_handle())
|
||||
self.db.add_event(event,trans)
|
||||
elif not handle1 and handle2:
|
||||
new.set_death_handle(handle2)
|
||||
|
||||
def merge_birth(self, new,trans):
|
||||
handle1 = self.p1.get_birth_handle()
|
||||
handle2 = self.p2.get_birth_handle()
|
||||
|
||||
if handle1:
|
||||
new.set_birth_handle(handle1)
|
||||
if handle2:
|
||||
event = self.db.get_event_from_handle(handle2)
|
||||
event.set_name('Alternate Birth')
|
||||
self.db.add_event(event,trans)
|
||||
new.add_event_handle(event.get_handle())
|
||||
elif not handle1 and handle2:
|
||||
new.set_birth_handle(handle2)
|
||||
|
||||
def merge_event_lists(self, new):
|
||||
data_list = new.get_event_list()
|
||||
for handle in self.p1.get_event_list():
|
||||
if handle not in data_list:
|
||||
data_list.append(handle)
|
||||
for handle in self.p2.get_event_list():
|
||||
if handle not in data_list:
|
||||
data_list.append(handle)
|
||||
new.set_event_list(data_list)
|
||||
|
@ -83,7 +83,7 @@ class NameDisplay:
|
||||
@rtype: str
|
||||
"""
|
||||
name = person.get_primary_name()
|
||||
if name.display_as == RelLib.Name.FNLN:
|
||||
if name.get_sort_as() == RelLib.Name.FNLN:
|
||||
return self._fnln(name)
|
||||
else:
|
||||
return self._lnfn(name)
|
||||
|
@ -29,6 +29,7 @@ from gettext import gettext as _
|
||||
import time
|
||||
import locale
|
||||
import cgi
|
||||
import sets
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -84,6 +85,7 @@ class PeopleModel(gtk.GenericTreeModel):
|
||||
self.visible = {}
|
||||
self.top_visible = {}
|
||||
self.invert_result = invert_result
|
||||
self.sortnames = {}
|
||||
self.rebuild_data(data_filter)
|
||||
|
||||
def rebuild_data(self,data_filter=None,skip=None):
|
||||
@ -111,38 +113,44 @@ class PeopleModel(gtk.GenericTreeModel):
|
||||
else:
|
||||
keys = self.db.get_person_handles(sort_handles=False)
|
||||
|
||||
for person_handle in keys:
|
||||
if person_handle == skip:
|
||||
continue
|
||||
person = self.db.get_person_from_handle(person_handle)
|
||||
grp_as = person.get_primary_name().get_group_as()
|
||||
sn = person.get_primary_name().get_surname()
|
||||
if grp_as:
|
||||
surname = grp_as
|
||||
else:
|
||||
surname = self.db.get_name_group_mapping(sn)
|
||||
flist = sets.Set(keys)
|
||||
if skip and skip in flist:
|
||||
flist.remove(skip)
|
||||
|
||||
if self.temp_sname_sub.has_key(surname):
|
||||
self.temp_sname_sub[surname].append(person_handle)
|
||||
else:
|
||||
self.temp_sname_sub[surname] = [person_handle]
|
||||
self.sortnames = {}
|
||||
cursor = self.db.get_person_cursor()
|
||||
node = cursor.next()
|
||||
while node:
|
||||
if node[0] in flist:
|
||||
primary_name = node[1][_NAME_COL]
|
||||
if primary_name.group_as:
|
||||
surname = primary_name.group_as
|
||||
else:
|
||||
surname = self.db.get_name_group_mapping(primary_name.surname)
|
||||
self.sortnames[node[0]] = primary_name.sname
|
||||
|
||||
if self.temp_sname_sub.has_key(surname):
|
||||
self.temp_sname_sub[surname].append(node[0])
|
||||
else:
|
||||
self.temp_sname_sub[surname] = [node[0]]
|
||||
node = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
self.temp_top_path2iter = self.temp_sname_sub.keys()
|
||||
self.temp_top_path2iter.sort(locale.strcoll)
|
||||
for name in self.temp_top_path2iter:
|
||||
self.build_sub_entry(name)
|
||||
|
||||
slist = []
|
||||
for handle in self.temp_sname_sub[name]:
|
||||
n = self.db.person_map.get(handle)[_NAME_COL].get_sort_name()
|
||||
slist.append((n,handle))
|
||||
slist.sort(self.byname)
|
||||
entries = map(lambda x: x[1], slist)
|
||||
val = 0
|
||||
for person_handle in entries:
|
||||
tpl = (name,val)
|
||||
self.temp_iter2path[person_handle] = tpl
|
||||
self.temp_path2iter[tpl] = person_handle
|
||||
val += 1
|
||||
def build_sub_entry(self,name):
|
||||
slist = map(lambda x: (self.sortnames[x],x),self.temp_sname_sub[name])
|
||||
slist.sort(self.byname)
|
||||
entries = map(lambda x: x[1], slist)
|
||||
val = 0
|
||||
for person_handle in entries:
|
||||
tpl = (name,val)
|
||||
self.temp_iter2path[person_handle] = tpl
|
||||
self.temp_path2iter[tpl] = person_handle
|
||||
val += 1
|
||||
|
||||
def assign_data(self):
|
||||
self.top_path2iter = self.temp_top_path2iter
|
||||
|
@ -88,13 +88,13 @@ class PeopleView:
|
||||
self.person_tree = self.parent.gtop.get_widget("person_tree")
|
||||
self.person_tree.set_rules_hint(True)
|
||||
self.renderer = gtk.CellRendererText()
|
||||
self.inactive = False
|
||||
|
||||
self.columns = []
|
||||
self.build_columns()
|
||||
self.person_selection = self.person_tree.get_selection()
|
||||
self.person_selection.set_mode(gtk.SELECTION_MULTIPLE)
|
||||
self.person_selection.connect('changed',self.row_changed)
|
||||
self.person_selection.connect('changed',self.set_dnd_target)
|
||||
self.person_tree.connect('row_activated', self.alpha_event)
|
||||
self.person_tree.connect('button-press-event',
|
||||
self.on_plist_button_press)
|
||||
@ -113,20 +113,6 @@ class PeopleView:
|
||||
sel_data.set(DdTargets.PERSON_LINK_LIST.drag_type,8,
|
||||
pickle.dumps(selected_ids))
|
||||
|
||||
def set_dnd_target(self,obj):
|
||||
selected_ids = self.get_selected_objects()
|
||||
|
||||
if len(selected_ids) == 1:
|
||||
self.person_tree.drag_source_set(BUTTON1_MASK,
|
||||
[DdTargets.PERSON_LINK.target()],
|
||||
ACTION_COPY)
|
||||
elif len(selected_ids) > 1:
|
||||
self.person_tree.drag_source_set(BUTTON1_MASK,
|
||||
[DdTargets.PERSON_LINK_LIST.target()],
|
||||
ACTION_COPY)
|
||||
|
||||
|
||||
|
||||
def sort_clicked(self,obj):
|
||||
for col in self.columns:
|
||||
if obj == col:
|
||||
@ -173,13 +159,12 @@ class PeopleView:
|
||||
self.parent.filter_invert.get_active())
|
||||
self.person_tree.set_model(self.person_model)
|
||||
|
||||
def blist(self, store, path, node, id_list):
|
||||
idval = self.person_model.get_value(node, PeopleModel.COLUMN_INT_ID)
|
||||
id_list.append(idval)
|
||||
|
||||
def get_selected_objects(self):
|
||||
(mode,paths) = self.person_selection.get_selected_rows()
|
||||
mlist = []
|
||||
self.person_selection.selected_foreach(self.blist,mlist)
|
||||
for path in paths:
|
||||
node = self.person_model.on_get_iter(path)
|
||||
mlist.append(self.person_model.on_get_value(node, PeopleModel.COLUMN_INT_ID))
|
||||
return mlist
|
||||
|
||||
def row_changed(self,obj):
|
||||
@ -189,24 +174,29 @@ class PeopleView:
|
||||
selected, set the active person to None"""
|
||||
|
||||
selected_ids = self.get_selected_objects()
|
||||
|
||||
try:
|
||||
person = self.parent.db.get_person_from_handle(selected_ids[0])
|
||||
self.parent.change_active_person(person)
|
||||
except:
|
||||
self.parent.change_active_person(None)
|
||||
|
||||
if len(selected_ids) == 1:
|
||||
self.person_tree.drag_source_set(BUTTON1_MASK,
|
||||
[DdTargets.PERSON_LINK.target()],
|
||||
ACTION_COPY)
|
||||
elif len(selected_ids) > 1:
|
||||
self.person_tree.drag_source_set(BUTTON1_MASK,
|
||||
[DdTargets.PERSON_LINK_LIST.target()],
|
||||
ACTION_COPY)
|
||||
|
||||
def change_db(self,db):
|
||||
self.build_columns()
|
||||
self.person_model = PeopleModel.PeopleModel(db,self.DataFilter)
|
||||
self.person_tree.set_model(self.person_model)
|
||||
|
||||
db.connect('person-add', self.person_added)
|
||||
db.connect('person-update', self.person_updated)
|
||||
db.connect('person-delete', self.person_removed)
|
||||
db.connect('person-rebuild', self.redisplay_person_list)
|
||||
self.apply_filter()
|
||||
|
||||
|
||||
def remove_from_person_list(self,person):
|
||||
"""Remove the selected person from the list. A person object is
|
||||
expected, not an ID"""
|
||||
@ -239,8 +229,9 @@ class PeopleView:
|
||||
self.goto_active_person()
|
||||
|
||||
def goto_active_person(self):
|
||||
if not self.parent.active_person:
|
||||
if not self.parent.active_person or self.inactive:
|
||||
return
|
||||
self.inactive = True
|
||||
p = self.parent.active_person
|
||||
try:
|
||||
path = self.person_model.on_get_path(p.get_handle())
|
||||
@ -248,13 +239,19 @@ class PeopleView:
|
||||
top_name = self.parent.db.get_name_group_mapping(group_name)
|
||||
top_path = self.person_model.on_get_path(top_name)
|
||||
self.person_tree.expand_row(top_path,0)
|
||||
self.person_selection.unselect_all()
|
||||
self.person_selection.select_path(path)
|
||||
self.person_tree.scroll_to_cell(path,None,1,0.5,0)
|
||||
|
||||
current = self.person_model.on_get_iter(path)
|
||||
|
||||
selected = self.person_selection.path_is_selected(path)
|
||||
if current != p.get_handle() or not selected:
|
||||
self.person_selection.unselect_all()
|
||||
self.person_selection.select_path(path)
|
||||
self.person_tree.scroll_to_cell(path,None,1,0.5,0)
|
||||
except KeyError:
|
||||
self.person_selection.unselect_all()
|
||||
print "Person not currently available due to filter"
|
||||
self.parent.active_person = p
|
||||
self.inactive = False
|
||||
|
||||
def alpha_event(self,*obj):
|
||||
self.parent.load_person(self.parent.active_person)
|
||||
@ -276,9 +273,9 @@ class PeopleView:
|
||||
fwd_sensitivity = self.parent.hindex + 1 < len(self.parent.history)
|
||||
mlist = self.get_selected_objects()
|
||||
if mlist:
|
||||
sel_sensitivity = 1
|
||||
sel_sensitivity = True
|
||||
else:
|
||||
sel_sensitivity = 0
|
||||
sel_sensitivity = False
|
||||
merge_sensitivity = len(mlist) == 2
|
||||
entries = [
|
||||
(gtk.STOCK_GO_BACK,self.parent.back_clicked,back_sensitivity),
|
||||
@ -361,7 +358,17 @@ class PeopleView:
|
||||
pnode = self.person_model.get_iter(pathval)
|
||||
|
||||
# calculate the new data
|
||||
self.person_model.calculate_data(self.DataFilter)
|
||||
|
||||
if person.primary_name.group_as:
|
||||
surname = person.primary_name.group_as
|
||||
else:
|
||||
surname = self.parent.db.get_name_group_mapping(person.primary_name.surname)
|
||||
|
||||
|
||||
if oldpath[0] == surname:
|
||||
self.person_model.build_sub_entry(surname)
|
||||
else:
|
||||
self.person_model.calculate_data(self.DataFilter)
|
||||
|
||||
# find the path of the person in the new data build
|
||||
newpath = self.person_model.temp_iter2path[node]
|
||||
@ -400,5 +407,4 @@ class PeopleView:
|
||||
pnode = self.person_model.get_iter(path)
|
||||
self.person_model.row_inserted(path,pnode)
|
||||
|
||||
#self.parent.change_active_person(person)
|
||||
self.goto_active_person()
|
||||
|
@ -434,13 +434,13 @@ class GedcomParser:
|
||||
self.text = string.translate(self.text,self.transtable2)
|
||||
|
||||
self.index += 1
|
||||
l = self.text.split(None, 2)
|
||||
l = self.text.split(' ', 2)
|
||||
ln = len(l)
|
||||
try:
|
||||
if ln == 2:
|
||||
self.groups = (int(l[0]),unicode(l[1]),u"")
|
||||
self.groups = (int(l[0]),unicode(l[1]).strip(),u"")
|
||||
else:
|
||||
self.groups = (int(l[0]),unicode(l[1]),unicode(l[2]))
|
||||
self.groups = (int(l[0]),unicode(l[1]).strip(),unicode(l[2]))
|
||||
except:
|
||||
if self.text == "":
|
||||
msg = _("Warning: line %d was blank, so it was ignored.\n") % self.index
|
||||
|
@ -59,7 +59,16 @@ def importData(database, filename, callback=None,cl=0,use_trans=True):
|
||||
else:
|
||||
ErrorDialog(_("%s could not be opened") % filename)
|
||||
return
|
||||
|
||||
if not other_database.version_supported():
|
||||
if cl:
|
||||
print "Error: %s could not be opened.\n%s Exiting." % (filename,\
|
||||
_("The database version is not supported by this version of GRAMPS.\n"\
|
||||
"Please upgrade to the corresponding version or use XML for porting data between different database versions."))
|
||||
else:
|
||||
ErrorDialog(_("%s could not be opened") % filename,
|
||||
_("The Database version is not supported by this version of GRAMPS."))
|
||||
return
|
||||
|
||||
# Check for duplicate handles. At the moment we simply exit here,
|
||||
# before modifying any data. In the future we will need to handle
|
||||
# this better.
|
||||
|
@ -308,6 +308,7 @@ class SelectChild:
|
||||
self.top)
|
||||
return
|
||||
|
||||
# TODO: Add child ordered by birth day
|
||||
self.family.add_child_handle(select_child.get_handle())
|
||||
|
||||
mrel = self.mrel.get_active()
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2004 Donald N. Allingham
|
||||
# Copyright (C) 2000-2005 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
|
||||
@ -27,18 +27,24 @@ and directly use class members. For this reason, care needs to be taken
|
||||
to make sure these remain in sync with the rest of the design.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import locale
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Imported Modules
|
||||
# GRAMPS Modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import Date
|
||||
from NameDisplay import displayer as _nd
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Functions
|
||||
# Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -52,7 +58,6 @@ class Sort:
|
||||
def __init__(self,database):
|
||||
self.database = database
|
||||
|
||||
|
||||
def by_last_name(self,first_id,second_id):
|
||||
"""Sort routine for comparing two last names. If last names are equal,
|
||||
uses the given name and suffix"""
|
||||
@ -75,6 +80,19 @@ class Sort:
|
||||
else:
|
||||
return locale.strcoll(fsn, ssn)
|
||||
|
||||
def by_sorted_name(self,first_id,second_id):
|
||||
"""
|
||||
Sort routine for comparing two displayed names.
|
||||
"""
|
||||
|
||||
first = self.database.get_person_from_handle(first_id)
|
||||
second = self.database.get_person_from_handle(second_id)
|
||||
|
||||
name1 = _nd.sorted(first)
|
||||
name2 = _nd.sorted(second)
|
||||
|
||||
return locale.strcoll(name1,name2)
|
||||
|
||||
def by_birthdate(self,first_id,second_id):
|
||||
"""Sort routine for comparing two people by birth dates. If the birth dates
|
||||
are equal, sorts by name"""
|
||||
|
@ -154,11 +154,13 @@ class SourceView:
|
||||
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
|
||||
mlist = []
|
||||
self.selection.selected_foreach(self.blist,mlist)
|
||||
handle = mlist[0]
|
||||
source = self.parent.db.get_source_from_handle(handle)
|
||||
EditSource.EditSource(source,self.parent.db,self.parent,
|
||||
self.topWindow)
|
||||
return True
|
||||
if mlist:
|
||||
handle = mlist[0]
|
||||
source = self.parent.db.get_source_from_handle(handle)
|
||||
EditSource.EditSource(source,self.parent.db,self.parent,
|
||||
self.topWindow)
|
||||
return True
|
||||
return False
|
||||
elif event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
|
||||
self.build_context_menu(event)
|
||||
return True
|
||||
|
@ -34,6 +34,7 @@ import locale
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
import gtk.gdk
|
||||
import gnome
|
||||
|
||||
try:
|
||||
@ -402,17 +403,34 @@ def search_for(name):
|
||||
# Change label apperance
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def bold_label(label):
|
||||
def bold_label(label,widget=None):
|
||||
text = unicode(label.get_text())
|
||||
text = text.replace('<i>','')
|
||||
text = text.replace('</i>','')
|
||||
label.set_text("<b>%s</b>" % text )
|
||||
label.set_use_markup(1)
|
||||
label.set_use_markup(True)
|
||||
if widget:
|
||||
widget.window.set_cursor(None)
|
||||
|
||||
def unbold_label(label):
|
||||
def unbold_label(label,widget=None):
|
||||
text = unicode(label.get_text())
|
||||
text = text.replace('<b>','')
|
||||
text = text.replace('</b>','')
|
||||
text = text.replace('<i>','')
|
||||
text = text.replace('</i>','')
|
||||
label.set_text(text)
|
||||
label.set_use_markup(0)
|
||||
label.set_use_markup(False)
|
||||
if widget:
|
||||
widget.window.set_cursor(None)
|
||||
|
||||
def temp_label(label,widget=None):
|
||||
text = unicode(label.get_text())
|
||||
text = text.replace('<b>','')
|
||||
text = text.replace('</b>','')
|
||||
label.set_text("<i>%s</i>" % text )
|
||||
label.set_use_markup(True)
|
||||
if widget:
|
||||
widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -447,14 +465,13 @@ def probably_alive(person,db,current_year=None):
|
||||
|
||||
"""
|
||||
|
||||
if not current_year:
|
||||
time_struct = time.localtime(time.time())
|
||||
current_year = time_struct[0]
|
||||
|
||||
death_year = None
|
||||
# If the recorded death year is before current year then
|
||||
# things are simple.
|
||||
if person.death_handle:
|
||||
if not current_year:
|
||||
# no current year and we have a death event -> person died
|
||||
return False
|
||||
death = db.get_event_from_handle(person.death_handle)
|
||||
if death.get_date_object().get_start_date() != Date.EMPTY:
|
||||
death_year = death.get_date_object().get_year()
|
||||
@ -466,12 +483,19 @@ def probably_alive(person,db,current_year=None):
|
||||
for ev_handle in person.event_list:
|
||||
ev = db.get_event_from_handle(ev_handle)
|
||||
if ev and ev.name in ["Cause Of Death", "Burial", "Cremation"]:
|
||||
if not current_year:
|
||||
# no current year and we have an event related to death
|
||||
return False
|
||||
if not death_year:
|
||||
death_year = ev.get_date_object().get_year()
|
||||
if ev.get_date_object().get_start_date() != Date.EMPTY:
|
||||
if ev.get_date_object().get_year() < current_year:
|
||||
return False
|
||||
|
||||
if not current_year:
|
||||
time_struct = time.localtime(time.time())
|
||||
current_year = time_struct[0]
|
||||
|
||||
birth_year = None
|
||||
# If they were born within 100 years before current year then
|
||||
# assume they are alive (we already know they are not dead).
|
||||
|
@ -809,7 +809,7 @@ class GedcomWriter:
|
||||
death = self.db.get_event_from_handle(death_handle)
|
||||
if death_handle and death and not (self.private and death.get_privacy()):
|
||||
if not death.get_date_object().is_empty() or death.get_place_handle():
|
||||
if birth.get_description() != "":
|
||||
if death.get_description() != "":
|
||||
self.writeln("1 DEAT %s" % death.get_description())
|
||||
else:
|
||||
self.writeln("1 DEAT")
|
||||
|
@ -827,11 +827,6 @@ class XmlWriter:
|
||||
path = obj.get_path()
|
||||
if self.strip_photos:
|
||||
path = os.path.basename(path)
|
||||
else:
|
||||
l = len(self.fileroot)
|
||||
if len(path) >= l:
|
||||
if self.fileroot == path[0:l]:
|
||||
path = path[l+1:]
|
||||
self.g.write(' <object id="%s" handle="%s" change="%d" src="%s" mime="%s"' %
|
||||
(handle,obj.get_handle(),obj.get_change_time(),path,mime_type))
|
||||
self.g.write(' description="%s"' % self.fix(obj.get_description()))
|
||||
|
@ -494,6 +494,13 @@ family_relations = [
|
||||
(_("Other"), _("An unspecified relationship between a man and woman"))
|
||||
]
|
||||
|
||||
family_relations_C = [
|
||||
"Married",
|
||||
"Unmarried",
|
||||
"Civil Union",
|
||||
"Unknown",
|
||||
"Other",
|
||||
]
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
@ -501,9 +508,9 @@ family_relations = [
|
||||
#-------------------------------------------------------------------------
|
||||
def save_frel(st):
|
||||
try:
|
||||
return family_relations[st][0]
|
||||
return family_relations_C[st]
|
||||
except:
|
||||
return _("Unknown")
|
||||
return "Unknown"
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -112,8 +112,8 @@ class DateParserDE(DateParser):
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
self._span = re.compile("(von|vom)\s+(.+)\s+(bis)\s+(.+)",re.IGNORECASE)
|
||||
self._range = re.compile("(zwischen)\s+(.+)\s+(und)\s+(.+)", re.IGNORECASE)
|
||||
self._span = re.compile("(von|vom)\s+(?P<start>.+)\s+(bis)\s+(?P<stop>.+)",re.IGNORECASE)
|
||||
self._range = re.compile("zwischen\s+(?P<start>.+)\s+und\s+(?P<stop>.+)", re.IGNORECASE)
|
||||
self._text2 = re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._mon_str,
|
||||
re.IGNORECASE)
|
||||
self._jtext2= re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._jmon_str,
|
||||
@ -131,7 +131,7 @@ class DateDisplayDE(DateDisplay):
|
||||
u" (Französisch Republikanisch)", u" (Persisch)", u" (Islamisch)"
|
||||
)
|
||||
|
||||
_mod_str = ("",u"vor ",u"nach ",u"circa ","","","")
|
||||
_mod_str = ("",u"vor ",u"nach ",u"etwa ","","","")
|
||||
|
||||
_qual_str = ("",u"geschätzt ",u"errechnet ")
|
||||
|
||||
@ -224,9 +224,5 @@ class DateDisplayDE(DateDisplay):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from DateHandler import register_datehandler
|
||||
register_datehandler(('de_DE','german'),DateParserDE, DateDisplayDE)
|
||||
register_datehandler(('de_AT','german (Austria)'),DateParserDE, DateDisplayDE)
|
||||
register_datehandler(('de_CH','german (Switzerland)'),DateParserDE, DateDisplayDE)
|
||||
register_datehandler(('de_LI','german (Lichtenstein)'),DateParserDE, DateDisplayDE)
|
||||
register_datehandler(('de_LU','german (Luxembourg)'),DateParserDE, DateDisplayDE)
|
||||
register_datehandler(('de_BE','german (Belgium)'),DateParserDE, DateDisplayDE)
|
||||
register_datehandler(('de_DE','german','de_AT','de_CH',
|
||||
'de_LI','de_LU','de_BE','de'),DateParserDE, DateDisplayDE)
|
||||
|
@ -98,10 +98,10 @@ class DateParserES(DateParser):
|
||||
_span_2 = [u'a']
|
||||
_range_1 = [u'ent.',u'ent',u'entre']
|
||||
_range_2 = [u'y']
|
||||
self._span = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
|
||||
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_span_1),'|'.join(_span_2)),
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
|
||||
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1),'|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
|
||||
@ -159,4 +159,4 @@ class DateDisplayES(DateDisplay):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from DateHandler import register_datehandler
|
||||
register_datehandler(('es_ES','spanish'),DateParserES, DateDisplayES)
|
||||
register_datehandler(('es_ES','es','spanish'),DateParserES, DateDisplayES)
|
||||
|
@ -95,9 +95,9 @@ class DateParserFI(DateParser):
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
# date, whitespace
|
||||
self._span = re.compile("(?P<start>.+)\s+-\s+(?P<stop>.+)",
|
||||
self._span = re.compile("(?P<start>.+)\s+(-)\s+(?P<stop>.+)",
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(?P<start>.+)\s+ja\s+(?P<stop>.+)\s+väliltä",
|
||||
self._range = re.compile("(vuosien\s*)?(?P<start>.+)\s+ja\s+(?P<stop>.+)\s+väliltä",
|
||||
re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@ -114,7 +114,7 @@ class DateDisplayFI(DateDisplay):
|
||||
u"(Persialainen)",
|
||||
u"(Islamilainen)")
|
||||
|
||||
_qual_str = ("", "laskettuna", "arviolta")
|
||||
_qual_str = ("", "arviolta", "laskettuna")
|
||||
|
||||
formats = (
|
||||
"VVVV-KK-PP (ISO)",
|
||||
@ -143,9 +143,15 @@ class DateDisplayFI(DateDisplay):
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
text = "%s - %s" % (d1, d2)
|
||||
elif mod == Date.MOD_RANGE:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
text = "%s ja %s väliltä" % (d1, d2)
|
||||
stop = date.get_stop_date()
|
||||
if start[0] == 0 and start[1] == 0 and stop[0] == 0 and stop[1] == 0:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](stop)
|
||||
text = "vuosien %s ja %s väliltä" % (d1, d2)
|
||||
else:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](stop)
|
||||
text = "%s ja %s väliltä" % (d1, d2)
|
||||
else:
|
||||
text = self.display_cal[date.get_calendar()](start)
|
||||
if mod == Date.MOD_BEFORE:
|
||||
@ -171,5 +177,5 @@ class DateDisplayFI(DateDisplay):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from DateHandler import register_datehandler
|
||||
register_datehandler(('fi_FI','finnish'), DateParserFI, DateDisplayFI)
|
||||
register_datehandler(('fi_FI','fi','finnish'), DateParserFI, DateDisplayFI)
|
||||
|
||||
|
@ -92,10 +92,10 @@ class DateParserFR(DateParser):
|
||||
_span_2 = [u'à']
|
||||
_range_1 = [u'ent.',u'ent',u'entre']
|
||||
_range_2 = [u'et']
|
||||
self._span = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
|
||||
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_span_1),'|'.join(_span_2)),
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
|
||||
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1),'|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
|
||||
@ -153,4 +153,4 @@ class DateDisplayFR(DateDisplay):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from DateHandler import register_datehandler
|
||||
register_datehandler(('fr_FR','french'),DateParserFR, DateDisplayFR)
|
||||
register_datehandler(('fr_FR','fr','french'),DateParserFR, DateDisplayFR)
|
||||
|
@ -102,10 +102,10 @@ class DateParserRU(DateParser):
|
||||
_span_2 = [u'по',u'до']
|
||||
_range_1 = [u'между',u'меж',u'меж.']
|
||||
_range_2 = [u'и']
|
||||
self._span = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
|
||||
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_span_1),'|'.join(_span_2)),
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(%s)\s+(.+)\s+(%s)\s+(.+)" %
|
||||
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1),'|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
|
||||
@ -168,4 +168,4 @@ class DateDisplayRU(DateDisplay):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from DateHandler import register_datehandler
|
||||
register_datehandler(('ru_RU','russian'),DateParserRU, DateDisplayRU)
|
||||
register_datehandler(('ru_RU','ru','russian'),DateParserRU, DateDisplayRU)
|
||||
|
@ -9,8 +9,9 @@ pkgdata_PYTHON = \
|
||||
Date_de.py\
|
||||
Date_ru.py\
|
||||
Date_fr.py\
|
||||
Date_es.py\
|
||||
Date_fi.py
|
||||
Date_es.py
|
||||
|
||||
# Date_fi.py
|
||||
|
||||
pkgpyexecdir = @pkgpyexecdir@/dates
|
||||
pkgpythondir = @pkgpythondir@/dates
|
||||
|
@ -1291,14 +1291,17 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
|
||||
ErrorDialog(_('Cannot open database'),
|
||||
_('The database file specified could not be opened.'))
|
||||
return 0
|
||||
except ( IOError, OSError ), msg:
|
||||
except ( IOError, OSError, Errors.FileVersionError), msg:
|
||||
ErrorDialog(_('Cannot open database'),str(msg))
|
||||
return 0
|
||||
except db.DBAccessError, msg:
|
||||
except (db.DBAccessError,db.DBError), msg:
|
||||
ErrorDialog(_('Cannot open database'),
|
||||
_('%s could not be opened.' % filename) + '\n' + msg[1])
|
||||
return 0
|
||||
|
||||
except Exception:
|
||||
DisplayTrace.DisplayTrace()
|
||||
return 0
|
||||
|
||||
# Undo/Redo always start with standard labels and insensitive state
|
||||
self.undo_callback(None)
|
||||
self.redo_callback(None)
|
||||
@ -1524,6 +1527,15 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
|
||||
self.people_view.goto_active_person()
|
||||
|
||||
def change_active_person(self,person,force=0):
|
||||
nph = ""
|
||||
if person:
|
||||
nph = person.get_handle()
|
||||
oph = ""
|
||||
if self.active_person:
|
||||
oph = self.active_person.get_handle()
|
||||
if nph == oph: # no need to change to the current active person again
|
||||
return
|
||||
|
||||
if person == None:
|
||||
self.set_buttons(0)
|
||||
self.active_person = None
|
||||
@ -1731,10 +1743,15 @@ class Gramps(GrampsDBCallback.GrampsDBCallback):
|
||||
gtk.main_iteration()
|
||||
|
||||
def post_load(self,name,callback=None):
|
||||
if not self.db.version_supported():
|
||||
raise Errors.FileVersionError(
|
||||
"The database version is not supported by this version of GRAMPS.\n"
|
||||
"Please upgrade to the corresponding version or use XML for porting data between different database versions.")
|
||||
|
||||
self.db.set_save_path(name)
|
||||
|
||||
res = self.db.get_researcher()
|
||||
owner = GrampsCfg.get_researcher()
|
||||
|
||||
if res.get_name() == "" and owner.get_name():
|
||||
self.db.set_researcher(owner)
|
||||
|
||||
|
166
gramps2/src/plugins/Checkpoint.py
Normal file
166
gramps2/src/plugins/Checkpoint.py
Normal file
@ -0,0 +1,166 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 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
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
"Database Processing/Extract information from names"
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import os
|
||||
import popen2
|
||||
import locale
|
||||
import time
|
||||
from gettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gnome/gtk
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from QuestionDialog import OkDialog, ErrorDialog
|
||||
import WriteXML
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def runTool(database,active_person,callback,parent=None):
|
||||
try:
|
||||
Checkpoint(database,callback,parent)
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Checkpoint
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class Checkpoint:
|
||||
|
||||
def __init__(self,db,callback,parent):
|
||||
self.cb = callback
|
||||
self.db = db
|
||||
self.parent = parent
|
||||
self.use_custom = False
|
||||
self.custom_str = "cat > /tmp/temp.file"
|
||||
self.run()
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
RCS will be a builtin command, since we can handle all
|
||||
configuration on our own. This isn't true for most versioning
|
||||
systems, which usually require external setup, and external
|
||||
communication.
|
||||
"""
|
||||
self.parent.status_text(_("Checkpointing database..."))
|
||||
|
||||
if self.use_custom:
|
||||
self.custom()
|
||||
else:
|
||||
self.rcs()
|
||||
|
||||
self.parent.progress.set_fraction(0)
|
||||
self.parent.modify_statusbar()
|
||||
|
||||
def timestamp(self):
|
||||
format = locale.nl_langinfo(locale.D_T_FMT)
|
||||
return unicode(time.strftime(format,time.localtime(time.time())))
|
||||
|
||||
def custom(self):
|
||||
"""
|
||||
Passed the generated XML file to the specified command.
|
||||
"""
|
||||
proc = popen2.Popen3(self.custom_str, True)
|
||||
xmlwrite = WriteXML.XmlWriter(self.db,self.callback,False,False)
|
||||
xmlwrite.write_handle(proc.tochild)
|
||||
status = proc.wait()
|
||||
if status:
|
||||
ErrorDialog(_("Checkpoint failed"),
|
||||
"\n".join(proc.childerr.readlines()))
|
||||
del proc
|
||||
|
||||
def rcs(self):
|
||||
"""
|
||||
Check the generated XML file into RCS. Initialize the RCS file if
|
||||
it does not already exist.
|
||||
"""
|
||||
(archive_base,ext) = os.path.splitext(self.db.get_save_path())
|
||||
|
||||
archive = archive_base + ",v"
|
||||
if not os.path.exists(archive):
|
||||
proc = popen2.Popen3('rcs -i -U -q -t-"GRAMPS database" %s' % archive,True)
|
||||
proc.tochild.write(comment)
|
||||
proc.tochild.close()
|
||||
status = proc.wait()
|
||||
if status:
|
||||
ErrorDialog(_("Checkpoint failed"),
|
||||
"\n".join(proc.childerr.readlines()))
|
||||
del proc
|
||||
return
|
||||
|
||||
xmlwrite = WriteXML.XmlWriter(self.db,self.callback,False,False)
|
||||
xmlwrite.write(archive_base)
|
||||
|
||||
comment = self.timestamp()
|
||||
|
||||
proc = popen2.Popen3("ci %s" % archive_base,True)
|
||||
proc.tochild.write(comment)
|
||||
proc.tochild.close()
|
||||
status = proc.wait()
|
||||
if status:
|
||||
ErrorDialog(_("Checkpoint failed"),
|
||||
"\n".join(proc.childerr.readlines()))
|
||||
del proc
|
||||
|
||||
def callback(self,value):
|
||||
"""
|
||||
Call back function for the WriteXML function that updates the
|
||||
status progress bar.
|
||||
"""
|
||||
self.parent.progress.set_fraction(value)
|
||||
while(gtk.events_pending()):
|
||||
gtk.main_iteration()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from PluginMgr import register_tool
|
||||
|
||||
register_tool(
|
||||
runTool,
|
||||
_("Checkpoint the database"),
|
||||
category=_("Revision control"),
|
||||
description=_("Store a snapshot of the current database into "
|
||||
"a revision control system"))
|
@ -486,7 +486,8 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
|
||||
"""
|
||||
spouses = self.get_spouses(dialog.db,dialog.person)
|
||||
spouse_index = self.spouse_menu.get_active()
|
||||
self.options_dict['spouse_id'] = spouses[spouse_index][0]
|
||||
if spouses:
|
||||
self.options_dict['spouse_id'] = spouses[spouse_index][0]
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
"""Make default output style for the Family Group Report."""
|
||||
|
@ -30,7 +30,6 @@ pkgdata_PYTHON = \
|
||||
IndivComplete.py\
|
||||
IndivSummary.py\
|
||||
Merge.py\
|
||||
NavWebPage.py\
|
||||
PatchNames.py\
|
||||
ReadPkg.py\
|
||||
RelCalc.py\
|
||||
|
@ -573,6 +573,11 @@ class ScratchPadListView:
|
||||
|
||||
self.treetips = TreeTips.TreeTips(self._widget,2,True)
|
||||
|
||||
# Set the column that inline searching will use.
|
||||
# The search does not appear to work properly so I am disabling it for now.
|
||||
self._widget.set_enable_search(False)
|
||||
#self._widget.set_search_column(1)
|
||||
|
||||
self._widget.drag_dest_set(gtk.DEST_DEFAULT_ALL,
|
||||
(ScratchPadListView.LOCAL_DRAG_TARGET,) + \
|
||||
DdTargets.all_targets(),
|
||||
@ -793,7 +798,7 @@ class ScratchPadWindow:
|
||||
"on_clear_clicked": self.on_clear_clicked,
|
||||
"on_help_clicked": self.on_help_clicked,
|
||||
"on_objectlist_delete_event": self.on_delete_event,
|
||||
"on_scratchPad_delete_event": self.on_delete_event
|
||||
"on_scratch_pad_delete_event": self.on_delete_event
|
||||
})
|
||||
|
||||
self.clear_all_btn.connect_object('clicked', gtk.ListStore.clear, ScratchPadWindow.otree)
|
||||
|
@ -899,7 +899,7 @@ class StatisticsChartOptions(ReportOptions.ReportOptions):
|
||||
tip = _("With fewer items pie chart and legend will be used instead of a bar chart.")
|
||||
self.bar_items = gtk.Entry(2)
|
||||
self.bar_items.set_text(str(self.options_dict['bar_items']))
|
||||
dialog.add_option(_("Min. bar char items"), self.bar_items, tip)
|
||||
dialog.add_option(_("Max. items for a pie"), self.bar_items, tip)
|
||||
|
||||
# -------------------------------------------------
|
||||
# List of available charts on a separate option tab
|
||||
|
@ -144,7 +144,6 @@ class TestcaseGenerator:
|
||||
if not self.multiple_transactions:
|
||||
self.trans.set_batch(True)
|
||||
self.db.disable_signals()
|
||||
|
||||
|
||||
if self.multiple_transactions:
|
||||
|
||||
@ -248,6 +247,23 @@ class TestcaseGenerator:
|
||||
print "DONE."
|
||||
|
||||
|
||||
if generate_bugs or generate_dates or generate_families:
|
||||
self.default_source = RelLib.Source()
|
||||
self.default_source.set_title("TestcaseGenerator")
|
||||
self.db.add_source(self.default_source, self.trans)
|
||||
self.default_sourceref = RelLib.SourceRef()
|
||||
self.default_sourceref.set_base_handle(self.default_source.get_handle())
|
||||
self.default_place = RelLib.Place()
|
||||
self.default_place.set_title("TestcaseGenerator place")
|
||||
self.db.add_place(self.default_place, self.trans)
|
||||
self.default_media = RelLib.MediaObject()
|
||||
self.default_media.set_description("TestcaseGenerator media")
|
||||
self.default_media.set_path("/tmp/TestcaseGenerator.png")
|
||||
self.default_media.set_mime_type("image/png")
|
||||
self.db.add_object(self.default_media, self.trans)
|
||||
self.default_mediaref = RelLib.MediaRef()
|
||||
self.default_mediaref.set_reference_handle(self.default_media.get_handle())
|
||||
|
||||
if generate_bugs:
|
||||
self.generate_broken_relations()
|
||||
|
||||
@ -607,6 +623,8 @@ class TestcaseGenerator:
|
||||
|
||||
np = RelLib.Person()
|
||||
|
||||
self.add_defaults(np)
|
||||
|
||||
# Note
|
||||
if note:
|
||||
np.set_note(note)
|
||||
@ -662,6 +680,7 @@ class TestcaseGenerator:
|
||||
self.parents_todo.append(person2_h)
|
||||
|
||||
fam = RelLib.Family()
|
||||
self.add_defaults(fam)
|
||||
fam.set_father_handle(person1_h)
|
||||
fam.set_mother_handle(person2_h)
|
||||
fam.set_relationship(RelLib.Family.MARRIED)
|
||||
@ -721,6 +740,15 @@ class TestcaseGenerator:
|
||||
self.db.commit_person(child,self.trans)
|
||||
self.commit_transaction() # COMMIT TRANSACTION STEP
|
||||
|
||||
def add_defaults(self,object,ref_text = ""):
|
||||
object.add_source_reference(self.default_sourceref)
|
||||
object.add_media_reference(self.default_mediaref)
|
||||
e = RelLib.Event()
|
||||
e.set_name("TestcaseGenerator")
|
||||
e.set_place_handle(self.default_place.get_handle())
|
||||
self.db.add_event(e, self.trans)
|
||||
object.add_event_handle(e.get_handle())
|
||||
|
||||
def commit_transaction(self):
|
||||
if self.multiple_transactions:
|
||||
self.db.transaction_commit(self.trans,_("Testcase generator step %d") % self.transaction_count)
|
||||
|
@ -29,6 +29,7 @@
|
||||
#------------------------------------------------------------------------
|
||||
import os
|
||||
import shutil
|
||||
import locale
|
||||
from gettext import gettext as _
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@ -57,6 +58,7 @@ import Errors
|
||||
import Utils
|
||||
from QuestionDialog import ErrorDialog
|
||||
import ReportOptions
|
||||
from NameDisplay import displayer as _nd
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@ -943,8 +945,6 @@ class WebReport(Report.Report):
|
||||
doc.write_text(_("Family Tree Index"))
|
||||
doc.end_paragraph()
|
||||
|
||||
person_handle_list.sort(self.sort.by_last_name)
|
||||
|
||||
a = {}
|
||||
for person_handle in person_handle_list:
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
@ -956,7 +956,7 @@ class WebReport(Report.Report):
|
||||
|
||||
section_number = 1
|
||||
link_keys = a.keys()
|
||||
link_keys.sort()
|
||||
link_keys.sort(locale.strcoll)
|
||||
for n in link_keys:
|
||||
a[n] = section_number
|
||||
section_number = section_number + 1
|
||||
@ -980,6 +980,7 @@ class WebReport(Report.Report):
|
||||
p_id_list = [ p_id for p_id in person_handle_list if \
|
||||
(self.database.get_person_from_handle(p_id).get_primary_name().get_surname() \
|
||||
and (self.database.get_person_from_handle(p_id).get_primary_name().get_surname()[0] == n) ) ]
|
||||
p_id_list.sort(self.sort.by_sorted_name)
|
||||
doc = HtmlLinkDoc(self.selected_style,None,template,None)
|
||||
doc.set_extension(self.ext)
|
||||
doc.set_title(_("Section %s") % n)
|
||||
@ -998,7 +999,7 @@ class WebReport(Report.Report):
|
||||
|
||||
for person_handle in p_id_list:
|
||||
the_person = self.database.get_person_from_handle(person_handle)
|
||||
name = the_person.get_primary_name().get_name()
|
||||
name = _nd.sorted(the_person)
|
||||
|
||||
if self.birth_dates:
|
||||
birth_handle = self.database.get_person_from_handle(person_handle).get_birth_handle()
|
||||
@ -1040,6 +1041,7 @@ class WebReport(Report.Report):
|
||||
p_id_list = [ p_id for p_id in person_handle_list if \
|
||||
(self.database.get_person_from_handle(p_id).get_primary_name().get_surname() \
|
||||
and (self.database.get_person_from_handle(p_id).get_primary_name().get_surname()[0] == n) ) ]
|
||||
p_id_list.sort(self.sort.by_sorted_name)
|
||||
doc.start_paragraph('IndexLabel')
|
||||
if self.include_alpha_links:
|
||||
doc.write_linktarget("%03d" % a[n])
|
||||
@ -1049,7 +1051,7 @@ class WebReport(Report.Report):
|
||||
|
||||
for person_handle in p_id_list:
|
||||
the_person = self.database.get_person_from_handle(person_handle)
|
||||
name = the_person.get_primary_name().get_name()
|
||||
name = _nd.sorted(the_person)
|
||||
|
||||
if self.birth_dates:
|
||||
birth_handle = self.database.get_person_from_handle(person_handle).get_birth_handle()
|
||||
|
@ -20,6 +20,7 @@
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="has_separator">True</property>
|
||||
<signal name="delete_event" handler="on_scratch_pad_delete_event" last_modification_time="Wed, 25 May 2005 13:26:32 GMT"/>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
|
4636
gramps2/src/po/de.po
4636
gramps2/src/po/de.po
File diff suppressed because it is too large
Load Diff
2160
gramps2/src/po/es.po
2160
gramps2/src/po/es.po
File diff suppressed because it is too large
Load Diff
2252
gramps2/src/po/fi.po
2252
gramps2/src/po/fi.po
File diff suppressed because it is too large
Load Diff
2150
gramps2/src/po/nb.po
2150
gramps2/src/po/nb.po
File diff suppressed because it is too large
Load Diff
2150
gramps2/src/po/no.po
2150
gramps2/src/po/no.po
File diff suppressed because it is too large
Load Diff
2174
gramps2/src/po/ru.po
2174
gramps2/src/po/ru.po
File diff suppressed because it is too large
Load Diff
5961
gramps2/src/po/sv.po
5961
gramps2/src/po/sv.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user