Compare commits
117 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 20bac63011 | |||
| 2bf08ece8f | |||
| 9209f7eca9 | |||
| d01c7bcfe5 | |||
| 80bc471b59 | |||
| 766bcc6060 | |||
| 267905f17d | |||
| dd917aa4c5 | |||
| 8bae700b80 | |||
| e697e7de4c | |||
| 638fcd1b09 | |||
| bf25a9582b | |||
| 94056f3602 | |||
| 0043572c35 | |||
| 877faeb4c4 | |||
| 264d06b2a9 | |||
| 622c870879 | |||
| 754cd97f3c | |||
| ed287a85d3 | |||
| 29a5a1397d | |||
| a19bd16975 | |||
| 082b2a7b88 | |||
| ea72d0db93 | |||
| 221a880136 | |||
| cc7027ca56 | |||
| d6dce0ecff | |||
| 8dc650bd01 | |||
| 4e5c3b529f | |||
| 429cb7b4ee | |||
| 9fded8b80c | |||
| e8d471d4ee | |||
| acc52f6816 | |||
| 5e7041cae4 | |||
| e7b45e9937 | |||
| 219fa3312e | |||
| 0daf58b604 | |||
| 95298549d8 | |||
| 1a7c66fa8d | |||
| 10deeaf7ac | |||
| 59c9e4802b | |||
| 96c3789009 | |||
| ed4b649f39 | |||
| b829978252 | |||
| 26baf4cbf6 | |||
| f25bdabcb7 | |||
| bc75ced306 | |||
| a7b12c2ec0 | |||
| 7309f0234a | |||
| cb0ca84064 | |||
| d445b84dac | |||
| 810a80da51 | |||
| c1b12a893f | |||
| 8c50ca9c9c | |||
| 4eedcb1b35 | |||
| df630cee0d | |||
| 2d39167929 | |||
| 98aab9b503 | |||
| 16563fcf32 | |||
| c41fbcaf18 | |||
| 69d2994491 | |||
| 312044b831 | |||
| f5f6442504 | |||
| 524becc3cd | |||
| fa8dde68bc | |||
| 34e7c8c67d | |||
| bc47111822 | |||
| 64d8eb7417 | |||
| c01f2f714e | |||
| 8a700ceabc | |||
| cca81f693f | |||
| fde077914c | |||
| d643aa3936 | |||
| cb52b7d9c6 | |||
| de81e15969 | |||
| bdf496ebb2 | |||
| 18e8cb6478 | |||
| 556b5cd371 | |||
| c284652cc3 | |||
| f37c2d5ccb | |||
| 92906e88cd | |||
| e0aab07c3e | |||
| d3753628c9 | |||
| 8eddbe7462 | |||
| 523af4b182 | |||
| b3bab9607d | |||
| 8ba376dd86 | |||
| 882d9c0b17 | |||
| 28b56af746 | |||
| 481a797b28 | |||
| 0574fd2489 | |||
| dcfe9af6cb | |||
| f79520e845 | |||
| 654e2af90d | |||
| df4d3c3309 | |||
| 9a357b844b | |||
| efb66d212f | |||
| 2700788f54 | |||
| 8c2563ad05 | |||
| 6963b95eec | |||
| 9e8462bffa | |||
| 840569cea7 | |||
| 608960a3e2 | |||
| c43f8c61a5 | |||
| e96641fa81 | |||
| be83003e5c | |||
| 86835434c6 | |||
| 4482378716 | |||
| 1c5ad3f57f | |||
| d6c4ffe649 | |||
| a5e9312678 | |||
| f3e2c25f21 | |||
| f1de6cc347 | |||
| 751a7911fb | |||
| 37bfa319a7 | |||
| 8c0ad73c2e | |||
| 10b86050d1 | |||
| 4f5fc60743 |
@@ -1,3 +1,310 @@
|
||||
2006-02-28 Eero Tamminen <eerot@sf>
|
||||
* src/plugins/GraphViz.py: major changes:
|
||||
Re-factoring:
|
||||
- split large functions to smaller ones to make code more readable
|
||||
- renamed few methods and variables to what they actually do
|
||||
- collect the report text to a buffer first so that it can be
|
||||
converted to latin-1 at one go
|
||||
- Move common style stuff to GraphViz header and remove from .dot
|
||||
comments stuff that's obvious from first .dot file settings
|
||||
Fixes:
|
||||
- latin-1 conversion option is explicit, not depending on font
|
||||
- set the GraphViz charset attribute according to latin1
|
||||
- quote node and edge identifiers
|
||||
- rankdir options correspond now to TB and LR (earlier LR and RL)
|
||||
New features:
|
||||
- Use christening/burial dates if birth/death dates are missing
|
||||
- User can add a (e.g. copyright) note to the graph and set its
|
||||
location (newlines and double quotes are automatically escaped)
|
||||
- User can give the paging direction
|
||||
- User can set the GraphViz aspect ratio setting
|
||||
- The weight option (either for children or parents)
|
||||
- Women have rounded boxes, except in filled mode
|
||||
(current GraphViz doesn't support boxes that are
|
||||
both rounded and filled)
|
||||
New default settings:
|
||||
- set the ratio to "compress" instead of "fill"
|
||||
- "mclimit=2.0", prevents crossed lines
|
||||
- minimum node separation is 0.25
|
||||
|
||||
2006-02-27 Alex Roitman <shura@gramps-project.org>
|
||||
* configure.in: Bump up release number.
|
||||
* Release: Version 2.0.10 "Holy Hand Grenade of Antioch" released.
|
||||
* configure.in: Bump up version number.
|
||||
|
||||
2006-02-27 Julio Sanchez <jsanchez@users.sourceforge.net>
|
||||
* src/po/es.po: Translation update
|
||||
|
||||
2006-02-26 Alex Roitman <shura@gramps-project.org>
|
||||
* src/po/template.po: Update.
|
||||
* src/po/ru.po: Update.
|
||||
|
||||
2006-02-27 Doug Blank <Doug.Blank@gmail.com>
|
||||
* src/plugins/Calendar.py: Fixed bug in primary family selection
|
||||
* src/plugins/Calendar.py: Fixed reversed meaning in maiden checkbox
|
||||
* src/plugins/Calendar.py: Added gettext around "name and name"
|
||||
|
||||
2006-02-26 Don Allingham <don@gramps-project.org>
|
||||
* src/EditPerson.py: strip names of trailing whitespace before
|
||||
assigning them
|
||||
* src/plugins/ImportGeneWeb.py: handle people with no firstname
|
||||
or lastname, if encoding fails, attempt and iso-8859-1 conversion
|
||||
|
||||
2006-02-26 Alex Roitman <shura@gramps-project.org>
|
||||
* gramps.sh.in: Update copyright year.
|
||||
* src/po/Makefile.am (.po.mo): Avoid using temp file as it breaks
|
||||
distcheck -- use pipe instead.
|
||||
|
||||
2006-02-26 Doug Blank <Doug.Blank@gmail.com>
|
||||
* src/plugins/Calendar.py (Widget.register): Do not add help
|
||||
strings to style widgets.
|
||||
|
||||
2006-02-24 Alex Roitman <shura@gramps-project.org>
|
||||
* NEWS: Update.
|
||||
* configure.in: Bump up the release number.
|
||||
* test/runtest.sh (GRPH_REP): Add calendar to the list of reports.
|
||||
* src/plugins/Calendar.py: Remove the unsupported flag.
|
||||
|
||||
2006-02-24 Marcos Bedinelli <bedinelli@yahoo.ca>
|
||||
* src/po/pt_BR.po: Update.
|
||||
|
||||
2006-02-23 Alex Roitman <shura@gramps-project.org>
|
||||
* src/plugins/Calendar.py: Remove translation from help strings;
|
||||
do not import unused modules.
|
||||
* src/po/template.po: Update.
|
||||
|
||||
2006-02-22 Alex Roitman <shura@gramps-project.org>
|
||||
* src/plugins/Calendar.py (Calendar.__getitem__,
|
||||
Widget.__getitem__): No translation for exception messages.
|
||||
* src/po/template.po: Update.
|
||||
* src/po/ru.po: Update.
|
||||
|
||||
2006-02-22 Arturas Sleinius <asleiniu@one.lt>
|
||||
* src/dates/Date_lt.py: new Lithuanian date handler
|
||||
* src/po/lt.po: updated Lithuanian translation
|
||||
|
||||
2006-02-19 Soren Roug <roug@users.sourceforge.net>
|
||||
* src/WriteXML.py: encode paths for objects in XML to handle
|
||||
&, > and < in paths.
|
||||
|
||||
2006-02-19 Don Allingham <don@gramps-project.org>
|
||||
* src/ImageSelect.py: fix already_loaded initalization
|
||||
|
||||
2006-02-18 Don Allingham <don@gramps-project.org>
|
||||
* src/plugins/Makefile.am: added Calendary.py and
|
||||
holidays.xml
|
||||
* src/po/template.po: updated
|
||||
|
||||
2006-02-18 Doug Blank <Doug.Blank@gmail.com>
|
||||
* src/plugins/Calendar.py: added
|
||||
* src/plugins/holidays.xml: added
|
||||
|
||||
2006-02-17 Alex Roitman <shura@gramps-project.org>
|
||||
* src/plugins/FamilyGroup.py (dump_parent): Translate event names.
|
||||
|
||||
2005-02-17 Martin Hawlisch <Martin.Hawlisch@gmx.de>
|
||||
* src/po/de.po: Translation update
|
||||
|
||||
2006-02-16 Don Allingham <don@gramps-project.org>
|
||||
* src/po/template.po: update for the string freeze for 2.0.10
|
||||
|
||||
2006-02-16 Alex Roitman <shura@gramps-project.org>
|
||||
* src/plugins/FamilyGroup.py (add_user_options): Do not use _("")
|
||||
to create empty checkbox.
|
||||
|
||||
2006-02-16 Don Allingham <don@gramps-project.org>
|
||||
* src/ReadGedcom.py: remove debugging statements
|
||||
|
||||
2006-02-15 Alex Roitman <shura@gramps-project.org>
|
||||
* src/ReportUtils.py (old_calc_age): Correct the logic.
|
||||
|
||||
2006-02-14 Don Allingham <don@gramps-project.org>
|
||||
* src/plugins/NavWebPage.py: include more information about CC licenses
|
||||
in the ALT and TITLE tags.
|
||||
* src/plugins/GraphViz.py: use new style links for narrative web page
|
||||
generator
|
||||
* src/DbPrompter.py: Try to give a more intelligent error message on an
|
||||
exception thrown in DbPrompter - don't give a traceback.
|
||||
* src/MediaView.py: clear out details and image if unselected
|
||||
|
||||
2006-02-14 Alex Roitman <shura@gramps-project.org>
|
||||
* src/ReportUtils.py (buried_str): Change the logic to be the same
|
||||
as in born_str: first test for modified date, then full date, then
|
||||
partial.
|
||||
* src/docgen/OpenSpreadSheet.py
|
||||
(OpenSpreadSheet._write_meta_file): Properly reference creator string.
|
||||
* src/plugins/EventCmp.py (DisplayChart.on_write_table): Set
|
||||
document creator; write localized event names.
|
||||
(DisplayChart.draw_clist_display): Display localized event names.
|
||||
* src/plugins/ChangeTypes.py: Convert event names to English for
|
||||
storage and comparison.
|
||||
|
||||
2006-02-13 Don Allingham <don@gramps-project.org>
|
||||
* src/EditPerson.py: don't double add a place
|
||||
|
||||
2006-02-13 Alex Roitman <shura@gramps-project.org>
|
||||
* src/ReportUtils.py (buried_partial_date_no_place): Typo.
|
||||
* src/ArgHandler.py (ArgHandler.cl_export): Do not strip path from
|
||||
the media oject references.
|
||||
|
||||
2006-02-13 Stefan Bjork <skalman@acc.umu.se>
|
||||
* src/po/sv.po: Minor update.
|
||||
|
||||
2006-02-12 Don Allingham <don@gramps-project.org>
|
||||
* src/EventEdit.py: don't report the false "new event added" message
|
||||
* src/EditPerson.py: display LDS temple correctly
|
||||
* src/plugins/NavWebpage.py: print nickname
|
||||
|
||||
2006-02-12 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
|
||||
* src/po/Makefile.am (.po.mo): Allow for parallel building.
|
||||
|
||||
2006-02-12 Alex Roitman <shura@gramps-project.org>
|
||||
* src/plugins/ReadPkg.py (impData): Use persistent directory for
|
||||
unpacking the tarball: we need images to stay there.
|
||||
|
||||
* src/AddrEdit.py: Make preformatetd note appear without wrapping.
|
||||
* src/EditPerson.py: No wrapping for preformatted notes.
|
||||
* src/EditPlace.py: No wrapping for preformatted notes.
|
||||
* src/EditSource.py: No wrapping for preformatted notes.
|
||||
* src/EventEdit.py: No wrapping for preformatted notes.
|
||||
* src/ImageSelect.py: No wrapping for preformatted notes.
|
||||
* src/NameEdit.py: No wrapping for preformatted notes.
|
||||
* src/Marriage.py: No wrapping for preformatted notes.
|
||||
|
||||
2006-02-11 Don Allingham <don@gramps-project.org>
|
||||
* src/GrampsMime.py: detect directory type
|
||||
* src/ImageSelect.py: don't allow directory types to be added
|
||||
* src/MediaView.py: don't allow directory types to be added
|
||||
|
||||
2006-02-11 Alex Roitman <shura@gramps-project.org>
|
||||
* src/DbPrompter.py (open_native): Use empty GRDB when opening fails.
|
||||
|
||||
2006-02-10 Alex Roitman <shura@gramps-project.org>
|
||||
* src/plugins/DetDescendantReport.py
|
||||
(DetDescendantReport.write_endnotes): Disable writing reference
|
||||
details.
|
||||
* src/plugins/DetAncestralReport.py
|
||||
(DetAncestorReport.write_endnotes): Disable writing reference details.
|
||||
* src/docgen/ODFDoc.py: Typo.
|
||||
|
||||
2006-02-09 Alex Roitman <shura@gramps-project.org>
|
||||
* src/WriteGedcom.py (write_sources): Export data_map.
|
||||
|
||||
2006-02-09 Alexandre Prokoudine <alexandre.prokoudine@gmail.com>
|
||||
* src/data/gramps.desktop: Improve Russian string, add Office
|
||||
category.
|
||||
|
||||
2006-02-08 Alex Roitman <shura@gramps-project.org>
|
||||
* src/plugins/Leak.py (display): Catch exception coming from
|
||||
trying to call __repr__ on a closed db.DB.
|
||||
* src/gramps.glade: Correct +/- tooltips for Data tab in Source Editor.
|
||||
* src/WriteGedcom.py (write_source_ref): Write confidence level
|
||||
(the QUAY tag) of the source reference into GEDCOM.
|
||||
* src/QuestionDialog.py (MissingMediaDialog): Catch delete event
|
||||
and warn the user.
|
||||
* src/Utils.py (ProgressMeter) Catch delete event and warn the user.
|
||||
|
||||
2006-01-26 Brian Matherly <pez4brian@users.sourceforge.net>
|
||||
* src/plugins/FamilyGroup.py: correctly put borders on the
|
||||
children cells.
|
||||
|
||||
2006-02-05 Alex Roitman <shura@gramps-project.org>
|
||||
* src/docgen/ODFDoc.py: Correct typos.
|
||||
|
||||
2006-02-02 Alex Roitman <shura@gramps-project.org>
|
||||
* src/GrampsBSDDB.py (rebuild_secondary): properly rebuild
|
||||
secondary indices relying on BSD DB rather than manually re-adding
|
||||
every record.
|
||||
* src/plugins/Rebuild.py (__init__): Use fixed 7 progress steps
|
||||
for 1 removing step and 6 index rebuilds.
|
||||
|
||||
2006-01-26 Brian Matherly <pez4brian@users.sourceforge.net>
|
||||
* src/docgen/ODFDoc.py (init): Correct name for parent style;
|
||||
Use handling program name obtained from the mime system.
|
||||
|
||||
2006-01-25 Serge Noiraud <Serge.Noiraud@free.fr>
|
||||
* src/docgen/ODFDoc.py: Add new document generator.
|
||||
* src/docgen/Makefile.am: Ship new file.
|
||||
* src/po/fr.po, src/po/template.po: Add new format's name.
|
||||
|
||||
2006-01-25 Kees Bakker <kees.bakker@xs4all.nl>
|
||||
* src/po/nl.po: Translation update.
|
||||
|
||||
2006-01-25 Brian Matherly <pez4brian@users.sourceforge.net>
|
||||
* src/plugings/FamiyGroup.py: options for "Recursive", "Generation
|
||||
Number", "Parent Events", "Parent Addresses", "Parent Alternate
|
||||
Names", "Parent Notes".
|
||||
|
||||
2006-01-18 Brian Matherly <pez4brian@yahoo.com>
|
||||
* src/plugins/DetDescendantReport.py: include spouse option
|
||||
|
||||
2006-01-16 Alex Roitman <shura@gramps-project.org>
|
||||
* src/GenericFilter.py
|
||||
(IsLessThanNthGenerationAncestorOfBookmarked): Typo.
|
||||
* src/EditPlace.py, src/EditSource.py, src/ImageSelect.py: Provide
|
||||
default value for the second argument on close().
|
||||
|
||||
2006-01-15 Don Allingham <don@gramps-project.org>
|
||||
* src/RelLib.py: improve Event is_equal method
|
||||
|
||||
2006-01-11 Stefan Bjork <skalman@acc.umu.se>
|
||||
* src/plugins/DetAncestralReport.py: Calculate age for indiviuals.
|
||||
* src/po/sv.po: Updates.
|
||||
|
||||
2006-01-05 Alex Roitman <shura@gramps-project.org>
|
||||
* doc/man, doc/man/fr: Add directories.
|
||||
* doc/man/Makefile.am, doc/man/fr/Makefile.am: Add files to CVS.
|
||||
* configure: Generate makefiles for new directories.
|
||||
* doc/man/gramps.1.in: move from doc.
|
||||
* doc/Makefile.am: Remove stuff related to man pages.
|
||||
|
||||
2006-01-05 Jérôme Rapinat <romjerome@yahoo.fr>
|
||||
* doc/man/fr/gramps.1.in: Add translated manpage.
|
||||
|
||||
2006-01-05 Stefan Bjork <skalman@acc.umu.se>
|
||||
* src/po/sv.po: Updates.
|
||||
|
||||
2006-01-03 Alex Roitman <shura@gramps-project.org>
|
||||
* src/gedcomimport.glade: Make dialog non-resizable.
|
||||
|
||||
2006-01-01 Don Allingham <don@gramps-project.org>
|
||||
* doc/gramps-manual/C/usage.xml: more updates
|
||||
|
||||
2005-12-07 Benny Malengier <bm@cage.UGent.be>
|
||||
* src/dates/Date_nl.py: fix index for "merz"
|
||||
|
||||
2005-12-22 Alex Roitman <shura@gramps-project.org>
|
||||
* src/GrampsBSDDB.py (GrampsBSDDBCursor): add delete method;
|
||||
(GrampsBSDDBDupCursor): Add class to handle duplicates.
|
||||
* src/plugins/Check.py: Avoid cursors when modifying data;
|
||||
(low_level): Add a low level repair routine, bypassing transactions.
|
||||
|
||||
2005-12-21 Don Allingham <don@gramps-project.org>
|
||||
* src/ReadGedcom.py: handle overlapping on source and family ID values
|
||||
|
||||
2005-12-17 Don Allingham <don@gramps-project.org>
|
||||
* doc/gramps-manual/C/usage.xml: updates
|
||||
|
||||
2005-12-17 Alex Roitman <shura@gramps-project.org>
|
||||
* src/GrampsDbBase.py (transaction_commit): Typo.
|
||||
|
||||
2005-12-16 Don Allingham <don@gramps-project.org>
|
||||
* doc/gramps-manual/C/usage.xml: updates
|
||||
* doc/gramps-manual/C/mainwin.xml: updates
|
||||
|
||||
2005-12-14 Don Allingham <don@gramps-project.org>
|
||||
* doc/gramps-manual/C/getstart.xml: updates
|
||||
* doc/gramps-manual/C/mainwin.xml: updates
|
||||
|
||||
2005-12-14 Alex Roitman <shura@gramps-project.org>
|
||||
* src/plugins/PatchNames.py: Fix title/name mixup, only detect new
|
||||
title, keep old title, keep old prefix.
|
||||
* src/plugins/DescendReport.py (dump): Initialize child list for
|
||||
each family.
|
||||
|
||||
2005-12-12 Alex Roitman <shura@gramps-project.org>
|
||||
* configure.in: bump up the version number.
|
||||
|
||||
2005-12-11 Don Allingham <don@gramps-project.org>
|
||||
* Release: Version 2.0.9 "Nobody expects the Spanish inquisition!"
|
||||
released.
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
Version 2.0.10 -- the "Holy Hand Grenade of Antioch" release
|
||||
* Date handler for Lithuanian language (Arturas Sleinius).
|
||||
* New Calendar graphical report (Doug Blank).
|
||||
* Multiple tool fixes.
|
||||
* GEDCOM import and export improvements.
|
||||
* Proper rebuilding of secondary indices.
|
||||
* Open Document Format support in reports (Serge Noiraud, Brian Matherly).
|
||||
* Multiple report fixes.
|
||||
* Fix for low-level duplicate records.
|
||||
* User Manual updates.
|
||||
* An insane number of bug fixes.
|
||||
|
||||
Version 2.0.9 -- the "Nobody expects the Spanish inquisition!" release
|
||||
* Incremental interface improvements.
|
||||
* Automated testing added, based on the CLI functionality.
|
||||
|
||||
@@ -4,12 +4,12 @@ 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.9, gramps-bugs@lists.sourceforge.net)
|
||||
AC_INIT(gramps, 2.0.11, 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 '-')
|
||||
dnl RELEASE=1
|
||||
dnl RELEASE=0.RC2
|
||||
dnl RELEASE=0.RC1
|
||||
|
||||
VERSIONSTRING=$VERSION
|
||||
if test x"$RELEASE" != "x"
|
||||
@@ -259,6 +259,8 @@ src/data/Makefile
|
||||
src/data/templates/Makefile
|
||||
src/po/Makefile
|
||||
doc/Makefile
|
||||
doc/man/Makefile
|
||||
doc/man/fr/Makefile
|
||||
doc/gramps-manual/Makefile
|
||||
doc/gramps-manual/C/Makefile
|
||||
doc/gramps-manual/fr/Makefile
|
||||
|
||||
+2
-11
@@ -1,13 +1,4 @@
|
||||
# Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = gramps-manual
|
||||
|
||||
man_IN_FILES = gramps.1.in
|
||||
man_MANS = $(man_IN_FILES:.1.in=.1)
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(man_IN_FILES) xmldocs.make omf.make
|
||||
|
||||
gramps.1: $(top_builddir)/config.status gramps.1.in
|
||||
cd $(top_builddir) && CONFIG_FILES=doc/$@ $(SHELL) ./config.status
|
||||
|
||||
CLEANFILES=$(man_MANS)
|
||||
SUBDIRS = gramps-manual man
|
||||
EXTRA_DIST = xmldocs.make omf.make
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
of Linux to another. On the default GNOME desktop, you'll
|
||||
find &app; in the
|
||||
<menuchoice><guimenu>Applications</guimenu><guisubmenu>Other</guisubmenu></menuchoice>
|
||||
menu. </para>
|
||||
menu.</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -116,8 +116,7 @@
|
||||
<screenshot>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="figures/researcher.png" format="PNG"
|
||||
width="510" depth="369" scale="75"/>
|
||||
<imagedata fileref="figures/researcher.png" format="PNG"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>Shows Researcher Information Window. </phrase>
|
||||
@@ -166,8 +165,7 @@
|
||||
|
||||
<para>To open a database that you have recently opened, choose the
|
||||
top selection, select your database from the menu and
|
||||
click <guibutton>OK</guibutton>. &app; will then ask you to specify
|
||||
the name of the database you wish to open. </para>
|
||||
click <guibutton>OK</guibutton>.</para>
|
||||
|
||||
<para>To open an existing database you have not recently opened,
|
||||
choose the middle selection and click
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -101,7 +101,7 @@
|
||||
immediately applied; this means that clicking
|
||||
<guibutton>OK</guibutton> in the Person, Family, Source,
|
||||
Place, Media object, or Event editor immediately records
|
||||
changes in the database. </para>
|
||||
changes to the database. </para>
|
||||
|
||||
<para>In previous versions, you could "quit without
|
||||
saving." This option no longer exists per se; however,
|
||||
@@ -177,7 +177,7 @@
|
||||
<para>Removal of the Save function and addition of Undo.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Proper window management and removal of most modal windows.</para>
|
||||
<para>Proper window management.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Support for Tip of the Day.</para>
|
||||
@@ -229,7 +229,7 @@
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>It is possible to generate reports from the command
|
||||
line, without launching the interactive GRAMPS
|
||||
line, without launching an interactive GRAMPS
|
||||
session.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
||||
+1740
-1659
File diff suppressed because it is too large
Load Diff
@@ -1485,7 +1485,7 @@
|
||||
</variablelist>
|
||||
</sect3>
|
||||
<sect3 id="cmdplug-id29">
|
||||
<title>Mémoriser le genre de statistiques ???</title>
|
||||
<title>Tableau statistique croisé du prénom et du sexe</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><command>name</command>:</term>
|
||||
|
||||
@@ -2285,7 +2285,119 @@ directement vers n'importe quelle personne sélectionnée récemment.
|
||||
</para>
|
||||
|
||||
|
||||
<!-- =============== Usage Sub-subsection ================ -->
|
||||
<!-- =============== Usage Sub-subsection ================ -->
|
||||
|
||||
<sect2 id="subst-values">
|
||||
<title>Valeurs de substitution</title>
|
||||
<para>
|
||||
La plupart des rapports graphiques vous permettent de personnaliser les informations affichées. Les variables de substitution sont représentées par des symboles particuliers. Il existe 2 styles de variables
|
||||
Leurs différences se trouvent dans la gestion des données vides.
|
||||
</para>
|
||||
<para>
|
||||
Le premier style est une variable précédée par '$'. Si cette variable se rapporte à une chaîne vide alors elle sera remplacée par une chaîne vide. Le second style est une variable précédée par '%'. Si cette variable se rapporte à une chaîne vide alors la ligne contenant la variable sera retirée lors de la sortie.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>$n/%n</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le nom de l'individu : Prénom Nom
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$N/%N</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le nom de l'individu : Nom Prénom
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$i/%i</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche l'ID GRAMPS associé à l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$b/%b</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche la date de naissance de l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$B/%B</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le lieu de naissance de l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$d/%d</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche la date de décès de l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$D/%D</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le lieu de décès de l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$s/%s</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le nom du conjoint préféré : Prénom Nom
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$S/%S</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le nom du conjoint préféré : Nom Prénom
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$m/%m</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche la date de marriage de l'individu et de son conjoint préféré.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$M/%M</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le lieu du marriage de l'individu et de son conjoint préféré.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="rep-books">
|
||||
<title>Livres</title>
|
||||
<para>Il n'y a actuellement qu'une seule édition dans cette catégorie : l'édition Livre. </para>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
gramps.1
|
||||
Makefile.in
|
||||
Makefile
|
||||
@@ -0,0 +1,13 @@
|
||||
# Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = fr
|
||||
|
||||
man_IN_FILES = gramps.1.in
|
||||
man_MANS = $(man_IN_FILES:.1.in=.1)
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(man_IN_FILES)
|
||||
|
||||
gramps.1: $(top_builddir)/config.status gramps.1.in
|
||||
cd $(top_builddir) && CONFIG_FILES=doc/man/$@ $(SHELL) ./config.status
|
||||
|
||||
CLEANFILES=$(man_MANS)
|
||||
@@ -0,0 +1,3 @@
|
||||
gramps.1
|
||||
Makefile.in
|
||||
Makefile
|
||||
@@ -0,0 +1,13 @@
|
||||
# Process this file with automake to produce Makefile.in
|
||||
|
||||
man_IN_FILES = gramps.1.in
|
||||
man_MANS = $(man_IN_FILES:.1.in=.1)
|
||||
|
||||
mandir = @mandir@/fr
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(man_IN_FILES)
|
||||
|
||||
gramps.1: $(top_builddir)/config.status gramps.1.in
|
||||
cd $(top_builddir) && CONFIG_FILES=doc/man/fr/$@ $(SHELL) ./config.status
|
||||
|
||||
CLEANFILES=$(man_MANS)
|
||||
@@ -0,0 +1,214 @@
|
||||
.TH gramps 1 "@VERSION@" "Janvier 2006" "@VERSION@"
|
||||
.SH NOM
|
||||
gramps \- GRAMPS est une application de généalogie. GRAMPS est l'acronyme de Genealogical Research and Analysis Management Programming System (Systeme de Programmation pour Recherche, Analyse et Gestion de données généalogiques)
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B gramps
|
||||
.RB [ \-?|\-\^\-help ]
|
||||
.RB [ \-\^\-usage ]
|
||||
.RB [ \-\^\-version ]
|
||||
.RB [ \-O|\-\^\-open=
|
||||
.IR FICHIER
|
||||
.RB [ \-f|\-\^\-format=
|
||||
.IR FORMAT ]]
|
||||
.RB [ \-i|\-\^\-import=
|
||||
.IR FICHIER
|
||||
.RB [ \-f|\-\^\-format=
|
||||
.IR FORMAT ]]
|
||||
.RB [ \-i|\-\^\-import=
|
||||
.IR ... ]
|
||||
.RB [ \-o|\-\^\-output=
|
||||
.IR FICHIER
|
||||
.RB [ \-f|\-\^\-format=
|
||||
.IR FORMAT ]]
|
||||
.RB [ \-a|\-\^\-action=
|
||||
.IR ACTION ]
|
||||
.RB [ \-p|\-\^\-options=
|
||||
.IR OPTIONSTRING ]]
|
||||
.RB [
|
||||
.IR FICHIER
|
||||
.RB ]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fIGramps\fP est un programme Libre/OpenSource de généalogie. Il est écrit en python,
|
||||
et utilise une interface GTK+/GNOME.
|
||||
Gramps est semblable à d'autres programmes de généalogie tel que \fIFamily Tree Maker (FTM)\fR, \fIPersonal Ancestral
|
||||
Files\fR, ou le programme GNU Geneweb.
|
||||
Il peut importer/exporter le format le plus utilisé par les autres logiciels de généalogie : GEDCOM.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI gramps " FICHIER"
|
||||
Si \fIFICHIER\fR est désigné (sans autres commandes) alors une session interactive est ouverte. Les autres options sont ignorées. Ce type de lancement permet d'utiliser gramps
|
||||
pour manipuler des données comme dans un navigateur web. Les formats natifs de gramps sont acceptés, voir ci-dessous.
|
||||
.br
|
||||
|
||||
.TP
|
||||
.BI \-f,\-\^\-format= " FORMAT"
|
||||
Le format spécifique du \fIFICHIER\fR est précédé par les options \fB\-O\fR,
|
||||
\fB\-i\fR, ou
|
||||
\fB\-o\fR. Si l'option \fB\-f\fR n'est pas donnée pour le \fIFICHIER\fR, alors le format sera celui de l'extension.
|
||||
.br
|
||||
|
||||
Les formats disponibles pour l'ouverture sont \fBgrdb\fR (choisi si \fIFICHIER\fR se termine par
|
||||
\fB.grdb\fR), \fBgramps\-xml\fR (choisi si \fIFICHIER\fR se termine par
|
||||
\fB.gramps\fR), et \fBgedcom\fR (choisi si \fIFICHIER\fR se termine par \fB.ged\fR).
|
||||
.br
|
||||
|
||||
Les formats disponibles pour l'importation sont \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR,
|
||||
\fBgramps\-pkg\fR (choisi si \fIFICHIER\fR se termine par \fB.gpkg\fR), et
|
||||
\fBgeneweb\fR (choisi si \fIFICHIER\fR se termine par \fB.gw\fR).
|
||||
.br
|
||||
|
||||
Les formats disponibles pour l'exportation sont \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR,
|
||||
\fBgramps\-pkg\fR, \fBwft\fR (choisi si \fIFICHIER\fR se termine par \fB.wft\fR),
|
||||
\fBgeneweb\fR, et \fBiso\fR (jamais deviné, toujours spécifié avec l'option
|
||||
\fB\-f\fR).
|
||||
|
||||
.TP
|
||||
.BI \-O,\-\^\-open= " FICHIER"
|
||||
Ouvrir un \fIFICHIER\fR.
|
||||
Seulement les formats \fBgrdb\fR, \fBgramps\-xml\fR, et \fBgedcom\fR peuvent être ouvert directement. Pour les autres formats, vous devez utiliser l'option d'import,
|
||||
laquelle ouvrira une base vide et importera les données.
|
||||
.br
|
||||
|
||||
Seulement un fichier peut être ouvert. Si vous utilisez plusieurs sources, vous devez utiliser l'option d'import.
|
||||
|
||||
.TP
|
||||
.BI \-i,\-\^\-import= " FICHIER"
|
||||
Importer des données depuis un \fIFICHIER\fR.
|
||||
.br
|
||||
|
||||
Quand plus d'un fichier doit être importé, chacun doit être précédé par la commande \fB\-i\fR. Ces fichiers sont importés dans le même ordre,
|
||||
i.e. \fB\-i\fR \fIFICHIER1\fR \fB\-i\fR \fIFICHIER2\fR
|
||||
et \fB\-i\fR \fIFICHIER2\fR \fB\-i\fR \fIFICHIER1\fR vont tous les deux produire différents IDs gramps.
|
||||
|
||||
.TP
|
||||
.BI \-o,\-\^\-output= " FICHIER"
|
||||
Exporter des données dans un \fIFICHIER\fR. Pour le format \fBiso\fR, le \fIFICHIER\fR est le nom du répertoire dans lequel la base de données gramps est écrite.
|
||||
Pour \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR, \fBwft\fR, \fBgramps\-pkg\fR,
|
||||
et \fBgeneweb\fR, le \fIFICHIER\fR est le nom du fichier de sortie
|
||||
.br
|
||||
|
||||
Quand plus d'un fichier doit être exporté, chacun doit être précédé par la commande \fB\-o\fR. Ces fichiers sont importés dans le même ordre.
|
||||
|
||||
.TP
|
||||
.BI \-a,\-\^\-action= " ACTION"
|
||||
Accomplir une \fIACTION\fR sur les données importées. C'est effectué à la fin de l'importation. Les actions possibles sont \fBsummary\fR
|
||||
(Comme le rapport->Affichage->Résumé?), \fBcheck\fR (comme l'outil->Réparation de la base->Vérifier et réparer), et \fBreport\fR (produit un rapport, à besoin
|
||||
de \fIOPTIONSTRING\fR précédé par la commande \fB\-p\fR.
|
||||
.br
|
||||
|
||||
Ces options de rapport doivent satisfaire ces conditions:
|
||||
.br
|
||||
Il ne doit pas y avoir d'espace.
|
||||
Si certains arguments doivent utiliser des espaces, la chaîne doit être encadrée par des guillemets.
|
||||
Les options vont par paire nom et valeur.
|
||||
Une paire est séparée par un signe égal.
|
||||
Différentes paires sont séparées par une virgule.
|
||||
.br
|
||||
|
||||
La plupart des options sont spécifiques à chaque rapport. Même s'il existe des options communes.
|
||||
|
||||
.BI "name=reportname "
|
||||
.br
|
||||
Cette option obligatoire, elle détermine quel rapport sera généré. Si le nom du rapport saisi ne correspond à aucun rapport disponible, un message d'erreur sera ajouté.
|
||||
|
||||
.BI "show=all"
|
||||
.br
|
||||
Cette option produit une liste avec les noms des options disponibles pour un rapport donné.
|
||||
|
||||
.BI "show=optionname"
|
||||
.br
|
||||
Cette option affiche une description de toutes les fonctionnalités proposées par optionname, aussi bien les types que les valeurs pour une option.
|
||||
|
||||
.br
|
||||
Utiliser les options ci-dessus pour trouver tout sur un rapport choisi.
|
||||
|
||||
.LP
|
||||
Quand plus d'une action doit être effectuée, chacune doit être précédée par la commande \fB\-a\fR. Les actions seront réalisées une à une, dans l'ordre spécifié.
|
||||
|
||||
.BI "Operation"
|
||||
.br
|
||||
Si le premier argument de la ligne de commande ne commence pas par un tiret (i.e. pas
|
||||
d'instruction), gramps va essayer d'ouvrir le fichier avec le nom donné par le premier argument et démarrer une session interactive, en ignorant le reste de la ligne de commande.
|
||||
|
||||
.LP
|
||||
Si la commande \fB\-O\fR est notée, alors gramps va essayer le fichier défini et va travailler avec ses données, comme pour les autres paramètres de la ligne de commande.
|
||||
|
||||
.LP
|
||||
Avec ou sans la commande \fB\-O\fR, il peut y avoir plusieurs imports, exports, et actions dans la ligne de commande \fB\-i\fR,
|
||||
\fB\-o\fR, et \fB\-a\fR.
|
||||
|
||||
.LP
|
||||
L'ordre des options \fB\-i\fR, \fB\-o\fR, ou \fB\-a\fR n'a pas de sens. L'ordre actuel est toujours : imports -> actions -> exports. Mais l'ouverture doit toujours être la première!
|
||||
|
||||
.LP
|
||||
Si aucune option \fB\-O\fR ou \fB\-i\fR n'est donnée, gramps lancera sa propre fenêtre et demarrera avec une base vide, puisqu'il n'y a pas données.
|
||||
|
||||
.LP
|
||||
Si aucune option \fB\-o\fR ou \fB\-a\fR n'est donnée, gramps lancera sa propre fenêtre et démarrera avec la base de données issue de tout les imports. Cette base sera \fBimport_db.grdb\fR sous le répertoire \fB~/.gramps/import\fR.
|
||||
|
||||
.LP
|
||||
Les erreurs rencontrées lors d'import, export, ou action, seront mémorisées en \fIstdout\fR (si elles sont le fait de la manipulation par gramps) ou
|
||||
en \fIstderr\fR (si elles ne sont pas le fait d'une manipulation). Utilisez les shell de redirection de
|
||||
\fIstdout\fR et \fIstderr\fR pour sauver les messages et les erreurs dans les fichiers.
|
||||
|
||||
.SH EXEMPLES
|
||||
.TP
|
||||
Lecture de quatre bases de données dont les formats peuvent être devinés d'après les noms, puis vérification des données:
|
||||
\fBgramps\fR \fB\-i\fR \fIfile1.ged\fR \fB\-i\fR \fIfile2.tgz\fR \fB\-i\fR \fI~/db3.gramps\fR \fB\-i\fR \fIfile4.wft\fR \fB\-a\fR \fIcheck\fR
|
||||
.TP
|
||||
Si vous voulez préciser les formats de fichiers dans l'exemple ci-dessus, complétez les noms de fichiers par les options \fB\-f\fR appropriées:
|
||||
\fBgramps\fR \fB\-i\fR \fIfile1.ged\fR \fB\-f\fR \fIgedcom\fR \fB\-i\fR \fIfile2.tgz\fR \fB\-f\fR \fIgramps-pkg\fR \fB\-i\fR \fI~/db3.gramps\fR \fB\-f\fR \fIgramps-xml\fR \fB\-i\fR \fIfile4.wft\fR \fB\-f\fR \fIwft\fR \fB\-a\fR \fIcheck\fR
|
||||
.TP
|
||||
Pour enregistrer le résultat des lectures, donnez l'option \fB\-o\fR (utiliser \fB\-f\fR si le nom de fichier ne permet pas à gramps de deviner le format):
|
||||
\fBgramps\fR \fB\-i\fR \fIfile1.ged\fR \fB\-i\fR \fIfile2.tgz\fR \fB\-o\fR \fI~/new-package\fR \fB\-f\fR \fIgramps-pkg\fR
|
||||
.TP
|
||||
Pour lire trois ensembles de données puis lancer une session interactive de gramps sur le tout :
|
||||
\fBgramps\fR \fB\-i\fR \fIfile1.ged\fR \fB\-i\fR \fIfile2.tgz\fR \fB\-i\fR \fI~/db3.gramps\fR
|
||||
.TP
|
||||
Enfin, pour lancer une session interactive normale, entrer : \fBgramps\fR
|
||||
|
||||
.SH CONCEPTS
|
||||
GRAMPS est un système basé sur le support de plugin-python, permettant d'importer et d'exporter, la saisie,
|
||||
générer des rapports, des outils, et afficher des filtres pouvant être ajoutés sans modifier le programme.
|
||||
.LP
|
||||
Par ailleurs, gramps permet la génération directe : impression, rapports avec sortie vers d'autres formats, comme \fIOpenOffice.org\fR, \fIAbiWord\fR, HTML,
|
||||
ou LaTeX pour permettre à l'utilisateur de choisir selon ses besoins
|
||||
|
||||
.SH BUGS CONNUS ET LIMITATIONS
|
||||
|
||||
.SH FICHIERS
|
||||
.LP
|
||||
\fI${PREFIX}/bin/gramps\fP
|
||||
.br
|
||||
\fI${PREFIX}/share/gramps\fP
|
||||
.br
|
||||
\fI${HOME}/.gramps\fP
|
||||
|
||||
.SH AUTEURS
|
||||
Donald Allingham \fI<don@gramps-project.org>\fR
|
||||
.br
|
||||
\fIhttp://gramps.sourceforge.net\fR
|
||||
.LP
|
||||
Cette page man a d'abord été écrite par:
|
||||
.br
|
||||
Brandon L. Griffith \fI<brandon@debian.org>\fR
|
||||
.br
|
||||
pour Debian GNU/Linux système.
|
||||
.LP
|
||||
Cette page man est maintenue par:
|
||||
.br
|
||||
Alex Roitman \fI<shura@gramps-project.org>\fR
|
||||
.LP
|
||||
La traduction française:
|
||||
.br
|
||||
Jérôme Rapinat \fI<romjerome@yahoo.fr>\fR
|
||||
.br
|
||||
|
||||
.SH DOCUMENTATION
|
||||
La documentation-utilisateur est disponible par le navigateur d'aide de GNOME sous la forme du manuel Gramps. Ce manuel est également disponible sous format XML comme \fBgramps-manual.xml\fR sous \fIdoc/gramps-manual/$LANG\fR dans les sources officielles.
|
||||
.LP
|
||||
La documentation pour développeur est disponible sur le site \fIhttp://developers.gramps-project.org\fR.
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2003 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
|
||||
+10
-1
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -139,8 +139,10 @@ class AddressEditor:
|
||||
Utils.bold_label(self.notes_label)
|
||||
if addr.get_note_format() == 1:
|
||||
self.preform.set_active(1)
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.flowed.set_active(1)
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
else:
|
||||
self.addr_date_obj = Date.Date()
|
||||
self.srcreflist = []
|
||||
@@ -162,6 +164,7 @@ class AddressEditor:
|
||||
okbtn.set_sensitive(not self.db.readonly)
|
||||
self.gladeif.connect('button129','clicked',self.on_help_clicked)
|
||||
self.gladeif.connect('notebook2','switch_page',self.on_switch_page)
|
||||
self.gladeif.connect('addr_preform','toggled',self.format_toggled)
|
||||
|
||||
if parent_window:
|
||||
self.window.set_transient_for(parent_window)
|
||||
@@ -238,6 +241,12 @@ class AddressEditor:
|
||||
self.callback(self.addr)
|
||||
self.close(obj)
|
||||
|
||||
def format_toggled(self,junk):
|
||||
if self.preform.get_active():
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
def check(self,get,set,data):
|
||||
"""Compares a data item, updates if necessary, and sets the
|
||||
parents lists_changed flag"""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -530,7 +530,7 @@ class ArgHandler:
|
||||
if filename:
|
||||
try:
|
||||
import WriteXML
|
||||
g = WriteXML.XmlWriter(self.parent.db,None,1,1)
|
||||
g = WriteXML.XmlWriter(self.parent.db,None,0,1)
|
||||
ret = g.write(filename)
|
||||
except:
|
||||
print "Error exporting %s" % filename
|
||||
|
||||
@@ -837,7 +837,7 @@ class LikelyFilter(GenericFilter.Rule):
|
||||
class LikelyFather(LikelyFilter):
|
||||
|
||||
name = _('Likely Father')
|
||||
description = _('Matches likely fathersn')
|
||||
description = _('Matches likely fathers')
|
||||
|
||||
def __init__(self,data_list):
|
||||
LikelyFilter.__init__(self,data_list,RelLib.Person.MALE)
|
||||
|
||||
+20
-19
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -138,29 +138,28 @@ class DbPrompter:
|
||||
top.show()
|
||||
response = top.run()
|
||||
top.hide()
|
||||
if response == gtk.RESPONSE_OK:
|
||||
if recent.get_active():
|
||||
try:
|
||||
try:
|
||||
if response == gtk.RESPONSE_OK:
|
||||
if recent.get_active():
|
||||
(filename,filetype) = self.recent_files[filelist.get_active()]
|
||||
if open_native(self.parent,filename,filetype):
|
||||
break
|
||||
except RuntimeError,msg:
|
||||
QuestionDialog.ErrorDialog(
|
||||
_("Could not open file: %s") % self.recent_file,
|
||||
str(msg))
|
||||
continue
|
||||
elif new.get_active():
|
||||
prompter = NewNativeDbPrompter(self.parent,
|
||||
self.parent_window)
|
||||
else:
|
||||
prompter = ExistingDbPrompter(self.parent,
|
||||
continue
|
||||
elif new.get_active():
|
||||
prompter = NewNativeDbPrompter(self.parent,
|
||||
self.parent_window)
|
||||
else:
|
||||
prompter = ExistingDbPrompter(self.parent,
|
||||
self.parent_window)
|
||||
if prompter.chooser():
|
||||
if prompter.chooser():
|
||||
break
|
||||
elif response == gtk.RESPONSE_CANCEL:
|
||||
break
|
||||
elif response == gtk.RESPONSE_CANCEL:
|
||||
break
|
||||
elif response == gtk.RESPONSE_HELP:
|
||||
GrampsDisplay.help('choose-db-start')
|
||||
elif response == gtk.RESPONSE_HELP:
|
||||
GrampsDisplay.help('choose-db-start')
|
||||
except:
|
||||
import sys
|
||||
QuestionDialog.ErrorDialog(_("Could not open file"),str(sys.exc_info()[1]))
|
||||
|
||||
top.destroy()
|
||||
if response == gtk.RESPONSE_CANCEL:
|
||||
@@ -599,6 +598,8 @@ def open_native(parent,filename,filetype):
|
||||
# Add the file to the recent items
|
||||
RecentFiles.recent_files(filename,filetype)
|
||||
parent.build_recent_menu()
|
||||
else:
|
||||
parent.db = GrampsBSDDB.GrampsBSDDB()
|
||||
|
||||
return success
|
||||
|
||||
|
||||
+46
-14
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -408,8 +408,10 @@ class EditPerson:
|
||||
self.notes_buffer.set_text(person.get_note())
|
||||
if person.get_note_object().get_format() == 1:
|
||||
self.preform.set_active(1)
|
||||
self.notes_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.flowed.set_active(1)
|
||||
self.notes_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
Utils.bold_label(self.notes_label)
|
||||
|
||||
self.set_list_dnd(self.name_list, self.name_drag_data_get,
|
||||
@@ -478,7 +480,8 @@ class EditPerson:
|
||||
self.gladeif.connect("button129", "clicked", self.on_ldsendow_note_clicked)
|
||||
self.gladeif.connect("button133", "clicked", self.on_ldsseal_source_clicked)
|
||||
self.gladeif.connect("button130", "clicked", self.on_ldsseal_note_clicked)
|
||||
|
||||
self.gladeif.connect('preform','toggled',self.format_toggled)
|
||||
|
||||
self.sourcetab = Sources.SourceTab(
|
||||
self.srcreflist, self, self.top, self.window, self.slist,
|
||||
self.top.get_widget('add_src'), self.top.get_widget('edit_src'),
|
||||
@@ -506,6 +509,12 @@ class EditPerson:
|
||||
|
||||
self.window.show()
|
||||
|
||||
def format_toggled(self,junk):
|
||||
if self.preform.get_active():
|
||||
self.notes_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.notes_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
def set_list_dnd(self,obj, get, begin, receive):
|
||||
obj.drag_dest_set(gtk.DEST_DEFAULT_ALL, [DdTargets.NAME.target()],
|
||||
ACTION_COPY)
|
||||
@@ -648,8 +657,10 @@ class EditPerson:
|
||||
|
||||
def lds_field(self,lds_ord,combo,date,place):
|
||||
build_combo(combo,_temple_names)
|
||||
temple_code = const.lds_temple_to_abrev.get(lds_ord.get_temple(),"")
|
||||
|
||||
temple_code = lds_ord.get_temple()
|
||||
index = _temple_names.index(temple_code)
|
||||
|
||||
combo.set_active(index)
|
||||
if not lds_ord.is_empty():
|
||||
stat = lds_ord.get_status()
|
||||
@@ -1096,11 +1107,32 @@ class EditPerson:
|
||||
def event_edit_callback(self,event):
|
||||
"""Birth and death events may not be in the map"""
|
||||
self.redraw_event_list()
|
||||
self.update_pdmap(event)
|
||||
try:
|
||||
self.etree.select_iter(self.emap[str(event)])
|
||||
except:
|
||||
pass
|
||||
|
||||
def update_pdmap(self,event):
|
||||
p = event.get_place_handle()
|
||||
if p:
|
||||
place = self.db.get_place_from_handle(p)
|
||||
self.pdmap[place.get_title()] = p
|
||||
|
||||
def event_birth_callback(self,event):
|
||||
"""Birth and death events may not be in the map"""
|
||||
self.update_birth = False
|
||||
self.birth = event
|
||||
self.update_birth_info()
|
||||
self.update_pdmap(event)
|
||||
|
||||
def event_death_callback(self,event):
|
||||
"""Birth and death events may not be in the map"""
|
||||
self.update_death = False
|
||||
self.death = event
|
||||
self.update_death_info()
|
||||
self.update_pdmap(event)
|
||||
|
||||
def attr_edit_callback(self,attr):
|
||||
self.redraw_attr_list()
|
||||
self.atree.select_iter(self.amap[str(attr)])
|
||||
@@ -1201,7 +1233,7 @@ class EditPerson:
|
||||
if p:
|
||||
event.set_place_handle(p)
|
||||
EventEdit.PersonEventEditor(self,pname, event, def_placename, True,
|
||||
self.event_edit_callback, noedit=self.db.readonly)
|
||||
self.event_birth_callback, noedit=self.db.readonly)
|
||||
|
||||
def on_edit_death_clicked(self,obj):
|
||||
"""Brings up the EventEditor for the death record, event
|
||||
@@ -1218,7 +1250,7 @@ class EditPerson:
|
||||
if p:
|
||||
event.set_place_handle(p)
|
||||
EventEdit.PersonEventEditor(self, pname, event, def_placename,
|
||||
True, self.event_edit_callback,
|
||||
True, self.event_death_callback,
|
||||
noedit=self.db.readonly)
|
||||
|
||||
def on_aka_delete_clicked(self,obj):
|
||||
@@ -1299,7 +1331,7 @@ class EditPerson:
|
||||
"""Check to see if any of the data has changed from the
|
||||
orig record"""
|
||||
|
||||
surname = unicode(self.surname.get_text())
|
||||
surname = unicode(self.surname.get_text().strip())
|
||||
self.birth_date_object = self.dp.parse(unicode(self.bdate.get_text()))
|
||||
self.death_date_object = self.dp.parse(unicode(self.ddate.get_text()))
|
||||
|
||||
@@ -1686,14 +1718,14 @@ class EditPerson:
|
||||
self.window.hide()
|
||||
trans = self.db.transaction_begin()
|
||||
|
||||
surname = unicode(self.surname.get_text())
|
||||
suffix = unicode(self.suffix.get_text())
|
||||
prefix = unicode(self.prefix.get_text())
|
||||
ntype = unicode(self.ntype_field.child.get_text())
|
||||
given = unicode(self.given.get_text())
|
||||
nick = unicode(self.nick.get_text())
|
||||
title = unicode(self.title.get_text())
|
||||
idval = unicode(self.gid.get_text())
|
||||
surname = unicode(self.surname.get_text().strip())
|
||||
suffix = unicode(self.suffix.get_text().strip())
|
||||
prefix = unicode(self.prefix.get_text().strip())
|
||||
ntype = unicode(self.ntype_field.child.get_text().strip())
|
||||
given = unicode(self.given.get_text().strip())
|
||||
nick = unicode(self.nick.get_text().strip())
|
||||
title = unicode(self.title.get_text().strip())
|
||||
idval = unicode(self.gid.get_text().strip())
|
||||
|
||||
name = self.pname
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -189,8 +189,10 @@ class EditPlace:
|
||||
Utils.bold_label(self.notes_label)
|
||||
if place.get_note_format() == 1:
|
||||
self.preform.set_active(1)
|
||||
self.note.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.flowed.set_active(1)
|
||||
self.note.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
self.flowed.set_sensitive(mode)
|
||||
self.preform.set_sensitive(mode)
|
||||
@@ -214,6 +216,7 @@ class EditPlace:
|
||||
self.gladeif.connect('web_edit', 'clicked', self.on_update_url_clicked)
|
||||
self.gladeif.connect('web_go', 'clicked', self.on_web_go_clicked)
|
||||
self.gladeif.connect('del_url', 'clicked', self.on_delete_url_clicked)
|
||||
self.gladeif.connect('place_preform','toggled',self.format_toggled)
|
||||
|
||||
self.sourcetab = Sources.SourceTab(
|
||||
self.srcreflist,self,
|
||||
@@ -259,6 +262,12 @@ class EditPlace:
|
||||
self.idle = gobject.idle_add(self.display_references)
|
||||
self.ref_not_loaded = 0
|
||||
|
||||
def format_toggled(self,junk):
|
||||
if self.preform.get_active():
|
||||
self.note.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.note.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
def build_pdmap(self):
|
||||
self.pdmap.clear()
|
||||
cursor = self.db.get_place_cursor()
|
||||
@@ -276,7 +285,7 @@ class EditPlace:
|
||||
self.remove_itself_from_menu()
|
||||
gc.collect()
|
||||
|
||||
def close(self,obj):
|
||||
def close(self,obj=None):
|
||||
self.glry.close()
|
||||
self.close_child_windows()
|
||||
self.remove_itself_from_menu()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -135,14 +135,16 @@ class EditSource:
|
||||
Utils.bold_label(self.notes_label)
|
||||
if source.get_note_format() == 1:
|
||||
self.preform.set_active(1)
|
||||
self.note.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.flowed.set_active(1)
|
||||
self.note.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
if self.source.get_media_list():
|
||||
Utils.bold_label(self.gallery_label)
|
||||
|
||||
self.gladeif.connect('sourceEditor','delete_event',self.on_delete_event)
|
||||
self.gladeif.connect('button90','clicked',self.close)
|
||||
self.gladeif.connect('cancel','clicked',self.close)
|
||||
self.gladeif.connect('ok','clicked',self.on_source_apply_clicked)
|
||||
self.gladeif.connect('button166','clicked',self.on_help_clicked)
|
||||
self.gladeif.connect('notebook2','switch_page',self.on_switch_page)
|
||||
@@ -152,6 +154,7 @@ class EditSource:
|
||||
self.gladeif.connect('sel_photo','clicked',self.gallery.on_select_media_clicked)
|
||||
self.gladeif.connect('edit_photo','clicked',self.gallery.on_edit_media_clicked)
|
||||
self.gladeif.connect('delete_photo','clicked',self.gallery.on_delete_media_clicked)
|
||||
self.gladeif.connect('source_preform','toggled',self.format_toggled)
|
||||
|
||||
if self.source.get_handle() == None or self.db.readonly:
|
||||
self.top_window.get_widget("edit_photo").set_sensitive(False)
|
||||
@@ -198,6 +201,12 @@ class EditSource:
|
||||
self.idle = gobject.idle_add(self.display_references)
|
||||
self.data_sel = self.datalist.get_selection()
|
||||
|
||||
def format_toggled(self,junk):
|
||||
if self.preform.get_active():
|
||||
self.note.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.note.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
def on_add_data_clicked(self,widget):
|
||||
node = self.data_model.append(row=['',''])
|
||||
self.data_sel.select_iter(node)
|
||||
@@ -227,7 +236,7 @@ class EditSource:
|
||||
"""Display the relevant portion of GRAMPS manual"""
|
||||
GrampsDisplay.help('adv-src')
|
||||
|
||||
def close(self,obj):
|
||||
def close(self,obj=None):
|
||||
self.gallery.close()
|
||||
self.close_child_windows()
|
||||
self.remove_itself_from_menu()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -204,8 +204,10 @@ class EventEditor:
|
||||
Utils.bold_label(self.notes_label)
|
||||
if event.get_note_format() == 1:
|
||||
self.preform.set_active(1)
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.flowed.set_active(1)
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
if event.get_media_list():
|
||||
Utils.bold_label(self.gallery_label)
|
||||
else:
|
||||
@@ -236,6 +238,7 @@ class EventEditor:
|
||||
self.gladeif.connect('sel_obj','clicked',self.gallery.on_select_media_clicked)
|
||||
self.gladeif.connect('button172','clicked',self.gallery.on_edit_media_clicked)
|
||||
self.gladeif.connect('del_obj','clicked',self.gallery.on_delete_media_clicked)
|
||||
self.gladeif.connect('eventpreform','toggled',self.format_toggled)
|
||||
|
||||
self.top.get_widget('del_obj').set_sensitive(not noedit)
|
||||
self.top.get_widget('sel_obj').set_sensitive(not noedit)
|
||||
@@ -248,6 +251,12 @@ class EventEditor:
|
||||
self.add_itself_to_menu()
|
||||
self.window.show()
|
||||
|
||||
def format_toggled(self,junk):
|
||||
if self.preform.get_active():
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
def on_delete_event(self,obj,b):
|
||||
self.gladeif.close()
|
||||
self.gallery.close()
|
||||
@@ -337,13 +346,13 @@ class EventEditor:
|
||||
edesc = unicode(self.descr_field.get_text())
|
||||
epriv = self.priv.get_active()
|
||||
|
||||
if ename not in self.elist + [_("Birth") , _("Death")]:
|
||||
WarningDialog(
|
||||
_('New event type created'),
|
||||
_('The "%s" event type has been added to this database.\n'
|
||||
'It will now appear in the event menus for this database') % ename)
|
||||
self.elist.append(ename)
|
||||
self.elist.sort()
|
||||
# if ename not in self.elist + [_("Birth") , _("Death")]:
|
||||
# WarningDialog(
|
||||
# _('New event type created'),
|
||||
# _('The "%s" event type has been added to this database.\n'
|
||||
# 'It will now appear in the event menus for this database') % ename)
|
||||
# self.elist.append(ename)
|
||||
# self.elist.sort()
|
||||
|
||||
if self.event == None:
|
||||
self.event = RelLib.Event()
|
||||
|
||||
@@ -67,7 +67,6 @@ from DdTargets import DdTargets
|
||||
_BORN = _('b.')
|
||||
_DIED = _('d.')
|
||||
|
||||
|
||||
column_names = [
|
||||
(_('#'),0) ,
|
||||
(_('ID'),1) ,
|
||||
|
||||
@@ -2038,7 +2038,7 @@ class IsLessThanNthGenerationAncestorOfBookmarked(Rule):
|
||||
name = _('Ancestors of bookmarked people not more '
|
||||
'than <N> generations away')
|
||||
category = _('Ancestral filters')
|
||||
description = _("Matches ancestors of the people on the bookmark list"
|
||||
description = _("Matches ancestors of the people on the bookmark list "
|
||||
"not more than N generations away")
|
||||
|
||||
def prepare(self,db):
|
||||
|
||||
+91
-82
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -69,6 +69,18 @@ class GrampsBSDDBCursor(GrampsCursor):
|
||||
def close(self):
|
||||
self.cursor.close()
|
||||
|
||||
def delete(self):
|
||||
self.cursor.delete()
|
||||
|
||||
class GrampsBSDDBDupCursor(GrampsBSDDBCursor):
|
||||
"""Cursor that includes handling for duplicate keys"""
|
||||
|
||||
def set(self,key):
|
||||
return self.cursor.set(str(key))
|
||||
|
||||
def next_dup(self):
|
||||
return self.cursor.next_dup()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GrampsBSDDB
|
||||
@@ -204,96 +216,88 @@ class GrampsBSDDB(GrampsDbBase):
|
||||
return 1
|
||||
|
||||
def rebuild_secondary(self,callback=None):
|
||||
openflags = db.DB_CREATE
|
||||
|
||||
# Repair secondary indices related to person_map
|
||||
|
||||
|
||||
# Repair secondary indices related to person_map
|
||||
self.id_trans.close()
|
||||
junk = db.DB(self.env)
|
||||
junk.remove(self.save_name,"idtrans")
|
||||
|
||||
self.surnames.close()
|
||||
junk = db.DB(self.env)
|
||||
junk.remove(self.save_name,"surnames")
|
||||
|
||||
# Repair secondary indices related to place_map
|
||||
self.pid_trans.close()
|
||||
junk = db.DB(self.env)
|
||||
junk.remove(self.save_name,"pidtrans")
|
||||
|
||||
# Repair secondary indices related to media_map
|
||||
self.oid_trans.close()
|
||||
junk = db.DB(self.env)
|
||||
junk.remove(self.save_name,"oidtrans")
|
||||
|
||||
# Repair secondary indices related to source_map
|
||||
self.sid_trans.close()
|
||||
junk = db.DB(self.env)
|
||||
junk.remove(self.save_name,"sidtrans")
|
||||
if callback:
|
||||
callback()
|
||||
|
||||
self.id_trans = db.DB(self.env)
|
||||
self.id_trans.set_flags(db.DB_DUP)
|
||||
self.id_trans.open(self.save_name, "idtrans", db.DB_HASH,
|
||||
flags=db.DB_CREATE)
|
||||
self.id_trans.truncate()
|
||||
self.id_trans.open(self.save_name, "idtrans",
|
||||
db.DB_HASH, flags=openflags)
|
||||
self.person_map.associate(self.id_trans, find_idmap, openflags)
|
||||
self.id_trans.sync()
|
||||
if callback:
|
||||
callback()
|
||||
|
||||
self.surnames = db.DB(self.env)
|
||||
self.surnames.set_flags(db.DB_DUP)
|
||||
self.surnames.open(self.save_name, "surnames", db.DB_HASH,
|
||||
flags=db.DB_CREATE)
|
||||
self.surnames.truncate()
|
||||
self.surnames.open(self.save_name, "surnames",
|
||||
db.DB_HASH, flags=openflags)
|
||||
self.person_map.associate(self.surnames, find_surname, openflags)
|
||||
self.surnames.sync()
|
||||
if callback:
|
||||
callback()
|
||||
|
||||
self.person_map.associate(self.surnames, find_surname, db.DB_CREATE)
|
||||
self.person_map.associate(self.id_trans, find_idmap, db.DB_CREATE)
|
||||
|
||||
for key in self.person_map.keys():
|
||||
if callback:
|
||||
callback()
|
||||
self.person_map[key] = self.person_map[key]
|
||||
self.person_map.sync()
|
||||
|
||||
# Repair secondary indices related to family_map
|
||||
|
||||
self.fid_trans.close()
|
||||
self.fid_trans = db.DB(self.env)
|
||||
self.fid_trans.set_flags(db.DB_DUP)
|
||||
self.fid_trans.open(self.save_name, "fidtrans", db.DB_HASH,
|
||||
flags=db.DB_CREATE)
|
||||
self.fid_trans.truncate()
|
||||
self.family_map.associate(self.fid_trans, find_idmap, db.DB_CREATE)
|
||||
self.fid_trans.open(self.save_name, "fidtrans",
|
||||
db.DB_HASH, flags=openflags)
|
||||
self.family_map.associate(self.fid_trans, find_idmap, openflags)
|
||||
self.fid_trans.sync()
|
||||
if callback:
|
||||
callback()
|
||||
|
||||
for key in self.family_map.keys():
|
||||
if callback:
|
||||
callback()
|
||||
self.family_map[key] = self.family_map[key]
|
||||
self.family_map.sync()
|
||||
|
||||
# Repair secondary indices related to place_map
|
||||
|
||||
self.pid_trans.close()
|
||||
self.pid_trans = db.DB(self.env)
|
||||
self.pid_trans.set_flags(db.DB_DUP)
|
||||
self.pid_trans.open(self.save_name, "pidtrans", db.DB_HASH,
|
||||
flags=db.DB_CREATE)
|
||||
self.pid_trans.truncate()
|
||||
self.place_map.associate(self.pid_trans, find_idmap, db.DB_CREATE)
|
||||
self.pid_trans.open(self.save_name, "pidtrans",
|
||||
db.DB_HASH, flags=openflags)
|
||||
self.place_map.associate(self.pid_trans, find_idmap, openflags)
|
||||
self.pid_trans.sync()
|
||||
if callback:
|
||||
callback()
|
||||
|
||||
for key in self.place_map.keys():
|
||||
if callback:
|
||||
callback()
|
||||
self.place_map[key] = self.place_map[key]
|
||||
self.place_map.sync()
|
||||
|
||||
# Repair secondary indices related to media_map
|
||||
|
||||
self.oid_trans.close()
|
||||
self.oid_trans = db.DB(self.env)
|
||||
self.oid_trans.set_flags(db.DB_DUP)
|
||||
self.oid_trans.open(self.save_name, "oidtrans", db.DB_HASH,
|
||||
flags=db.DB_CREATE)
|
||||
self.oid_trans.truncate()
|
||||
self.media_map.associate(self.oid_trans, find_idmap, db.DB_CREATE)
|
||||
|
||||
for key in self.media_map.keys():
|
||||
if callback:
|
||||
callback()
|
||||
self.media_map[key] = self.media_map[key]
|
||||
self.media_map.sync()
|
||||
|
||||
# Repair secondary indices related to source_map
|
||||
|
||||
self.sid_trans.close()
|
||||
self.sid_trans = db.DB(self.env)
|
||||
self.sid_trans.set_flags(db.DB_DUP)
|
||||
self.sid_trans.open(self.save_name, "sidtrans", db.DB_HASH,
|
||||
flags=db.DB_CREATE)
|
||||
self.sid_trans.truncate()
|
||||
self.source_map.associate(self.sid_trans, find_idmap, db.DB_CREATE)
|
||||
self.sid_trans.open(self.save_name, "sidtrans",
|
||||
db.DB_HASH, flags=openflags)
|
||||
self.source_map.associate(self.sid_trans, find_idmap, openflags)
|
||||
self.sid_trans.sync()
|
||||
if callback:
|
||||
callback()
|
||||
|
||||
for key in self.source_map.keys():
|
||||
if callback:
|
||||
callback()
|
||||
self.source_map[key] = self.source_map[key]
|
||||
self.source_map.sync()
|
||||
self.oid_trans = db.DB(self.env)
|
||||
self.oid_trans.set_flags(db.DB_DUP)
|
||||
self.oid_trans.open(self.save_name, "oidtrans",
|
||||
db.DB_HASH, flags=openflags)
|
||||
self.media_map.associate(self.oid_trans, find_idmap, openflags)
|
||||
self.oid_trans.sync()
|
||||
if callback:
|
||||
callback()
|
||||
|
||||
def abort_changes(self):
|
||||
while self.undo():
|
||||
@@ -851,7 +855,10 @@ class GrampsBSDDB(GrampsDbBase):
|
||||
for handle in handle_list:
|
||||
event = self.get_event_from_handle(handle)
|
||||
self.individual_event_names.add(event.name)
|
||||
data = cursor.next()
|
||||
try:
|
||||
data = cursor.next()
|
||||
except:
|
||||
data = None
|
||||
cursor.close()
|
||||
|
||||
cursor = self.get_family_cursor()
|
||||
@@ -863,7 +870,8 @@ class GrampsBSDDB(GrampsDbBase):
|
||||
# Check to prevent crash on corrupted data (event_list=None)
|
||||
for handle in handle_list:
|
||||
event = self.get_event_from_handle(handle)
|
||||
self.family_event_names.add(event.name)
|
||||
if event:
|
||||
self.family_event_names.add(event.name)
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
@@ -874,13 +882,14 @@ if __name__ == "__main__":
|
||||
d = GrampsBSDDB()
|
||||
d.load(sys.argv[1],lambda x: x)
|
||||
|
||||
c = d.get_person_cursor()
|
||||
data = c.first()
|
||||
while data:
|
||||
person = Person(data[1])
|
||||
print data[0], person.get_primary_name().get_name(),
|
||||
data = c.next()
|
||||
c.close()
|
||||
|
||||
print d.surnames.keys()
|
||||
## c = d.get_person_cursor()
|
||||
## data = c.first()
|
||||
## while data:
|
||||
## person = Person(data[1])
|
||||
## print data[0], person.get_primary_name().get_name(),
|
||||
## data = c.next()
|
||||
## c.close()
|
||||
|
||||
## print d.surnames.keys()
|
||||
|
||||
|
||||
@@ -1001,7 +1001,7 @@ class GrampsDbBase(GrampsDBCallback.GrampsDBCallback):
|
||||
transaction.set_description(msg)
|
||||
self.undoindex += 1
|
||||
if self.undoindex == _UNDO_SIZE:
|
||||
self.translist = transaction[0:-1] + [ transaction ]
|
||||
self.translist = self.translist[0:-1] + [ transaction ]
|
||||
else:
|
||||
self.translist[self.undoindex] = transaction
|
||||
|
||||
|
||||
@@ -59,3 +59,16 @@ def mime_type_is_defined(type):
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
def base_type(val):
|
||||
return val.split('/')[0]
|
||||
|
||||
def is_image_type(val):
|
||||
return base_type(val) == "image"
|
||||
|
||||
def is_directory(val):
|
||||
return base_type(val) == "x-directory"
|
||||
_invalid_mime_types = ('x-directory','x-special')
|
||||
|
||||
def is_valid_type(val):
|
||||
return base_type(val) not in _invalid_mime_types
|
||||
|
||||
+43
-11
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -169,6 +169,12 @@ class ImageSelect:
|
||||
filename = Utils.find_file( filename)
|
||||
if filename:
|
||||
mtype = GrampsMime.get_type(filename)
|
||||
if not GrampsMime.is_valid_type(mtype):
|
||||
ErrorDialog(_('Invalid file type'),
|
||||
_('An object of type %s cannot be added '
|
||||
'to a gallery') % mtype)
|
||||
return
|
||||
|
||||
if mtype and mtype.startswith("image"):
|
||||
image = RelImage.scale_image(filename,const.thumbScale)
|
||||
self.image.set_from_pixbuf(image)
|
||||
@@ -187,6 +193,8 @@ class ImageSelect:
|
||||
|
||||
internal = self.internal.get_active()
|
||||
|
||||
already_imported = None
|
||||
|
||||
if not internal:
|
||||
if os.path.exists(filename) == 0:
|
||||
msgstr = _("Cannot import %s")
|
||||
@@ -194,8 +202,6 @@ class ImageSelect:
|
||||
ErrorDialog(msgstr % filename, msgstr2)
|
||||
return
|
||||
|
||||
already_imported = None
|
||||
|
||||
for o_id in self.db.get_media_object_handles():
|
||||
o = self.db.get_object_from_handle(o_id)
|
||||
if o.get_path() == filename:
|
||||
@@ -209,12 +215,18 @@ class ImageSelect:
|
||||
self.add_thumbnail(oref)
|
||||
else:
|
||||
mtype = GrampsMime.get_type(filename)
|
||||
mobj = RelLib.MediaObject()
|
||||
if description == "":
|
||||
description = os.path.basename(filename)
|
||||
mobj.set_description(description)
|
||||
mobj.set_mime_type(mtype)
|
||||
mobj.set_path(filename)
|
||||
if GrampsMime.is_valid_type(mtype):
|
||||
mobj = RelLib.MediaObject()
|
||||
if description == "":
|
||||
description = os.path.basename(filename)
|
||||
mobj.set_description(description)
|
||||
mobj.set_mime_type(mtype)
|
||||
mobj.set_path(filename)
|
||||
else:
|
||||
ErrorDialog(_('Invalid file type'),
|
||||
_('An object of type %s cannot be added '
|
||||
'to a gallery') % mtype)
|
||||
return
|
||||
else:
|
||||
mobj = RelLib.MediaObject()
|
||||
mobj.set_description(description)
|
||||
@@ -493,6 +505,8 @@ class Gallery(ImageSelect):
|
||||
if protocol == "file":
|
||||
name = Utils.fix_encoding(mfile)
|
||||
mime = GrampsMime.get_type(name)
|
||||
if not GrampsMime.is_valid_type(mime):
|
||||
return
|
||||
photo = RelLib.MediaObject()
|
||||
photo.set_path(name)
|
||||
photo.set_mime_type(mime)
|
||||
@@ -769,8 +783,10 @@ class LocalMediaProperties:
|
||||
Utils.bold_label(self.notes_label)
|
||||
if self.photo.get_note_format() == 1:
|
||||
self.preform.set_active(1)
|
||||
self.notes.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.flowed.set_active(1)
|
||||
self.notes.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
self.gladeif = GladeIf(self.change_dialog)
|
||||
self.gladeif.connect('change_description','delete_event',self.on_delete_event)
|
||||
@@ -781,6 +797,7 @@ class LocalMediaProperties:
|
||||
self.gladeif.connect('button86','clicked',self.on_add_attr_clicked)
|
||||
self.gladeif.connect('button100','clicked',self.on_update_attr_clicked)
|
||||
self.gladeif.connect('button88','clicked',self.on_delete_attr_clicked)
|
||||
self.gladeif.connect('preform','toggled',self.format_toggled)
|
||||
|
||||
media_obj = self.db.get_object_from_handle(self.photo.get_reference_handle())
|
||||
gnote = self.change_dialog.get_widget('global_notes')
|
||||
@@ -794,13 +811,19 @@ class LocalMediaProperties:
|
||||
self.add_itself_to_menu()
|
||||
self.window.show()
|
||||
|
||||
def format_toggled(self,junk):
|
||||
if self.preform.get_active():
|
||||
self.notes.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.notes.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
def on_delete_event(self,obj,b):
|
||||
self.gladeif.close()
|
||||
self.close_child_windows()
|
||||
self.remove_itself_from_menu()
|
||||
gc.collect()
|
||||
|
||||
def close(self,obj):
|
||||
def close(self,obj=None):
|
||||
self.gladeif.close()
|
||||
self.close_child_windows()
|
||||
self.remove_itself_from_menu()
|
||||
@@ -1059,8 +1082,10 @@ class GlobalMediaProperties:
|
||||
Utils.bold_label(self.notes_label)
|
||||
if self.obj.get_note_format() == 1:
|
||||
self.preform.set_active(1)
|
||||
self.notes.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.flowed.set_active(1)
|
||||
self.notes.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
self.gladeif.connect('change_global','delete_event',
|
||||
self.on_delete_event)
|
||||
@@ -1072,6 +1097,7 @@ class GlobalMediaProperties:
|
||||
self.gladeif.connect('add_attr','clicked',self.on_add_attr_clicked)
|
||||
self.gladeif.connect('button101','clicked',self.on_update_attr_clicked)
|
||||
self.gladeif.connect('del_attr','clicked',self.on_delete_attr_clicked)
|
||||
self.gladeif.connect('global_preform','toggled',self.format_toggled)
|
||||
|
||||
for name in ['gl_del_src','gl_add_src','add_attr','del_attr','ok']:
|
||||
self.change_dialog.get_widget(name).set_sensitive(mode)
|
||||
@@ -1086,12 +1112,18 @@ class GlobalMediaProperties:
|
||||
self.cursor_type = None
|
||||
self.idle = gobject.idle_add(self.display_refs)
|
||||
|
||||
def format_toggled(self,junk):
|
||||
if self.preform.get_active():
|
||||
self.notes.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.notes.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
def on_delete_event(self,obj,b):
|
||||
self.close_child_windows()
|
||||
self.remove_itself_from_menu()
|
||||
gc.collect()
|
||||
|
||||
def close(self,obj):
|
||||
def close(self,obj=None):
|
||||
self.close_child_windows()
|
||||
self.remove_itself_from_menu()
|
||||
self.window.destroy()
|
||||
|
||||
+10
-1
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modiy
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -138,6 +138,7 @@ class Marriage:
|
||||
self.gladeif.connect('media_del','clicked',self.gallery.on_delete_media_clicked)
|
||||
self.gladeif.connect('button114','clicked',self.lds_src_clicked)
|
||||
self.gladeif.connect('button115','clicked',self.lds_note_clicked)
|
||||
self.gladeif.connect('mar_preform','toggled',self.format_toggled)
|
||||
|
||||
mode = not self.db.readonly
|
||||
|
||||
@@ -310,8 +311,10 @@ class Marriage:
|
||||
Utils.bold_label(self.notes_label)
|
||||
if family.get_note_format() == 1:
|
||||
self.preform.set_active(1)
|
||||
self.notes_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.flowed.set_active(1)
|
||||
self.notes_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
self.sourcetab = Sources.SourceTab(
|
||||
self.srcreflist, self, self.top, self.window, self.slist,
|
||||
@@ -350,6 +353,12 @@ class Marriage:
|
||||
index = 0
|
||||
combo.set_active(index)
|
||||
|
||||
def format_toggled(self,junk):
|
||||
if self.preform.get_active():
|
||||
self.notes_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.notes_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
def close_child_windows(self):
|
||||
for child_window in self.child_windows.values():
|
||||
child_window.close(None)
|
||||
|
||||
+43
-28
@@ -227,36 +227,41 @@ class MediaView:
|
||||
|
||||
store,node = self.selection.get_selected()
|
||||
if not node:
|
||||
return
|
||||
|
||||
handle = store.get_value(node,_HANDLE_COL)
|
||||
|
||||
mobj = self.db.get_object_from_handle(handle)
|
||||
mtype = mobj.get_mime_type()
|
||||
path = mobj.get_path()
|
||||
if mtype:
|
||||
type_name = Utils.get_mime_description(mtype)
|
||||
image = ImgManip.get_thumbnail_image(path,mtype)
|
||||
else:
|
||||
image = Utils.find_mime_type_pixbuf('text/plain')
|
||||
type_name = _('Note')
|
||||
self.preview.set_from_pixbuf(image)
|
||||
del image
|
||||
gc.collect()
|
||||
|
||||
self.mid.set_text(mobj.get_gramps_id())
|
||||
if type_name:
|
||||
self.mtype.set_text(type_name)
|
||||
else:
|
||||
self.mtype.set_text(_('unknown'))
|
||||
self.mdesc.set_text(mobj.get_description())
|
||||
if type_name == _('Note'):
|
||||
self.preview.set_from_pixbuf(None)
|
||||
self.mid.set_text('')
|
||||
self.mdesc.set_text('')
|
||||
self.mpath.set_text('')
|
||||
elif len(path) == 0 or fexists == 0:
|
||||
self.mpath.set_text(_("The file no longer exists"))
|
||||
self.mdetails.set_text('')
|
||||
self.mtype.set_text('')
|
||||
else:
|
||||
self.mpath.set_text(path)
|
||||
self.mdetails.set_text(Utils.get_detail_text(mobj,0))
|
||||
handle = store.get_value(node,_HANDLE_COL)
|
||||
|
||||
mobj = self.db.get_object_from_handle(handle)
|
||||
mtype = mobj.get_mime_type()
|
||||
path = mobj.get_path()
|
||||
if mtype:
|
||||
type_name = Utils.get_mime_description(mtype)
|
||||
image = ImgManip.get_thumbnail_image(path,mtype)
|
||||
else:
|
||||
image = Utils.find_mime_type_pixbuf('text/plain')
|
||||
type_name = _('Note')
|
||||
self.preview.set_from_pixbuf(image)
|
||||
del image
|
||||
gc.collect()
|
||||
|
||||
self.mid.set_text(mobj.get_gramps_id())
|
||||
if type_name:
|
||||
self.mtype.set_text(type_name)
|
||||
else:
|
||||
self.mtype.set_text(_('unknown'))
|
||||
self.mdesc.set_text(mobj.get_description())
|
||||
if type_name == _('Note'):
|
||||
self.mpath.set_text('')
|
||||
elif len(path) == 0 or fexists == 0:
|
||||
self.mpath.set_text(_("The file no longer exists"))
|
||||
else:
|
||||
self.mpath.set_text(path)
|
||||
self.mdetails.set_text(Utils.get_detail_text(mobj,0))
|
||||
|
||||
def on_button_press_event(self,obj,event):
|
||||
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
|
||||
@@ -403,6 +408,11 @@ class MediaView:
|
||||
protocol,site,name, j,k,l = urlparse.urlparse(d)
|
||||
if protocol == "file":
|
||||
mime = GrampsMime.get_type(name)
|
||||
if not GrampsMime.is_valid_type(mime):
|
||||
ErrorDialog(_('Invalid file type'),
|
||||
_('An object of type %s cannot be added '
|
||||
'to a gallery') % mime)
|
||||
return
|
||||
photo = RelLib.MediaObject()
|
||||
photo.set_path(name)
|
||||
photo.set_mime_type(mime)
|
||||
@@ -426,6 +436,11 @@ class MediaView:
|
||||
ErrorDialog(_('Image import failed'),str(msg))
|
||||
return
|
||||
mime = GrampsMime.get_type(tfile)
|
||||
if not GrampsMime.is_valid_type(mime):
|
||||
ErrorDialog(_('Invalid file type'),
|
||||
_('An object of type %s cannot be added '
|
||||
'to a gallery') % mtype)
|
||||
return
|
||||
photo = RelLib.MediaObject()
|
||||
photo.set_mime_type(mime)
|
||||
photo.set_description(d)
|
||||
|
||||
@@ -147,6 +147,24 @@ class NameDisplay:
|
||||
else:
|
||||
return self._fnln(name,'')
|
||||
|
||||
def display_with_nick(self,person):
|
||||
"""
|
||||
Returns a text string representing the L{RelLib.Person} instance's
|
||||
L{RelLib.Name} in a manner that should be used for normal displaying.
|
||||
|
||||
@param person: L{RelLib.Person} instance that contains the
|
||||
L{RelLib.Name} that is to be displayed. The primary name is used for
|
||||
the display.
|
||||
@type person: L{RelLib.Person}
|
||||
@returns: Returns the L{RelLib.Person} instance's name
|
||||
@rtype: str
|
||||
"""
|
||||
name = person.get_primary_name()
|
||||
if name.display_as == RelLib.Name.LNFN:
|
||||
return self._lnfn(name,person.get_nick_name())
|
||||
else:
|
||||
return self._fnln(name,person.get_nick_name())
|
||||
|
||||
def display_name(self,name):
|
||||
"""
|
||||
Returns a text string representing the L{RelLib.Name} instance
|
||||
|
||||
+10
-1
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -167,6 +167,7 @@ class NameEditor:
|
||||
self.gladeif.connect('button131','clicked',self.on_help_clicked)
|
||||
self.gladeif.connect('notebook3','switch_page',self.on_switch_page)
|
||||
self.gladeif.connect('group_over','toggled',self.on_group_over_toggled)
|
||||
self.gladeif.connect('alt_preform','toggled',self.format_toggled)
|
||||
|
||||
if name != None:
|
||||
self.given_field.set_text(name.get_first_name())
|
||||
@@ -182,8 +183,10 @@ class NameEditor:
|
||||
Utils.bold_label(self.notes_label)
|
||||
if name.get_note_format() == 1:
|
||||
self.preform.set_active(1)
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.flowed.set_active(1)
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
self.display_as.set_active(name.get_display_as())
|
||||
self.sort_as.set_active(name.get_display_as())
|
||||
grp_as = name.get_group_as()
|
||||
@@ -201,6 +204,12 @@ class NameEditor:
|
||||
self.add_itself_to_menu()
|
||||
self.window.show()
|
||||
|
||||
def format_toggled(self,junk):
|
||||
if self.preform.get_active():
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.note_field.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
def update_group_as(self,obj):
|
||||
if not self.group_over.get_active():
|
||||
if self.name and self.name.get_group_as() != self.name.get_surname():
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -216,9 +216,11 @@ class OkDialog:
|
||||
|
||||
class MissingMediaDialog:
|
||||
def __init__(self,msg1,msg2,task1,task2,task3,parent=None):
|
||||
self.xml = gtk.glade.XML(const.errdialogsFile,"missmediadialog","gramps")
|
||||
self.xml = gtk.glade.XML(const.errdialogsFile,
|
||||
"missmediadialog","gramps")
|
||||
self.top = self.xml.get_widget('missmediadialog')
|
||||
self.top.set_icon(ICON)
|
||||
|
||||
self.task1 = task1
|
||||
self.task2 = task2
|
||||
self.task3 = task3
|
||||
@@ -236,7 +238,15 @@ class MissingMediaDialog:
|
||||
self.top.show()
|
||||
if parent:
|
||||
self.top.set_transient_for(parent)
|
||||
response = self.top.run()
|
||||
self.top.connect('delete_event',self.warn)
|
||||
response = gtk.RESPONSE_DELETE_EVENT
|
||||
|
||||
# Need some magic here, because an attempt to close the dialog
|
||||
# with the X button not only emits the 'delete_event' signal
|
||||
# but also exits with the RESPONSE_DELETE_EVENT
|
||||
while response == gtk.RESPONSE_DELETE_EVENT:
|
||||
response = self.top.run()
|
||||
|
||||
if response == 1:
|
||||
self.task1()
|
||||
elif response == 2:
|
||||
@@ -248,3 +258,11 @@ class MissingMediaDialog:
|
||||
else:
|
||||
self.default_action = 0
|
||||
self.top.destroy()
|
||||
|
||||
def warn(self,obj,obj2):
|
||||
WarningDialog(
|
||||
_("Attempt to force closing the dialog"),
|
||||
_("Please do not force closing this important dialog.\n"
|
||||
"Instead select one of the available options"),
|
||||
self.top)
|
||||
return True
|
||||
|
||||
+58
-45
@@ -316,6 +316,34 @@ class NoteParser:
|
||||
def get_lines(self):
|
||||
return self.count
|
||||
|
||||
|
||||
class IdMapper:
|
||||
|
||||
def __init__(self,trans_func,gen_next_id):
|
||||
self.idswap = {}
|
||||
self.id2handle = {}
|
||||
self.trans_func = trans_func
|
||||
self.gen_next_id = gen_next_id
|
||||
|
||||
def map_id(self, gramps_id):
|
||||
gramps_id = str(gramps_id)
|
||||
|
||||
handle = self.idswap.get(gramps_id)
|
||||
if not handle:
|
||||
if self.trans_func(gramps_id):
|
||||
handle = self.gen_next_id()
|
||||
else:
|
||||
handle = gramps_id
|
||||
self.idswap[gramps_id] = handle
|
||||
return handle
|
||||
|
||||
def convert_to_handle(self,gramps_id):
|
||||
return self.id2handle.get(gramps_id)
|
||||
|
||||
def save_id_to_handle(self,gramps_id,handle):
|
||||
self.id2handle[gramps_id] = handle
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
@@ -349,11 +377,11 @@ class GedcomParser:
|
||||
self.broken_conc_list = [ 'FamilyOrigins', 'FTW' ]
|
||||
self.broken_conc = 0
|
||||
self.is_ftw = 0
|
||||
self.idswap = {}
|
||||
self.gid2id = {}
|
||||
self.sid2id = {}
|
||||
|
||||
self.pmapper = IdMapper(self.db.id_trans.get, self.db.find_next_person_gramps_id)
|
||||
self.fmapper = IdMapper(self.db.fid_trans.get, self.db.find_next_family_gramps_id)
|
||||
self.smapper = IdMapper(self.db.sid_trans.get, self.db.find_next_source_gramps_id)
|
||||
self.lid2id = {}
|
||||
self.fid2id = {}
|
||||
|
||||
self.place_names = sets.Set()
|
||||
cursor = dbase.get_place_cursor()
|
||||
@@ -370,11 +398,6 @@ class GedcomParser:
|
||||
self.backoff = 0
|
||||
self.override = codeset
|
||||
|
||||
if self.db.get_number_of_people() == 0:
|
||||
self.map_gid = self.map_gid_empty
|
||||
else:
|
||||
self.map_gid = self.map_gid_not_empty
|
||||
|
||||
if self.override != 0:
|
||||
if self.override == 1:
|
||||
self.cnv = ansel_to_utf8
|
||||
@@ -650,7 +673,7 @@ class GedcomParser:
|
||||
self.ignore_sub_junk(level+1)
|
||||
|
||||
def parse_source(self,name,level):
|
||||
self.source = self.find_or_create_source(name[1:-1])
|
||||
self.source = self.find_or_create_source(self.smapper.map_id(name[1:-1]))
|
||||
note = ""
|
||||
while True:
|
||||
matches = self.get_next()
|
||||
@@ -703,7 +726,7 @@ class GedcomParser:
|
||||
if self.fam_count % UPDATE == 0 and self.window:
|
||||
self.update(self.families_obj,str(self.fam_count))
|
||||
self.fam_count = self.fam_count + 1
|
||||
self.family = self.find_or_create_family(matches[1][1:-1])
|
||||
self.family = self.find_or_create_family(self.fmapper.map_id(matches[1][1:-1]))
|
||||
self.parse_family()
|
||||
if self.addr != None:
|
||||
father_handle = self.family.get_father_handle()
|
||||
@@ -733,7 +756,8 @@ class GedcomParser:
|
||||
self.indi_count = self.indi_count + 1
|
||||
gid = matches[1]
|
||||
gid = gid[1:-1]
|
||||
self.person = self.find_or_create_person(self.map_gid(gid))
|
||||
# self.person = self.find_or_create_person(self.map_gid(gid))
|
||||
self.person = self.find_or_create_person(self.pmapper.map_id(gid))
|
||||
self.added[self.person.get_handle()] = 1
|
||||
self.parse_individual()
|
||||
if len(self.person.get_source_references()) == 0:
|
||||
@@ -751,7 +775,7 @@ class GedcomParser:
|
||||
elif matches[2].startswith("SOUR "):
|
||||
# A source formatted in a single line, for example:
|
||||
# 0 @S62@ SOUR This is the title of the source
|
||||
source = self.find_or_create_source(matches[1][1:-1])
|
||||
source = self.find_or_create_source(self.smapper.map_id(matches[1][1:-1]))
|
||||
source.set_title( matches[2][5:])
|
||||
self.db.commit_source(source, self.trans)
|
||||
elif matches[2][0:4] == "NOTE":
|
||||
@@ -766,22 +790,9 @@ class GedcomParser:
|
||||
else:
|
||||
self.barf(1)
|
||||
|
||||
def map_gid_empty(self,gid):
|
||||
return gid
|
||||
|
||||
def map_gid_not_empty(self,gid):
|
||||
if self.idswap.get(gid):
|
||||
return self.idswap[gid]
|
||||
else:
|
||||
if self.db.id_trans.get(str(gid)):
|
||||
self.idswap[gid] = self.db.find_next_person_gramps_id()
|
||||
else:
|
||||
self.idswap[gid] = gid
|
||||
return self.idswap[gid]
|
||||
|
||||
def find_or_create_person(self,gramps_id):
|
||||
person = RelLib.Person()
|
||||
intid = self.gid2id.get(gramps_id)
|
||||
intid = self.pmapper.convert_to_handle(gramps_id)
|
||||
if self.db.person_map.has_key(intid):
|
||||
person.unserialize(self.db.person_map.get(intid))
|
||||
else:
|
||||
@@ -791,33 +802,33 @@ class GedcomParser:
|
||||
return person
|
||||
|
||||
def find_person_handle(self,gramps_id):
|
||||
intid = self.gid2id.get(gramps_id)
|
||||
intid = self.pmapper.convert_to_handle(gramps_id)
|
||||
if not intid:
|
||||
intid = create_id()
|
||||
self.gid2id[gramps_id] = intid
|
||||
self.pmapper.save_id_to_handle(gramps_id,intid)
|
||||
return intid
|
||||
|
||||
def find_or_create_family(self,gramps_id):
|
||||
family = RelLib.Family()
|
||||
intid = self.fid2id.get(gramps_id)
|
||||
intid = self.fmapper.convert_to_handle(gramps_id)
|
||||
if self.db.family_map.has_key(intid):
|
||||
family.unserialize(self.db.family_map.get(intid))
|
||||
else:
|
||||
intid = self.find_family_handle(gramps_id)
|
||||
intid = self.find_family_handle(self.fmapper.map_id(gramps_id))
|
||||
family.set_handle(intid)
|
||||
family.set_gramps_id(gramps_id)
|
||||
return family
|
||||
|
||||
def find_family_handle(self,gramps_id):
|
||||
intid = self.fid2id.get(gramps_id)
|
||||
intid = self.fmapper.convert_to_handle(gramps_id)
|
||||
if not intid:
|
||||
intid = create_id()
|
||||
self.fid2id[gramps_id] = intid
|
||||
self.fmapper.save_id_to_handle(gramps_id,intid)
|
||||
return intid
|
||||
|
||||
def find_or_create_source(self,gramps_id):
|
||||
source = RelLib.Source()
|
||||
intid = self.sid2id.get(gramps_id)
|
||||
intid = self.smapper.convert_to_handle(gramps_id)
|
||||
if self.db.source_map.has_key(intid):
|
||||
source.unserialize(self.db.source_map.get(intid))
|
||||
else:
|
||||
@@ -825,7 +836,7 @@ class GedcomParser:
|
||||
source.set_handle(intid)
|
||||
source.set_gramps_id(gramps_id)
|
||||
self.db.add_source(source,self.trans)
|
||||
self.sid2id[gramps_id] = intid
|
||||
self.smapper.save_id_to_handle(gramps_id,intid)
|
||||
return source
|
||||
|
||||
def find_or_create_place(self,title):
|
||||
@@ -833,6 +844,7 @@ class GedcomParser:
|
||||
|
||||
# check to see if we've encountered this name before
|
||||
# if we haven't we need to get a new GRAMPS ID
|
||||
|
||||
intid = self.lid2id.get(title)
|
||||
if intid == None:
|
||||
new_id = self.db.find_next_place_gramps_id()
|
||||
@@ -927,12 +939,12 @@ class GedcomParser:
|
||||
return
|
||||
elif matches[1] == "HUSB":
|
||||
gid = matches[2]
|
||||
handle = self.find_person_handle(self.map_gid(gid[1:-1]))
|
||||
handle = self.find_person_handle(self.pmapper.map_id(gid[1:-1]))
|
||||
self.family.set_father_handle(handle)
|
||||
self.ignore_sub_junk(2)
|
||||
elif matches[1] == "WIFE":
|
||||
gid = matches[2]
|
||||
handle = self.find_person_handle(self.map_gid(gid[1:-1]))
|
||||
handle = self.find_person_handle(self.pmapper.map_id(gid[1:-1]))
|
||||
self.family.set_mother_handle(handle)
|
||||
self.ignore_sub_junk(2)
|
||||
elif matches[1] == "SLGS":
|
||||
@@ -946,7 +958,7 @@ class GedcomParser:
|
||||
elif matches[1] == "CHIL":
|
||||
mrel,frel = self.parse_ftw_relations(2)
|
||||
gid = matches[2]
|
||||
child = self.find_or_create_person(self.map_gid(gid[1:-1]))
|
||||
child = self.find_or_create_person(self.pmapper.map_id(gid[1:-1]))
|
||||
self.family.add_child_handle(child.get_handle())
|
||||
|
||||
for f in child.get_parent_family_handle_list():
|
||||
@@ -1093,7 +1105,7 @@ class GedcomParser:
|
||||
self.person.set_lds_sealing(lds_ord)
|
||||
self.parse_ord(lds_ord,2)
|
||||
elif matches[1] == "FAMS":
|
||||
handle = self.find_family_handle(matches[2][1:-1])
|
||||
handle = self.find_family_handle(self.fmapper.map_id(matches[2][1:-1]))
|
||||
self.person.add_family_handle(handle)
|
||||
if note == "":
|
||||
note = self.parse_optional_note(2)
|
||||
@@ -1101,7 +1113,7 @@ class GedcomParser:
|
||||
note = "%s\n\n%s" % (note,self.parse_optional_note(2))
|
||||
elif matches[1] == "FAMC":
|
||||
ftype,note = self.parse_famc_type(2)
|
||||
handle = self.find_family_handle(matches[2][1:-1])
|
||||
handle = self.find_family_handle(self.fmapper.map_id(matches[2][1:-1]))
|
||||
|
||||
for f in self.person.get_parent_family_handle_list():
|
||||
if f[0] == handle:
|
||||
@@ -1266,6 +1278,7 @@ class GedcomParser:
|
||||
filename = ""
|
||||
title = "no title"
|
||||
note = ""
|
||||
|
||||
while True:
|
||||
matches = self.get_next()
|
||||
if int(matches[0]) < level:
|
||||
@@ -1439,7 +1452,7 @@ class GedcomParser:
|
||||
elif matches[1] == "DATE":
|
||||
lds_ord.set_date_object(self.extract_date(matches[2]))
|
||||
elif matches[1] == "FAMC":
|
||||
lds_ord.set_family_handle(self.find_family_handle(matches[2][1:-1]))
|
||||
lds_ord.set_family_handle(self.find_family_handle(self.fmapper.map_id(matches[2][1:-1])))
|
||||
elif matches[1] == "PLAC":
|
||||
try:
|
||||
place = self.find_or_create_place(matches[2])
|
||||
@@ -1519,7 +1532,7 @@ class GedcomParser:
|
||||
event.set_description("%s\n%s" % (event.get_description(),matches[2]))
|
||||
elif matches[1] in ["_GODP", "_WITN", "_WTN"]:
|
||||
if matches[2][0] == "@":
|
||||
witness_handle = self.find_person_handle(self.map_gid(matches[2][1:-1]))
|
||||
witness_handle = self.find_person_handle(self.pmapper.map_id(matches[2][1:-1]))
|
||||
witness = RelLib.Witness(RelLib.Event.ID,witness_handle)
|
||||
else:
|
||||
witness = RelLib.Witness(RelLib.Event.NAME,matches[2])
|
||||
@@ -1546,7 +1559,7 @@ class GedcomParser:
|
||||
elif matches[1] == "SOUR":
|
||||
event.add_source_reference(self.handle_source(matches,level+1))
|
||||
elif matches[1] == "FAMC":
|
||||
handle = self.find_family_handle(matches[2][1:-1])
|
||||
handle = self.find_family_handle(self.fmapper.map_id(matches[2][1:-1]))
|
||||
mrel,frel = self.parse_adopt_famc(level+1);
|
||||
if self.person.get_main_parents_family_handle() == handle:
|
||||
self.person.set_main_parent_family_handle(None)
|
||||
@@ -1691,7 +1704,7 @@ class GedcomParser:
|
||||
note = self.parse_note(matches,event,level+1,note)
|
||||
elif matches[1] in ["_WITN", "_WTN"]:
|
||||
if matches[2][0] == "@":
|
||||
witness_handle = self.find_person_handle(self.map_gid(matches[2][1:-1]))
|
||||
witness_handle = self.find_person_handle(self.self.pmapper.map_id(matches[2][1:-1]))
|
||||
witness = RelLib.Witness(RelLib.Event.ID,witness_handle)
|
||||
else:
|
||||
witness = RelLib.Witness(RelLib.Event.NAME,matches[2])
|
||||
@@ -2094,7 +2107,7 @@ class GedcomParser:
|
||||
self.inline_srcs[(title,note)] = handle
|
||||
self.ignore_sub_junk(level+1)
|
||||
else:
|
||||
handle = self.find_or_create_source(matches[2][1:-1]).get_handle()
|
||||
handle = self.find_or_create_source(self.smapper.map_id(matches[2][1:-1])).get_handle()
|
||||
self.parse_source_reference(source_ref,level)
|
||||
source_ref.set_base_handle(handle)
|
||||
return source_ref
|
||||
|
||||
@@ -2248,7 +2248,8 @@ class Event(PrimaryObject,PrivateSourceNote,MediaBase,DateBase,PlaceBase):
|
||||
self.description != other.description or self.cause != other.cause or
|
||||
self.private != other.private or
|
||||
(not self.get_date_object().is_equal(other.get_date_object())) or
|
||||
len(self.get_source_references()) != len(other.get_source_references())):
|
||||
len(self.get_source_references()) != len(other.get_source_references()) or
|
||||
len(self.media_list) != len(other.media_list)):
|
||||
return False
|
||||
|
||||
index = 0
|
||||
|
||||
+53
-23
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -525,7 +525,7 @@ buried_partial_date_place = {
|
||||
buried_partial_date_no_place = {
|
||||
RelLib.Person.MALE: [
|
||||
_("%(male_name)s was buried in %(month_year)s."),
|
||||
_("He was buried on %(month_year)s."),
|
||||
_("He was buried in %(month_year)s."),
|
||||
],
|
||||
RelLib.Person.FEMALE: [
|
||||
_("%(female_name)s was buried in %(month_year)s."),
|
||||
@@ -1990,16 +1990,16 @@ def buried_str(database,person,person_name=None,empty_date="",empty_place=""):
|
||||
'modified_date' : bdate,
|
||||
}
|
||||
|
||||
if bdate and bdate_full:
|
||||
if bplace: #male, date, place
|
||||
text = buried_full_date_place[gender][name_index] % values
|
||||
else: #male, date, no place
|
||||
text = buried_full_date_no_place[gender][name_index] % values
|
||||
elif bdate and bdate_mod:
|
||||
if bdate and bdate_mod:
|
||||
if bplace: #male, date, place
|
||||
text = buried_modified_date_place[gender][name_index] % values
|
||||
else: #male, date, no place
|
||||
text = buried_modified_date_no_place[gender][name_index] % values
|
||||
elif bdate and bdate_full:
|
||||
if bplace: #male, date, place
|
||||
text = buried_full_date_place[gender][name_index] % values
|
||||
else: #male, date, no place
|
||||
text = buried_full_date_no_place[gender][name_index] % values
|
||||
elif bdate:
|
||||
if bplace: #male, month_year, place
|
||||
text = buried_partial_date_place[gender][name_index] % values
|
||||
@@ -2119,8 +2119,11 @@ def old_calc_age(database,person):
|
||||
months: 2
|
||||
days: 3
|
||||
"""
|
||||
YEARS = 1
|
||||
MONTHS = 2
|
||||
DAYS = 3
|
||||
|
||||
# This is an old and ugly implementation.
|
||||
# FIXME: This is an old and ugly implementation.
|
||||
# It must be changed to use the new age calculator.
|
||||
age = 0
|
||||
units = 0
|
||||
@@ -2138,23 +2141,50 @@ def old_calc_age(database,person):
|
||||
else:
|
||||
death_year_valid = None
|
||||
|
||||
if birth_year_valid and death_year_valid:
|
||||
age = death.get_year() - birth.get_year()
|
||||
units = 1 # year
|
||||
# wihtout at least a year for each event we're clueless
|
||||
if not (birth_year_valid and death_year_valid):
|
||||
return (age,units)
|
||||
|
||||
# FIXME: The code below uses hard-coded 31 days in a month
|
||||
# and 12 month in a year. This is incorrect for half the Gregorian
|
||||
# months and for other calendars.
|
||||
# FIXME: We need to move to estimate_age !!!
|
||||
|
||||
# If born and died in the same year, go to the months
|
||||
if death.get_year() == birth.get_year():
|
||||
if birth.get_month_valid() and death.get_month_valid():
|
||||
# if born and died in the same month, do the days
|
||||
if birth.get_month() == death.get_month() \
|
||||
and birth.get_day_valid() and death.get_day_valid():
|
||||
age = death.get_day() - birth.get_day()
|
||||
units = DAYS
|
||||
# if not the same month, just diff the months
|
||||
else:
|
||||
age = death.get_month() - birth.get_month()
|
||||
units = MONTHS
|
||||
# Born and died in different years
|
||||
else:
|
||||
age = death.get_year() - birth.get_year()
|
||||
units = YEARS
|
||||
if birth.get_month_valid() and death.get_month_valid():
|
||||
# Subtract one year if less than a last full year
|
||||
if birth.get_month() > death.get_month():
|
||||
age = age - 1
|
||||
if birth.get_day_valid() and death.get_day_valid():
|
||||
if birth.get_month() == death.get_month() and birth.get_day() > death.get_day():
|
||||
age = age - 1
|
||||
if age == 0:
|
||||
age = death.get_month() - birth.get_month() # calc age in months
|
||||
if birth.get_day() > death.get_day():
|
||||
age = age - 1
|
||||
units = 2 # month
|
||||
if age == 0:
|
||||
age = death.get_day() + 31 - birth.get_day() # calc age in days
|
||||
units = 3 # day
|
||||
|
||||
# If less than a year (but still in different years)
|
||||
# then calculate month diff modulo 12
|
||||
if age == 0:
|
||||
age = 12 + death.get_month() - birth.get_month()
|
||||
units = MONTHS
|
||||
|
||||
# This is the case of birth on Dec 30 and death on Jan 2
|
||||
# or birth on May 30 and death on June 2
|
||||
if age == 1 and units == MONTHS \
|
||||
and birth.get_day_valid() and death.get_day_valid() \
|
||||
and birth.get_day() > death.get_day():
|
||||
age = death.get_day() + 31 - birth.get_day()
|
||||
unit = DAYS
|
||||
|
||||
return (age,units)
|
||||
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ import GrampsMime
|
||||
import NameDisplay
|
||||
import Date
|
||||
import Errors
|
||||
from QuestionDialog import WarningDialog
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -871,6 +872,7 @@ class ProgressMeter:
|
||||
Specify the title and the current pass header.
|
||||
"""
|
||||
self.ptop = gtk.Dialog()
|
||||
self.ptop.connect('delete_event',self.warn)
|
||||
self.ptop.set_has_separator(False)
|
||||
self.ptop.set_title(title)
|
||||
self.ptop.set_border_width(12)
|
||||
@@ -920,6 +922,13 @@ class ProgressMeter:
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration()
|
||||
|
||||
def warn(self,obj,obj2):
|
||||
WarningDialog(
|
||||
_("Attempt to force closing the dialog"),
|
||||
_("Please do not force closing this important dialog."),
|
||||
self.ptop)
|
||||
return True
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close the progress meter
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -775,6 +775,13 @@ class GedcomWriter:
|
||||
|
||||
if source.get_note():
|
||||
self.write_long_text("NOTE",1,self.cnvtxt(source.get_note()))
|
||||
datamap = source.get_data_map()
|
||||
if datamap:
|
||||
self.writeln("1 DATA")
|
||||
for (key,value) in datamap.items():
|
||||
self.write_long_text("NOTE",2,
|
||||
self.cnvtxt('%s: %s' % (key,value)))
|
||||
|
||||
index = index + 1
|
||||
self.write_change(1,source.get_change_time())
|
||||
|
||||
@@ -1208,7 +1215,8 @@ class GedcomWriter:
|
||||
self.writeln("%d SOUR @%s@" %
|
||||
(level,self.sid(ref.get_base_handle())))
|
||||
if ref.get_page() != "":
|
||||
self.write_long_text("PAGE",level+1,self.cnvtxt(ref.get_page()))
|
||||
self.write_long_text("PAGE",level+1,
|
||||
self.cnvtxt(ref.get_page()))
|
||||
|
||||
ref_text = ref.get_text()
|
||||
if ref_text != "" or not ref.get_date_object().is_empty():
|
||||
@@ -1217,6 +1225,13 @@ class GedcomWriter:
|
||||
self.write_long_text("TEXT",level+2,self.cnvtxt(ref_text))
|
||||
pfx = "%d DATE" % (level+2)
|
||||
self.print_date(pfx,ref.get_date_object())
|
||||
conf = ref.get_confidence_level()
|
||||
if conf != RelLib.CONF_NORMAL:
|
||||
if conf > 1:
|
||||
gedcom_conf = conf - 1
|
||||
else:
|
||||
gedcom_conf = conf
|
||||
self.writeln('%d QUAY %d' % (level+1,gedcom_conf))
|
||||
else:
|
||||
# We put title, page, and date on the SOUR line.
|
||||
# Not using CONC and CONT because GeneWeb does not support these.
|
||||
|
||||
@@ -849,7 +849,7 @@ class XmlWriter:
|
||||
def write_object(self,obj):
|
||||
handle = obj.get_gramps_id()
|
||||
mime_type = obj.get_mime_type()
|
||||
path = obj.get_path()
|
||||
path = self.fix(obj.get_path())
|
||||
if self.strip_photos:
|
||||
path = os.path.basename(path)
|
||||
self.g.write(' <object id="%s" handle="%s" change="%d" src="%s" mime="%s"' %
|
||||
|
||||
@@ -4,11 +4,12 @@ Name=GRAMPS Genealogy System
|
||||
Name[sv]=GRAMPS
|
||||
Name[no]=GRAMPS
|
||||
Name[nb]=GRAMPS
|
||||
Name[ru]=GRAMPS
|
||||
Name[ru]=Генеалогические исследования в GRAMPS
|
||||
Name[de]=GRAMPS
|
||||
Name[hu]=GRAMPS
|
||||
Name[nl]=GRAMPS genealogie
|
||||
Name[fi]=GRAMPS sukututkimusohjelma
|
||||
Name[fr]=GRAMPS
|
||||
Comment=Manage genealogical information, perform genealogical research and analysis
|
||||
Comment[nl]=Een programma voor genealogie infomatie beheer en genealogisch onderzoek en analyse
|
||||
Comment[sv]=Ett släktforskningsprogram
|
||||
@@ -18,11 +19,12 @@ Comment[ru]=Система исследования и анализа генеа
|
||||
Comment[de]=Ein Programm zur Ahnenforschung
|
||||
Comment[hu]=Örökléskutató és elemző program
|
||||
Comment[fi]=Hallinnoi, tutki ja analysoi sukutietoa
|
||||
Comment[fr]=Gestion des informations genealogiques, optimisation de la recherche et de l'analyse
|
||||
Icon=gramps.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=Application;Genealogy;
|
||||
Categories=Application;Genealogy;Office;
|
||||
X-GNOME-DocPath=gramps/gramps-manual.xml
|
||||
MimeType=application/x-gramps
|
||||
Exec=gramps %F
|
||||
|
||||
+110
-28
@@ -48,64 +48,97 @@ from DateDisplay import DateDisplay
|
||||
#-------------------------------------------------------------------------
|
||||
class DateParserFR(DateParser):
|
||||
|
||||
month_to_int = DateParser.month_to_int
|
||||
# Add common latin, local and historical variants (now only on east france)
|
||||
month_to_int[u"januaris"] = 1
|
||||
month_to_int[u"janer"] = 1
|
||||
month_to_int[u"jenner"] = 1
|
||||
month_to_int[u"hartmonat"] = 1
|
||||
month_to_int[u"hartung"] = 1
|
||||
month_to_int[u"eismond"] = 1
|
||||
month_to_int[u"bluviose"] = 1
|
||||
month_to_int[u"februaris"] = 2
|
||||
month_to_int[u"hornung"] = 2
|
||||
month_to_int[u"wintermonat"] = 2
|
||||
month_to_int[u"taumond"] = 2
|
||||
month_to_int[u"narrenmond"] = 2
|
||||
month_to_int[u"vendose"] = 2
|
||||
month_to_int[u"martius"] = 3
|
||||
month_to_int[u"aprilis"] = 4
|
||||
month_to_int[u"wiesenmonat"] = 5
|
||||
month_to_int[u"maius"] = 5
|
||||
month_to_int[u"junius"] = 6
|
||||
month_to_int[u"julius"] = 7
|
||||
month_to_int[u"augustus"] = 8
|
||||
month_to_int[u"september"] = 9
|
||||
month_to_int[u"7bre"] = 9
|
||||
month_to_int[u"7bris"] = 9
|
||||
month_to_int[u"october"] = 10
|
||||
month_to_int[u"8bre"] = 10
|
||||
month_to_int[u"8bris"] = 10
|
||||
month_to_int[u"nebelmonat"] = 10
|
||||
month_to_int[u"november"] = 11
|
||||
month_to_int[u"9bre"] = 11
|
||||
month_to_int[u"9bris"] = 11
|
||||
month_to_int[u"december"] = 12
|
||||
month_to_int[u"10bre"] = 12
|
||||
month_to_int[u"10bris"] = 12
|
||||
month_to_int[u"xbre"] = 12
|
||||
month_to_int[u"xbris"] = 12
|
||||
|
||||
modifier_to_int = {
|
||||
u'avant' : Date.MOD_BEFORE,
|
||||
u'av.' : Date.MOD_BEFORE,
|
||||
u'av' : Date.MOD_BEFORE,
|
||||
u'après' : Date.MOD_AFTER,
|
||||
u'avant' : Date.MOD_BEFORE,
|
||||
u'av.' : Date.MOD_BEFORE,
|
||||
u'av' : Date.MOD_BEFORE,
|
||||
u'après' : Date.MOD_AFTER,
|
||||
u'ap.' : Date.MOD_AFTER,
|
||||
u'ap' : Date.MOD_AFTER,
|
||||
u'env.' : Date.MOD_ABOUT,
|
||||
u'env' : Date.MOD_ABOUT,
|
||||
u'environ': Date.MOD_ABOUT,
|
||||
u'circa' : Date.MOD_ABOUT,
|
||||
u'c.' : Date.MOD_ABOUT,
|
||||
u'ca' : Date.MOD_ABOUT,
|
||||
u'ca.' : Date.MOD_ABOUT,
|
||||
u'vers' : Date.MOD_ABOUT,
|
||||
u'~' : Date.MOD_ABOUT,
|
||||
}
|
||||
|
||||
calendar_to_int = {
|
||||
u'grégorien' : Date.CAL_GREGORIAN,
|
||||
u'grégorien' : Date.CAL_GREGORIAN,
|
||||
u'g' : Date.CAL_GREGORIAN,
|
||||
u'julien' : Date.CAL_JULIAN,
|
||||
u'j' : Date.CAL_JULIAN,
|
||||
u'hébreu' : Date.CAL_HEBREW,
|
||||
u'hébreu' : Date.CAL_HEBREW,
|
||||
u'h' : Date.CAL_HEBREW,
|
||||
u'islamique' : Date.CAL_ISLAMIC,
|
||||
u'i' : Date.CAL_ISLAMIC,
|
||||
u'révolutionnaire': Date.CAL_FRENCH,
|
||||
u'révolutionnaire' : Date.CAL_FRENCH,
|
||||
u'r' : Date.CAL_FRENCH,
|
||||
u'perse' : Date.CAL_PERSIAN,
|
||||
u'p' : Date.CAL_PERSIAN,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
u'estimated' : Date.QUAL_ESTIMATED,
|
||||
u'estimer' : Date.QUAL_ESTIMATED,
|
||||
u'estimée' : Date.QUAL_ESTIMATED,
|
||||
u'est.' : Date.QUAL_ESTIMATED,
|
||||
u'est' : Date.QUAL_ESTIMATED,
|
||||
u'environ' : Date.QUAL_ESTIMATED,
|
||||
u'env' : Date.QUAL_ESTIMATED,
|
||||
u'env.' : Date.QUAL_ESTIMATED,
|
||||
u'calculer' : Date.QUAL_CALCULATED,
|
||||
u'calculée' : Date.QUAL_CALCULATED,
|
||||
u'calc.' : Date.QUAL_CALCULATED,
|
||||
u'calc' : Date.QUAL_CALCULATED,
|
||||
u'compter' : Date.QUAL_CALCULATED,
|
||||
u'comptée' : Date.QUAL_CALCULATED,
|
||||
u'compt' : Date.QUAL_CALCULATED,
|
||||
u'compt.' : Date.QUAL_CALCULATED,
|
||||
u'calculated' : Date.QUAL_CALCULATED,
|
||||
}
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
_span_1 = [u'de']
|
||||
_span_2 = [u'à']
|
||||
_range_1 = [u'ent.',u'ent',u'entre']
|
||||
_range_2 = [u'et']
|
||||
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+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1),'|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
self._span = re.compile("(de)\s+(?P<start>.+)\s+(à)\s+(?P<stop>.+)",re.IGNORECASE)
|
||||
self._range = re.compile("(entre|ent|ent.)\s+(?P<start>.+)\s+(et)\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._mon_str,
|
||||
re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -115,19 +148,68 @@ class DateParserFR(DateParser):
|
||||
class DateDisplayFR(DateDisplay):
|
||||
|
||||
calendar = (
|
||||
"", u" (Julien)", u" (Hébreu)",
|
||||
"", u" (Julien)", u" (Hébreu)",
|
||||
u" (Révolutionnaire)", u" (Perse)", u" (Islamique)"
|
||||
)
|
||||
|
||||
_mod_str = ("",u"avant ",u"après ",u"vers ","","","")
|
||||
|
||||
_qual_str = ("","estimated ","calculated ")
|
||||
_qual_str = ("","estimée ","calculée ","")
|
||||
|
||||
formats = (
|
||||
"AAAA-MM-DD (ISO)", "Numérique", "Mois Jour, Année",
|
||||
"MOI Jour, Année", "Jour Mois, Année", "Jour MOIS Année"
|
||||
)
|
||||
|
||||
def _display_gregorian(self,date_val):
|
||||
year = self._slash_year(date_val[2],date_val[3])
|
||||
if self.format == 0:
|
||||
value = self.display_iso(date_val)
|
||||
elif self.format == 1:
|
||||
if date_val[0] == 0 and date_val[1] == 0:
|
||||
value = str(date_val[2])
|
||||
else:
|
||||
value = self._tformat.replace('%m',str(date_val[1]))
|
||||
value = value.replace('%d',str(date_val[0]))
|
||||
value = value.replace('%Y',str(date_val[2]))
|
||||
elif self.format == 2:
|
||||
# Month Day, Year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self._months[date_val[1]],year)
|
||||
else:
|
||||
value = "%s %d, %s" % (self._months[date_val[1]],date_val[0],year)
|
||||
elif self.format == 3:
|
||||
# MON Day, Year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self._MONS[date_val[1]],year)
|
||||
else:
|
||||
value = "%s %d, %s" % (self._MONS[date_val[1]],date_val[0],year)
|
||||
elif self.format == 4:
|
||||
# Day Month Year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self._months[date_val[1]],year)
|
||||
else:
|
||||
value = "%d. %s %s" % (date_val[0],self._months[date_val[1]],year)
|
||||
else:
|
||||
# Day MON Year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self._MONS[date_val[1]],year)
|
||||
else:
|
||||
value = "%d. %s %s" % (date_val[0],self._MONS[date_val[1]],year)
|
||||
return value
|
||||
|
||||
def display(self,date):
|
||||
"""
|
||||
Returns a text string representing the date.
|
||||
@@ -161,4 +243,4 @@ class DateDisplayFR(DateDisplay):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from DateHandler import register_datehandler
|
||||
register_datehandler(('fr_FR','fr','french'),DateParserFR, DateDisplayFR)
|
||||
register_datehandler(('fr_FR','fr','french','fr_CA','fr_BE','fr_CH'),DateParserFR,DateDisplayFR)
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2004-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$
|
||||
|
||||
"""
|
||||
Lithuanian-specific classes for parsing and displaying dates.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import re
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import Date
|
||||
from DateParser import DateParser
|
||||
from DateDisplay import DateDisplay
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Lithuanian parser
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateParserLT(DateParser):
|
||||
|
||||
modifier_to_int = {
|
||||
u'prieš' : Date.MOD_BEFORE,
|
||||
u'po' : Date.MOD_AFTER,
|
||||
u'apie' : Date.MOD_ABOUT,
|
||||
}
|
||||
|
||||
calendar_to_int = {
|
||||
u'Grigaliaus' : Date.CAL_GREGORIAN,
|
||||
u'g' : Date.CAL_GREGORIAN,
|
||||
u'Julijaus' : Date.CAL_JULIAN,
|
||||
u'j' : Date.CAL_JULIAN,
|
||||
u'Hebrajų' : Date.CAL_HEBREW,
|
||||
u'h' : Date.CAL_HEBREW,
|
||||
u'Islamo' : Date.CAL_ISLAMIC,
|
||||
u'i' : Date.CAL_ISLAMIC,
|
||||
u'Prancuzų Respublikos': Date.CAL_FRENCH,
|
||||
u'r' : Date.CAL_FRENCH,
|
||||
u'Persų' : Date.CAL_PERSIAN,
|
||||
u'p' : Date.CAL_PERSIAN,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
u'apytikriai' : Date.QUAL_ESTIMATED,
|
||||
u'apskaičiuota' : Date.QUAL_CALCULATED,
|
||||
}
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
_span_1 = [u'nuo']
|
||||
_span_2 = [u'iki']
|
||||
_range_1 = [u'tarp']
|
||||
_range_2 = [u'ir']
|
||||
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+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1),'|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Lithuanian displayer
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateDisplayLT(DateDisplay):
|
||||
|
||||
calendar = (
|
||||
"", u" (Julijaus)",
|
||||
u" (Hebrajų)",
|
||||
u" (Prancuzų Respublikos)",
|
||||
u" (Persų)",
|
||||
u" (Islamo)"
|
||||
)
|
||||
|
||||
_mod_str = ("",u"iki ",
|
||||
u"po ",
|
||||
u"apie ","","","")
|
||||
|
||||
_qual_str = ("","apytikriai ","apskaičiuota ")
|
||||
|
||||
formats = (
|
||||
"YYYY-MM-DD (ISO)", "Skaitmeninis", "Mėnuo Diena, Metai",
|
||||
"Mėn DD, YYYY", "Diena Mėnuo Metai", "DD Mėn YYYY"
|
||||
)
|
||||
|
||||
def display(self,date):
|
||||
"""
|
||||
Returns a text string representing the date.
|
||||
"""
|
||||
mod = date.get_modifier()
|
||||
cal = date.get_calendar()
|
||||
qual = date.get_quality()
|
||||
start = date.get_start_date()
|
||||
|
||||
qual_str = self._qual_str[qual]
|
||||
|
||||
if mod == Date.MOD_TEXTONLY:
|
||||
return date.get_text()
|
||||
elif start == Date.EMPTY:
|
||||
return ""
|
||||
elif mod == Date.MOD_SPAN:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
return "%sс %s %s %s%s" % (qual_str,d1,u'iki',d2,self.calendar[cal])
|
||||
elif mod == Date.MOD_RANGE:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
return "%s%s %s %s %s%s" % (qual_str,u'tarp',d1,u'ir',d2,self.calendar[cal])
|
||||
else:
|
||||
text = self.display_cal[date.get_calendar()](start)
|
||||
return "%s%s%s%s" % (qual_str,self._mod_str[mod],text,self.calendar[cal])
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Register classes
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from DateHandler import register_datehandler
|
||||
register_datehandler(('lt_LT','lt','lithuanian'),DateParserLT, DateDisplayLT)
|
||||
@@ -63,7 +63,7 @@ class DateParserNL(DateParser):
|
||||
month_to_int[u"januaris"] = 1
|
||||
month_to_int[u"feber"] = 2
|
||||
month_to_int[u"februaris"] = 2
|
||||
month_to_int[u"merz"] = 2
|
||||
month_to_int[u"merz"] = 3
|
||||
month_to_int[u"aprilis"] = 4
|
||||
month_to_int[u"maius"] = 5
|
||||
month_to_int[u"junius"] = 6
|
||||
|
||||
@@ -8,6 +8,7 @@ pkgdatadir = $(datadir)/@PACKAGE@/dates
|
||||
pkgdata_PYTHON = \
|
||||
Date_de.py\
|
||||
Date_ru.py\
|
||||
Date_lt.py\
|
||||
Date_fr.py\
|
||||
Date_es.py\
|
||||
Date_fi.py\
|
||||
|
||||
@@ -10,6 +10,7 @@ docgen_PYTHON = \
|
||||
HtmlDoc.py\
|
||||
KwordDoc.py\
|
||||
LaTeXDoc.py\
|
||||
ODFDoc.py\
|
||||
OpenOfficeDoc.py\
|
||||
OpenSpreadSheet.py\
|
||||
PdfDoc.py\
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -451,13 +451,13 @@ class OpenSpreadSheet(SpreadSheetDoc):
|
||||
self.f.write(const.progName + ' ' + const.version)
|
||||
self.f.write('</meta:generator>\n')
|
||||
self.f.write('<meta:initial-creator>')
|
||||
self.f.write(name)
|
||||
self.f.write(self.name)
|
||||
self.f.write('</meta:initial-creator>\n')
|
||||
self.f.write('<meta:creation-date>')
|
||||
self.f.write(self.time)
|
||||
self.f.write('</meta:creation-date>\n')
|
||||
self.f.write('<dc:creator>')
|
||||
self.f.write(name)
|
||||
self.f.write(self.name)
|
||||
self.f.write('</dc:creator>\n')
|
||||
self.f.write('<dc:date>')
|
||||
self.f.write(self.time)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<property name="window_position">GTK_WIN_POS_CENTER</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="default_width">600</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
@@ -18,7 +18,6 @@
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox5">
|
||||
@@ -570,7 +569,6 @@
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
|
||||
<child internal-child="vbox">
|
||||
|
||||
@@ -4735,7 +4735,7 @@ Other</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="button90">
|
||||
<widget class="GtkButton" id="cancel">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Abandon changes and close window</property>
|
||||
<property name="can_default">True</property>
|
||||
@@ -5243,7 +5243,7 @@ Other</property>
|
||||
<widget class="GtkButton" id="add_data">
|
||||
<property name="width_request">36</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Add a new media object to the database and place it in this gallery</property>
|
||||
<property name="tooltip" translatable="yes">Add a new Key/Value pair</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
@@ -5270,7 +5270,7 @@ Other</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="del_data">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Remove selected object from this gallery only</property>
|
||||
<property name="tooltip" translatable="yes">Remove selected Key/Value pair</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
|
||||
@@ -0,0 +1,943 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 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
|
||||
|
||||
__author__ = "Douglas Blank <Doug.Blank@gmail.com>"
|
||||
__version__ = "$Revision$"
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
import datetime, time
|
||||
from xml.parsers import expat
|
||||
import const
|
||||
import os
|
||||
import locale
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import BaseDoc
|
||||
import Report
|
||||
import GenericFilter
|
||||
from ReportUtils import pt2cm
|
||||
import DateDisplay
|
||||
import ReportOptions
|
||||
import RelLib
|
||||
|
||||
# _days could be added to DateDisplay:
|
||||
_codeset = locale.nl_langinfo(locale.CODESET)
|
||||
# slightly different from _months; this is zero based
|
||||
_days = (
|
||||
unicode(locale.nl_langinfo(locale.DAY_1),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_2),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_3),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_4),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_5),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_6),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_7),_codeset),
|
||||
)
|
||||
_language, _country = "en", "US"
|
||||
(_language_country, _encoding) = locale.getlocale()
|
||||
if _language_country != None and _language_country.count("_") == 1:
|
||||
(_language, _country) = _language_country.split("_")
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# The one and only GUI, unfortunately. This will be able to be moved to
|
||||
# Widget once it is created.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Support functions
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def easter(year):
|
||||
"""
|
||||
Computes the year/month/day of easter. Currently hardcoded in
|
||||
holidays.xml. Based on work by J.-M. Oudin (1940) and is reprinted in
|
||||
the "Explanatory Supplement to the Astronomical Almanac", ed. P. K.
|
||||
Seidelmann (1992).
|
||||
Note: Ash Wednesday is 46 days before Easter Sunday.
|
||||
"""
|
||||
c = year / 100
|
||||
n = year - 19 * (year / 19)
|
||||
k = (c - 17) / 25
|
||||
i = c - c / 4 - (c - k) / 3 + 19 * n + 15
|
||||
i = i - 30 * (i / 30)
|
||||
i = i - (i / 28) * (1 - (i / 28) * (29 / (i + 1))
|
||||
* ((21 - n) / 11))
|
||||
j = year + year / 4 + i + 2 - c + c / 4
|
||||
j = j - 7 * (j / 7)
|
||||
l = i - j
|
||||
month = 3 + (l + 40) / 44
|
||||
day = l + 28 - 31 * ( month / 4 )
|
||||
return "%d/%d/%d" % (year, month, day)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Calendar
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class Calendar(Report.Report):
|
||||
"""
|
||||
Creates the Calendar object that produces the report.
|
||||
"""
|
||||
def __getitem__(self, item):
|
||||
""" Used to get items from various places. Could be moved up to Report. """
|
||||
if item in self.doc.style_list:
|
||||
# font is the only element people refer to in writing reports
|
||||
# from the style_list:
|
||||
return self.doc.style_list[item].get_font()
|
||||
elif item in self.options_class.options_dict:
|
||||
# otherwise it is a option:
|
||||
return self.options_class.options_dict[item]
|
||||
else:
|
||||
raise AttributeError, ("no widget named '%s'" % item)
|
||||
|
||||
def define_graphics_styles(self):
|
||||
""" Set up the report. Could be moved up to Report. """
|
||||
for widget in self.options_class.widgets:
|
||||
if widget.__class__.__name__ == "StyleWidget":
|
||||
widget.define_graphics_style(self.doc)
|
||||
|
||||
def get_short_name(self, person, maiden_name = None):
|
||||
""" Is there a better, built-in way of getting a short, personal name? """
|
||||
nickname = person.get_nick_name()
|
||||
if nickname:
|
||||
first_name = nickname
|
||||
else:
|
||||
first_name = person.get_primary_name().get_first_name()
|
||||
if first_name:
|
||||
first_name = first_name.split()[0] # not middle name
|
||||
if nickname.strip().count(" ") > 0: # HACK: first and last name assumed
|
||||
family_name = ""
|
||||
elif maiden_name != None:
|
||||
family_name = maiden_name
|
||||
else:
|
||||
family_name = person.get_primary_name().get_surname()
|
||||
return ("%s %s" % (first_name, family_name)).strip()
|
||||
|
||||
def draw_rectangle(self, style, sx, sy, ex, ey):
|
||||
""" This should be in BaseDoc """
|
||||
self.doc.draw_line(style, sx, sy, sx, ey)
|
||||
self.doc.draw_line(style, sx, sy, ex, sy)
|
||||
self.doc.draw_line(style, ex, sy, ex, ey)
|
||||
self.doc.draw_line(style, sx, ey, ex, ey)
|
||||
|
||||
### The rest of these all have to deal with calendar specific things
|
||||
|
||||
def add_day_item(self, text, year, month, day):
|
||||
month_dict = self.calendar.get(month, {})
|
||||
day_list = month_dict.get(day, [])
|
||||
day_list.append(text)
|
||||
month_dict[day] = day_list
|
||||
self.calendar[month] = month_dict
|
||||
|
||||
def get_holidays(self, year, country = "US"):
|
||||
""" Looks in multiple places for holidays.xml files """
|
||||
locations = [const.pluginsDir,
|
||||
os.path.expanduser("~/.gramps/plugins")]
|
||||
holiday_file = 'holidays.xml'
|
||||
for dir in locations:
|
||||
holiday_full_path = os.path.join(dir, holiday_file)
|
||||
if os.path.exists(holiday_full_path):
|
||||
self.process_holiday_file(holiday_full_path, year, country)
|
||||
|
||||
def process_holiday_file(self, filename, year, country):
|
||||
""" This will process a holiday file """
|
||||
parser = Xml2Obj()
|
||||
element = parser.Parse(filename)
|
||||
calendar = Holidays(element, country)
|
||||
date = datetime.date(year, 1, 1)
|
||||
while date.year == year:
|
||||
holidays = calendar.check_date( date )
|
||||
for text in holidays:
|
||||
self.add_day_item(text, date.year, date.month, date.day)
|
||||
date = date.fromordinal( date.toordinal() + 1)
|
||||
|
||||
def write_report(self):
|
||||
""" The short method that runs through each month and creates a page. """
|
||||
# initialize the dict to fill:
|
||||
self.calendar = {}
|
||||
# get the information, first from holidays:
|
||||
if self["holidays"]:
|
||||
self.get_holidays(self["year"], _country) # currently global
|
||||
# get data from database:
|
||||
self.collect_data()
|
||||
# generate the report:
|
||||
for month in range(1, 13):
|
||||
self.print_page(month)
|
||||
|
||||
def print_page(self, month):
|
||||
"""
|
||||
This method actually writes the calendar page.
|
||||
"""
|
||||
self.doc.start_page()
|
||||
width = self.doc.get_usable_width()
|
||||
height = self.doc.get_usable_height()
|
||||
header = self.doc.tmargin
|
||||
self.draw_rectangle("border", 0, 0, width, height)
|
||||
self.doc.draw_bar("title", 0, 0, width, header)
|
||||
self.doc.draw_line("border", 0, header, width, header)
|
||||
year = self["year"]
|
||||
title = "%s %d" % (DateDisplay.DateDisplay._months[month], year)
|
||||
font_height = pt2cm(1.25 * self["title"].get_size())
|
||||
self.doc.center_text("title", title, width/2, font_height + self["offset"]) # 1.0
|
||||
cell_width = width / 7
|
||||
cell_height = (height - header)/ 6
|
||||
current_date = datetime.date(year, month, 1)
|
||||
spacing = pt2cm(1.25 * self["text"].get_size()) # 158
|
||||
if current_date.isoweekday() != 7: # start dow here is 7, sunday
|
||||
current_ord = current_date.toordinal() - current_date.isoweekday()
|
||||
else:
|
||||
current_ord = current_date.toordinal()
|
||||
for day_col in range(7):
|
||||
self.doc.center_text("daynames", _days[day_col], # global
|
||||
day_col * cell_width + cell_width/2,
|
||||
header - font_height/3.0 + self["offset"]) # .35
|
||||
for week_row in range(6):
|
||||
something_this_week = 0
|
||||
for day_col in range(7):
|
||||
thisday = current_date.fromordinal(current_ord)
|
||||
if thisday.month == month:
|
||||
something_this_week = 1
|
||||
self.draw_rectangle("border", day_col * cell_width,
|
||||
header + week_row * cell_height,
|
||||
(day_col + 1) * cell_width,
|
||||
header + (week_row + 1) * cell_height)
|
||||
last_edge = (day_col + 1) * cell_width
|
||||
self.doc.center_text("numbers", str(thisday.day),
|
||||
day_col * cell_width + cell_width/2,
|
||||
header + week_row * cell_height + .5 + self["offset"])
|
||||
list = self.calendar.get(month, {}).get(thisday.day, [])
|
||||
position = 0.0
|
||||
for p in list:
|
||||
lines = p.count("\n") + 1 # lines in the text
|
||||
position += (lines * spacing)
|
||||
current = 0
|
||||
for line in p.split("\n"):
|
||||
self.doc.write_at("text", line,
|
||||
day_col * cell_width + .1,
|
||||
header + (week_row + 1) * cell_height - position + (current * spacing) + self["offset"])
|
||||
current += 1
|
||||
current_ord += 1
|
||||
if not something_this_week:
|
||||
last_edge = 0
|
||||
font_height = pt2cm(1.25 * self["text1style"].get_size())
|
||||
self.doc.center_text("text1style", self["text1"], last_edge + (width - last_edge)/2, height - font_height * 3 + self["offset"]) # - 1.5
|
||||
self.doc.center_text("text2style", self["text2"], last_edge + (width - last_edge)/2, height - font_height * 2 + self["offset"]) # - 0.78
|
||||
self.doc.center_text("text3style", self["text3"], last_edge + (width - last_edge)/2, height - font_height * 1 + self["offset"]) # - 0.30
|
||||
self.doc.end_page()
|
||||
|
||||
def collect_data(self):
|
||||
"""
|
||||
This method runs through the data, and collects the relevant dates
|
||||
and text.
|
||||
"""
|
||||
filter_num = self.options_class.get_filter_number()
|
||||
filters = self.options_class.get_report_filters(self.start_person)
|
||||
filters.extend(GenericFilter.CustomFilters.get_filters())
|
||||
self.filter = filters[filter_num]
|
||||
people = self.filter.apply(self.database,
|
||||
self.database.get_person_handles(sort_handles=False))
|
||||
for person_handle in people:
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
birth_handle = person.get_birth_handle()
|
||||
birth_date = None
|
||||
if birth_handle:
|
||||
birth_event = self.database.get_event_from_handle(birth_handle)
|
||||
birth_date = birth_event.get_date()
|
||||
if birth_date == "":
|
||||
birth_date = None
|
||||
else:
|
||||
birth_date_obj = birth_event.get_date_object()
|
||||
death_handle = person.get_death_handle()
|
||||
death_date = None
|
||||
if death_handle:
|
||||
death_event = self.database.get_event_from_handle(death_handle)
|
||||
death_date = death_event.get_date()
|
||||
if death_date == "": # BUG: couldn't remove event
|
||||
death_date = None
|
||||
else:
|
||||
death_date_obj = death_event.get_date_object()
|
||||
if death_date == None:
|
||||
alive = True # well, until we get probably_alive in here
|
||||
else:
|
||||
alive = False
|
||||
if self["birthdays"] and birth_date != None and ((self["alive"] and alive) or not self["alive"]):
|
||||
year = birth_date_obj.get_year()
|
||||
month = birth_date_obj.get_month()
|
||||
day = birth_date_obj.get_day()
|
||||
age = self["year"] - year
|
||||
# add some things to handle maiden name:
|
||||
father_lastname = None # husband, actually
|
||||
if self["maiden_name"] == 0: # get husband's last name:
|
||||
if person.get_gender() == RelLib.Person.FEMALE:
|
||||
family_list = person.get_family_handle_list()
|
||||
if len(family_list) > 0:
|
||||
fhandle = family_list[0] # first is primary
|
||||
fam = self.database.get_family_from_handle(fhandle)
|
||||
father_handle = fam.get_father_handle()
|
||||
mother_handle = fam.get_mother_handle()
|
||||
if mother_handle == person_handle:
|
||||
if father_handle:
|
||||
father = self.database.get_person_from_handle(father_handle)
|
||||
if father != None:
|
||||
father_lastname = father.get_primary_name().get_surname()
|
||||
short_name = self.get_short_name(person, father_lastname)
|
||||
self.add_day_item("%s, %d" % (short_name, age), year, month, day)
|
||||
if self["anniversaries"] and ((self["alive"] and alive) or not self["alive"]):
|
||||
family_list = person.get_family_handle_list()
|
||||
for fhandle in family_list:
|
||||
fam = self.database.get_family_from_handle(fhandle)
|
||||
father_handle = fam.get_father_handle()
|
||||
mother_handle = fam.get_mother_handle()
|
||||
if father_handle == person.get_handle():
|
||||
spouse_handle = mother_handle
|
||||
else:
|
||||
continue # with next person if this was the marriage event
|
||||
if spouse_handle:
|
||||
spouse = self.database.get_person_from_handle(spouse_handle)
|
||||
if spouse:
|
||||
spouse_name = self.get_short_name(spouse)
|
||||
short_name = self.get_short_name(person)
|
||||
if self["alive"]:
|
||||
spouse_death_handle = spouse.get_death_handle()
|
||||
if spouse_death_handle != None:
|
||||
# there is a death event, maybe empty though
|
||||
spouse_death_event = self.database.get_event_from_handle(spouse_death_handle)
|
||||
if spouse_death_event != None:
|
||||
spouse_death_date = spouse_death_event.get_date()
|
||||
if spouse_death_date != "": # BUG: couldn't remove event
|
||||
continue
|
||||
for event_handle in fam.get_event_list():
|
||||
event = self.database.get_event_from_handle(event_handle)
|
||||
event_obj = event.get_date_object()
|
||||
year = event_obj.get_year()
|
||||
month = event_obj.get_month()
|
||||
day = event_obj.get_day()
|
||||
years = self["year"] - year
|
||||
text = _("%(spouse)s and\n %(person)s, %(nyears)d") % {
|
||||
'spouse' : spouse_name,
|
||||
'person' : short_name,
|
||||
'nyears' : years,
|
||||
}
|
||||
self.add_day_item(text, year, month, day)
|
||||
|
||||
###################################################################################
|
||||
# These classes are a suggested of how to rework the graphics out of reports. It also
|
||||
# makes these items abstractions, which makes it easy to change the report
|
||||
# infrastructure without having everyone rewrite their reports each time.
|
||||
#
|
||||
# This builds on the current document code, so no changes are needed.
|
||||
###################################################################################
|
||||
class Widget:
|
||||
""" A Widget virtual base class. This contains no graphics specifics. """
|
||||
commonDefaults = {
|
||||
"wtype" : None,
|
||||
"name" : None,
|
||||
"label" : None,
|
||||
"help" : None,
|
||||
"wtype" : None,
|
||||
"valid_text" : None,
|
||||
"frame" : None,
|
||||
"value" : None,
|
||||
}
|
||||
defaults = {}
|
||||
def __init__(self, option_object, **args):
|
||||
self.option_object = option_object
|
||||
self.setup(args)
|
||||
self.register()
|
||||
def __getitem__(self, key):
|
||||
if key in self.settings:
|
||||
return self.settings[key]
|
||||
else:
|
||||
raise AttributeError, ("no widget attribute named '%s'" % key)
|
||||
def __setitem__(self, key, value):
|
||||
self.settings[key] = value
|
||||
def setup(self, args = {}):
|
||||
# start with the base defaults common to all:
|
||||
self.settings = self.commonDefaults.copy()
|
||||
# now add those from the subclass:
|
||||
self.settings.update(self.defaults)
|
||||
# ad finally, those from the user:
|
||||
self.settings.update(args)
|
||||
def register(self):
|
||||
className = self.__class__.__name__
|
||||
if className == "FilterWidget":
|
||||
self.option_object.enable_dict['filter'] = 0
|
||||
elif className == "StyleWidget":
|
||||
self.option_object[self["name"]] = self["value"]
|
||||
else:
|
||||
self.option_object[self["name"]] = self["value"]
|
||||
self.option_object.options_help[self["name"]] = (
|
||||
self["wtype"], self["help"], self["valid_text"])
|
||||
def add_gui(self, dialog): pass
|
||||
def update(self): pass
|
||||
class SpinWidget(Widget):
|
||||
""" A spinner number selector widget for GTK. """
|
||||
defaults = {
|
||||
"wtype" : "=num",
|
||||
"help" : "Numeric option",
|
||||
"valid_text": "Any number",
|
||||
}
|
||||
def add_gui(self, dialog):
|
||||
keyword = self["name"]
|
||||
obj = self.option_object.__dict__
|
||||
obj[keyword] = gtk.SpinButton()
|
||||
obj[keyword].set_digits(0)
|
||||
obj[keyword].set_increments(1,2)
|
||||
obj[keyword].set_range(0,2100)
|
||||
obj[keyword].set_numeric(True)
|
||||
obj[keyword].set_value(self.option_object[keyword])
|
||||
if self["frame"] != None:
|
||||
dialog.add_frame_option(self["frame"], self["label"], obj[keyword])
|
||||
else:
|
||||
dialog.add_option(self["label"], obj[keyword])
|
||||
def update(self):
|
||||
dict = self.option_object.__dict__
|
||||
keyword = self["name"]
|
||||
self.option_object[keyword] = dict[keyword].get_value_as_int()
|
||||
self[keyword] = dict[keyword].get_value_as_int()
|
||||
class CheckWidget(Widget):
|
||||
""" A check box widget for GTK. """
|
||||
defaults = {
|
||||
"wtype" : "=0/1",
|
||||
"help" : "Yes/No option",
|
||||
"valid_text": "1 for yes, 0 for no",
|
||||
}
|
||||
def add_gui(self, dialog):
|
||||
keyword = self["name"]
|
||||
obj = self.option_object.__dict__
|
||||
obj[keyword] = gtk.CheckButton(self["label"])
|
||||
obj[keyword].set_active(self.option_object[keyword])
|
||||
if self["frame"] != None:
|
||||
dialog.add_frame_option(self["frame"], "", obj[keyword])
|
||||
else:
|
||||
dialog.add_option("", obj[keyword])
|
||||
def update(self):
|
||||
dict = self.option_object.__dict__
|
||||
keyword = self["name"]
|
||||
self.option_object[keyword] = int(dict[keyword].get_active())
|
||||
self[keyword] = int(dict[keyword].get_active())
|
||||
class EntryWidget(Widget):
|
||||
""" A text widget for GTK. """
|
||||
defaults = {
|
||||
"wtype" : "=str",
|
||||
"help" : "String option",
|
||||
"valid_text": "Any textual data",
|
||||
}
|
||||
def add_gui(self, dialog):
|
||||
keyword = self["name"]
|
||||
obj = self.option_object.__dict__
|
||||
obj[keyword] = gtk.Entry()
|
||||
obj[keyword].set_text(self.option_object[keyword])
|
||||
if self["frame"] != None:
|
||||
dialog.add_frame_option(self["frame"], self["label"], obj[keyword])
|
||||
else:
|
||||
dialog.add_option(self["label"], obj[keyword])
|
||||
def update(self):
|
||||
dict = self.option_object.__dict__
|
||||
keyword = self["name"]
|
||||
self.option_object[keyword] = unicode(dict[keyword].get_text())
|
||||
self[keyword] = unicode(dict[keyword].get_text())
|
||||
class NumberWidget(EntryWidget):
|
||||
""" A number widget for GTK. """
|
||||
defaults = {
|
||||
"wtype" : "=num",
|
||||
"help" : "Numeric option",
|
||||
"valid_text": "Any number",
|
||||
}
|
||||
def add_gui(self, dialog):
|
||||
keyword = self["name"]
|
||||
obj = self.option_object.__dict__
|
||||
obj[keyword] = gtk.Entry()
|
||||
obj[keyword].set_text(str(self.option_object[keyword]))
|
||||
if self["frame"] != None:
|
||||
dialog.add_frame_option(self["frame"], self["label"], obj[keyword])
|
||||
else:
|
||||
dialog.add_option(self["label"], obj[keyword])
|
||||
def update(self):
|
||||
dict = self.option_object.__dict__
|
||||
keyword = self["name"]
|
||||
self.option_object[keyword] = float(dict[keyword].get_text())
|
||||
self[keyword] = float(dict[keyword].get_text())
|
||||
class StyleWidget(Widget):
|
||||
defaults = {
|
||||
"size" : 8,
|
||||
"bold" : 0,
|
||||
"italics" : 0,
|
||||
"type_face" : BaseDoc.FONT_SERIF,
|
||||
"fill_color": None,
|
||||
}
|
||||
def make_default_style(self, default_style):
|
||||
f = BaseDoc.FontStyle()
|
||||
f.set_size(self["size"])
|
||||
f.set_italic(self["italics"])
|
||||
f.set_bold(self["bold"])
|
||||
f.set_type_face(self["type_face"])
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
p.set_font(f)
|
||||
p.set_description(self["label"])
|
||||
default_style.add_style(self["name"],p)
|
||||
def define_graphics_style(self, document):
|
||||
g = BaseDoc.GraphicsStyle()
|
||||
g.set_paragraph_style(self["name"])
|
||||
if self["fill_color"]:
|
||||
g.set_fill_color(self["fill_color"])
|
||||
# FIXME: add all other graphics items (color, etc) here
|
||||
document.add_draw_style(self["name"],g)
|
||||
class FilterWidget(Widget):
|
||||
"""
|
||||
A filter widget. This doesn't have the GTK code here, but should.
|
||||
This class takes names of the filters and does everything for you.
|
||||
"all filters" - all of them
|
||||
"everyone" - all people in table
|
||||
"descendents" - direct descendents
|
||||
"descendent familes" - direct descendents and their familes
|
||||
"ancestors" - all ancestors of person
|
||||
"common ancestors" - all common ancestors
|
||||
"calendar attribute" - experimental filter for tagging people
|
||||
"""
|
||||
def get_filters(self, person):
|
||||
"""Set up the list of possible content filters."""
|
||||
if person:
|
||||
name = person.get_primary_name().get_name()
|
||||
gramps_id = person.get_gramps_id()
|
||||
else:
|
||||
name = 'PERSON'
|
||||
gramps_id = ''
|
||||
retval = []
|
||||
for filter in self["filters"]:
|
||||
if filter in ["everyone", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("Entire Database"))
|
||||
f.add_rule(GenericFilter.Everyone([]))
|
||||
retval.append(f)
|
||||
if filter in ["descendants", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("Descendants of %s") % name)
|
||||
f.add_rule(GenericFilter.IsDescendantOf([gramps_id,1]))
|
||||
retval.append(f)
|
||||
if filter in ["descendant families", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("Descendant Families of %s") % name)
|
||||
f.add_rule(GenericFilter.IsDescendantFamilyOf([gramps_id]))
|
||||
retval.append(f)
|
||||
if filter in ["ancestors", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("Ancestors of %s") % name)
|
||||
f.add_rule(GenericFilter.IsAncestorOf([gramps_id,1]))
|
||||
retval.append(f)
|
||||
if filter in ["common ancestors", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("People with common ancestor with %s") % name)
|
||||
f.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id]))
|
||||
retval.append(f)
|
||||
if filter in ["calendar attribute", "all filters"]:
|
||||
f = GenericFilter.ParamFilter()
|
||||
f.set_name(_("People with a Calendar attribute"))
|
||||
f.add_rule(GenericFilter.HasTextMatchingSubstringOf(['Calendar',0,0]))
|
||||
retval.append(f)
|
||||
return retval
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# The following could all be moved to the parent class, if you wanted
|
||||
# to adopt this report reworking. Even if you didn't want to use them
|
||||
# it would be ok to put there, because self.widgets would be empty.
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
class NewReportOptions(ReportOptions.ReportOptions):
|
||||
"""
|
||||
Defines options and provides code to handling the interface.
|
||||
This is free of any graphics specifics.
|
||||
"""
|
||||
def __getitem__(self, keyword):
|
||||
""" This could be moved up to ReportOptions """
|
||||
if keyword in self.options_dict:
|
||||
return self.options_dict[keyword]
|
||||
else:
|
||||
raise AttributeError, ("no widget named '%s'" % keyword)
|
||||
|
||||
def __setitem__(self, keyword, value):
|
||||
""" This could be moved up to ReportOptions """
|
||||
self.options_dict[keyword] = value
|
||||
|
||||
def add_user_options(self,dialog):
|
||||
for widget in self.widgets:
|
||||
widget.add_gui(dialog)
|
||||
|
||||
def parse_user_options(self,dialog):
|
||||
for widget in self.widgets:
|
||||
widget.update()
|
||||
|
||||
def get_report_filters(self,person):
|
||||
for widget in self.widgets:
|
||||
if widget.__class__.__name__ == "FilterWidget":
|
||||
return widget.get_filters(person)
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
for widget in self.widgets:
|
||||
if widget.__class__.__name__ == "StyleWidget":
|
||||
widget.make_default_style(default_style)
|
||||
|
||||
class CalendarOptions(NewReportOptions):
|
||||
def enable_options(self):
|
||||
self.enable_dict = {}
|
||||
self.widgets = [
|
||||
FilterWidget(self, label = _("Filter"),
|
||||
name = "filter",
|
||||
filters = ["all filters"]),
|
||||
EntryWidget(self, label = _("Text 1"),
|
||||
name = "text1",
|
||||
value = "My Calendar",
|
||||
help = "Large text area",
|
||||
valid_text = "Any text",
|
||||
frame = _("Text Options")
|
||||
),
|
||||
EntryWidget(self, label = _("Text 2"),
|
||||
name = "text2",
|
||||
value = "Produced with GRAMPS",
|
||||
help = "Medium size text",
|
||||
valid_text = "Any text",
|
||||
frame = _("Text Options")
|
||||
),
|
||||
EntryWidget(self, label = _("Text 3"),
|
||||
name = "text3",
|
||||
value = "http://gramps-project.org/",
|
||||
help = "Small text area",
|
||||
valid_text = "Any text",
|
||||
frame = _("Text Options")
|
||||
),
|
||||
SpinWidget(self, label = _("Year of calendar"),
|
||||
name = "year",
|
||||
value = time.localtime()[0], # the current year
|
||||
help = "Year of calendar",
|
||||
valid_text = "Any year",
|
||||
),
|
||||
CheckWidget(self, label = _("Use maiden names"),
|
||||
name = "maiden_name",
|
||||
value = 1,
|
||||
help = "Use married women's maiden name.",
|
||||
valid_text = "Select to use married women's maiden name.",
|
||||
),
|
||||
CheckWidget(self, label = _("Only include living people"),
|
||||
name = "alive",
|
||||
value = 1,
|
||||
help = "Include only living people",
|
||||
valid_text = "Select to only include living people",
|
||||
),
|
||||
CheckWidget(self, label = _("Include birthdays"),
|
||||
name = "birthdays",
|
||||
value = 1,
|
||||
help = "Include birthdays",
|
||||
valid_text = "Select to include birthdays",
|
||||
),
|
||||
CheckWidget(self, label = _("Include anniversaries"),
|
||||
name = "anniversaries",
|
||||
value = 1,
|
||||
help = "Include anniversaries",
|
||||
valid_text = "Select to include anniversaries",
|
||||
),
|
||||
CheckWidget(self, label = _("Include holidays"),
|
||||
name = "holidays",
|
||||
value = 1,
|
||||
help = "Include holidays",
|
||||
valid_text = "Select to include holidays",
|
||||
),
|
||||
NumberWidget(self, label = "Offset",
|
||||
name = "offset",
|
||||
value = -0.5,
|
||||
help = "Distance to move text on page",
|
||||
valid_text = "Any number",
|
||||
frame = "Text Options"
|
||||
),
|
||||
StyleWidget(self, label = _('Title text and background color.'),
|
||||
name = "title",
|
||||
size = 20,
|
||||
italics = 1,
|
||||
bold = 1,
|
||||
fill_color = (0xEA,0xEA,0xEA),
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Border lines of calendar boxes.'),
|
||||
name = "border",
|
||||
),
|
||||
StyleWidget(self, label = _('Calendar day numbers.'),
|
||||
name = "numbers",
|
||||
size = 13,
|
||||
bold = 1,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Daily text display.'),
|
||||
name = "text",
|
||||
size = 9,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Days of the week text.'),
|
||||
name = "daynames",
|
||||
size = 12,
|
||||
italics = 1,
|
||||
bold = 1,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Text at bottom, line 1.'),
|
||||
name = "text1style",
|
||||
size = 12,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Text at bottom, line 2.'),
|
||||
name = "text2style",
|
||||
size = 12,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Text at bottom, line 3.'),
|
||||
name = "text3style",
|
||||
size = 9,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
]
|
||||
|
||||
class Element:
|
||||
""" A parsed XML element """
|
||||
def __init__(self,name,attributes):
|
||||
'Element constructor'
|
||||
# The element's tag name
|
||||
self.name = name
|
||||
# The element's attribute dictionary
|
||||
self.attributes = attributes
|
||||
# The element's cdata
|
||||
self.cdata = ''
|
||||
# The element's child element list (sequence)
|
||||
self.children = []
|
||||
|
||||
def AddChild(self,element):
|
||||
'Add a reference to a child element'
|
||||
self.children.append(element)
|
||||
|
||||
def getAttribute(self,key):
|
||||
'Get an attribute value'
|
||||
return self.attributes.get(key)
|
||||
|
||||
def getData(self):
|
||||
'Get the cdata'
|
||||
return self.cdata
|
||||
|
||||
def getElements(self,name=''):
|
||||
'Get a list of child elements'
|
||||
#If no tag name is specified, return the all children
|
||||
if not name:
|
||||
return self.children
|
||||
else:
|
||||
# else return only those children with a matching tag name
|
||||
elements = []
|
||||
for element in self.children:
|
||||
if element.name == name:
|
||||
elements.append(element)
|
||||
return elements
|
||||
|
||||
def toString(self, level=0):
|
||||
retval = " " * level
|
||||
retval += "<%s" % self.name
|
||||
for attribute in self.attributes:
|
||||
retval += " %s=\"%s\"" % (attribute, self.attributes[attribute])
|
||||
c = ""
|
||||
for child in self.children:
|
||||
c += child.toString(level+1)
|
||||
if c == "":
|
||||
retval += "/>\n"
|
||||
else:
|
||||
retval += ">\n" + c + ("</%s>\n" % self.name)
|
||||
return retval
|
||||
|
||||
class Xml2Obj:
|
||||
""" XML to Object """
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
self.nodeStack = []
|
||||
|
||||
def StartElement(self,name,attributes):
|
||||
'SAX start element even handler'
|
||||
# Instantiate an Element object
|
||||
element = Element(name.encode(),attributes)
|
||||
# Push element onto the stack and make it a child of parent
|
||||
if len(self.nodeStack) > 0:
|
||||
parent = self.nodeStack[-1]
|
||||
parent.AddChild(element)
|
||||
else:
|
||||
self.root = element
|
||||
self.nodeStack.append(element)
|
||||
|
||||
def EndElement(self,name):
|
||||
'SAX end element event handler'
|
||||
self.nodeStack = self.nodeStack[:-1]
|
||||
|
||||
def CharacterData(self,data):
|
||||
'SAX character data event handler'
|
||||
if data.strip():
|
||||
data = data.encode()
|
||||
element = self.nodeStack[-1]
|
||||
element.cdata += data
|
||||
return
|
||||
|
||||
def Parse(self,filename):
|
||||
# Create a SAX parser
|
||||
Parser = expat.ParserCreate()
|
||||
# SAX event handlers
|
||||
Parser.StartElementHandler = self.StartElement
|
||||
Parser.EndElementHandler = self.EndElement
|
||||
Parser.CharacterDataHandler = self.CharacterData
|
||||
# Parse the XML File
|
||||
ParserStatus = Parser.Parse(open(filename,'r').read(), 1)
|
||||
return self.root
|
||||
|
||||
class Holidays:
|
||||
""" Class used to read XML holidays to add to calendar. """
|
||||
def __init__(self, elements, country="US"):
|
||||
self.debug = 0
|
||||
self.elements = elements
|
||||
self.country = country
|
||||
self.dates = []
|
||||
self.initialize()
|
||||
def set_country(self, country):
|
||||
self.country = country
|
||||
self.dates = []
|
||||
self.initialize()
|
||||
def initialize(self):
|
||||
# parse the date objects
|
||||
for country_set in self.elements.children:
|
||||
if country_set.name == "country" and country_set.attributes["name"] == self.country:
|
||||
for date in country_set.children:
|
||||
if date.name == "date":
|
||||
data = {"value" : "",
|
||||
"name" : "",
|
||||
"offset": "",
|
||||
"type": "",
|
||||
"if": "",
|
||||
} # defaults
|
||||
for attr in date.attributes:
|
||||
data[attr] = date.attributes[attr]
|
||||
self.dates.append(data)
|
||||
def get_daynames(self, y, m, dayname):
|
||||
if self.debug: print "%s's in %d %d..." % (dayname, m, y)
|
||||
retval = [0]
|
||||
dow = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'].index(dayname)
|
||||
for d in range(1, 32):
|
||||
try:
|
||||
date = datetime.date(y, m, d)
|
||||
except ValueError:
|
||||
continue
|
||||
if date.weekday() == dow:
|
||||
retval.append( d )
|
||||
if self.debug: print "dow=", dow, "days=", retval
|
||||
return retval
|
||||
def check_date(self, date):
|
||||
retval = []
|
||||
for rule in self.dates:
|
||||
if self.debug: print "Checking ", rule["name"], "..."
|
||||
offset = 0
|
||||
if rule["offset"] != "":
|
||||
if rule["offset"].isdigit():
|
||||
offset = int(rule["offset"])
|
||||
elif rule["offset"][0] in ["-","+"] and rule["offset"][1:].isdigit():
|
||||
offset = int(rule["offset"])
|
||||
else:
|
||||
# must be a dayname
|
||||
offset = rule["offset"]
|
||||
if rule["value"].count("/") == 3: # year/num/day/month, "3rd wednesday in april"
|
||||
y, num, dayname, mon = rule["value"].split("/")
|
||||
if y == "*":
|
||||
y = date.year
|
||||
else:
|
||||
y = int(y)
|
||||
if mon.isdigit():
|
||||
m = int(mon)
|
||||
elif mon == "*":
|
||||
m = date.month
|
||||
else:
|
||||
m = ['jan', 'feb', 'mar', 'apr', 'may', 'jun',
|
||||
'jul', 'aug', 'sep', 'oct', 'nov', 'dec'].index(mon) + 1
|
||||
dates_of_dayname = self.get_daynames(y, m, dayname)
|
||||
if self.debug: print "num =", num
|
||||
d = dates_of_dayname[int(num)]
|
||||
elif rule["value"].count("/") == 2: # year/month/day
|
||||
y, m, d = rule["value"].split("/")
|
||||
if y == "*":
|
||||
y = date.year
|
||||
else:
|
||||
y = int(y)
|
||||
if m == "*":
|
||||
m = date.month
|
||||
else:
|
||||
m = int(m)
|
||||
if d == "*":
|
||||
d = date.day
|
||||
else:
|
||||
d = int(d)
|
||||
ndate = datetime.date(y, m, d)
|
||||
if self.debug: print ndate, offset, type(offset)
|
||||
if type(offset) == int:
|
||||
if offset != 0:
|
||||
ndate = ndate.fromordinal(ndate.toordinal() + offset)
|
||||
elif type(offset) in [type(u''), str]:
|
||||
dir = 1
|
||||
if offset[0] == "-":
|
||||
dir = -1
|
||||
offset = offset[1:]
|
||||
if offset in ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']:
|
||||
# next tuesday you come to, including this one
|
||||
dow = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'].index(offset)
|
||||
ord = ndate.toordinal()
|
||||
while ndate.fromordinal(ord).weekday() != dow:
|
||||
ord += dir
|
||||
ndate = ndate.fromordinal(ord)
|
||||
if self.debug: print "ndate:", ndate, "date:", date
|
||||
if ndate == date:
|
||||
if rule["if"] != "":
|
||||
if not eval(rule["if"]):
|
||||
continue
|
||||
retval.append(rule["name"])
|
||||
return retval
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Register this plugin
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from PluginMgr import register_report
|
||||
register_report(
|
||||
name = 'calendar',
|
||||
category = Report.CATEGORY_DRAW,
|
||||
report_class = Calendar,
|
||||
options_class = CalendarOptions,
|
||||
modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI,
|
||||
translated_name = _("Calendar"),
|
||||
status = _("Experimental"),
|
||||
author_name = "Douglas S. Blank",
|
||||
author_email = "Doug.Blank@gmail.com",
|
||||
description = _("Produces a graphical calendar"),
|
||||
)
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -80,10 +80,11 @@ class ChangeTypes(Tool.Tool):
|
||||
|
||||
AutoComp.fill_combo(self.auto1,const.personalEvents)
|
||||
AutoComp.fill_combo(self.auto2,const.personalEvents)
|
||||
self.auto1.child.set_text(
|
||||
self.options.handler.options_dict['fromtype'])
|
||||
self.auto2.child.set_text(
|
||||
self.options.handler.options_dict['totype'])
|
||||
# Need to display localized event names
|
||||
self.auto1.child.set_text(const.display_event(
|
||||
self.options.handler.options_dict['fromtype']))
|
||||
self.auto2.child.set_text(const.display_event(
|
||||
self.options.handler.options_dict['totype']))
|
||||
|
||||
self.title = _('Change Event Types')
|
||||
self.window = self.glade.get_widget('top')
|
||||
@@ -103,6 +104,7 @@ class ChangeTypes(Tool.Tool):
|
||||
|
||||
def run_tool(self,cli=False):
|
||||
# Run tool and return results
|
||||
# These are English names, no conversion needed
|
||||
fromtype = self.options.handler.options_dict['fromtype']
|
||||
totype = self.options.handler.options_dict['totype']
|
||||
|
||||
@@ -162,10 +164,11 @@ class ChangeTypes(Tool.Tool):
|
||||
self.window.present()
|
||||
|
||||
def on_apply_clicked(self,obj):
|
||||
self.options.handler.options_dict['fromtype'] = unicode(
|
||||
self.auto1.child.get_text())
|
||||
self.options.handler.options_dict['totype'] = unicode(
|
||||
self.auto2.child.get_text())
|
||||
# Need to store English names for later comparison
|
||||
self.options.handler.options_dict['fromtype'] = const.save_event(
|
||||
unicode(self.auto1.child.get_text()))
|
||||
self.options.handler.options_dict['totype'] = const.save_event(
|
||||
unicode(self.auto2.child.get_text()))
|
||||
|
||||
modified,msg = self.run_tool(cli=False)
|
||||
OkDialog(_('Change types'),msg,self.parent.topWindow)
|
||||
|
||||
@@ -51,6 +51,79 @@ import const
|
||||
import Tool
|
||||
from QuestionDialog import OkDialog, MissingMediaDialog
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Low Level repair
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def low_level(db):
|
||||
"""
|
||||
This is a low-level repair routine.
|
||||
|
||||
It is fixing DB inconsistencies such as duplicates.
|
||||
Returns a (status,name) tuple.
|
||||
The boolean status indicates the success of the procedure.
|
||||
The name indicates the problematic table (empty if status is True).
|
||||
"""
|
||||
|
||||
for the_map in [('Person',db.person_map),
|
||||
('Family',db.family_map),
|
||||
('Event',db.event_map),
|
||||
('Place',db.place_map),
|
||||
('Source',db.source_map),
|
||||
('Media',db.media_map)]:
|
||||
|
||||
print "Low-level repair: table: %s" % the_map[0]
|
||||
if _table_low_level(db,the_map[1]):
|
||||
print "Done."
|
||||
else:
|
||||
print "Low-level repair: Problem with table: %s" % the_map[0]
|
||||
return (False,the_map[0])
|
||||
return (True,'')
|
||||
|
||||
|
||||
def _table_low_level(db,table):
|
||||
"""
|
||||
Low level repair for a given db table.
|
||||
"""
|
||||
handle_list = table.keys()
|
||||
dup_handles = sets.Set(
|
||||
[ handle for handle in handle_list if handle_list.count(handle) > 1 ]
|
||||
)
|
||||
|
||||
if not dup_handles:
|
||||
print " No dupes found for this table"
|
||||
return True
|
||||
|
||||
import GrampsBSDDB
|
||||
table_cursor = GrampsBSDDB.GrampsBSDDBDupCursor(table)
|
||||
for handle in dup_handles:
|
||||
print " Duplicates found for handle: %s" % handle
|
||||
try:
|
||||
ret = table_cursor.set(handle)
|
||||
except:
|
||||
print " Failed setting initial cursor."
|
||||
return False
|
||||
|
||||
for count in range(handle_list.count(handle)-1):
|
||||
try:
|
||||
table_cursor.delete()
|
||||
print " Succesfully deleted dupe #%d" % (count+1)
|
||||
except:
|
||||
print " Failed deleting dupe."
|
||||
return False
|
||||
|
||||
try:
|
||||
ret = table_cursor.next_dup()
|
||||
except:
|
||||
print " Failed moving the cursor."
|
||||
return False
|
||||
|
||||
table_cursor.close()
|
||||
table.sync()
|
||||
return True
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# runTool
|
||||
@@ -68,6 +141,12 @@ class Check(Tool.Tool):
|
||||
# TODO: split plugin in a check and repair part to support
|
||||
# checking of a read only database
|
||||
return
|
||||
|
||||
# The low-level repair is bypassing the transaction mechanism.
|
||||
# As such, we run it before starting the transaction.
|
||||
# We only do this for the BSDDB backend.
|
||||
if db.__class__.__name__ == 'GrampsBSDDB':
|
||||
low_level(db)
|
||||
|
||||
trans = db.transaction_begin()
|
||||
trans.set_batch(True)
|
||||
@@ -137,10 +216,8 @@ class CheckIntegrity:
|
||||
self.progress.set_pass(_('Looking for duplicate spouses'),
|
||||
self.db.get_number_of_people())
|
||||
|
||||
cursor = self.db.get_person_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
(handle,value) = data
|
||||
for handle in self.db.person_map.keys():
|
||||
value = self.db.person_map[handle]
|
||||
p = RelLib.Person(value)
|
||||
splist = p.get_family_handle_list()
|
||||
if len(splist) != len(sets.Set(splist)):
|
||||
@@ -151,27 +228,21 @@ class CheckIntegrity:
|
||||
self.duplicate_links.append((handle,value))
|
||||
p.set_family_handle_list(new_list)
|
||||
self.db.commit_person(p,self.trans)
|
||||
data = cursor.next()
|
||||
self.progress.step()
|
||||
cursor.close()
|
||||
|
||||
|
||||
def fix_encoding(self):
|
||||
self.progress.set_pass(_('Looking for character encoding errors'),
|
||||
self.db.get_number_of_media_objects())
|
||||
|
||||
cursor = self.db.get_media_cursor()
|
||||
value = cursor.first()
|
||||
while value:
|
||||
(handle,data) = value
|
||||
for handle in self.db.media_map.keys():
|
||||
data = self.db.media_map[handle]
|
||||
if type(data[2]) != unicode or type(data[4]) != unicode:
|
||||
obj = self.db.get_object_from_handle(handle)
|
||||
obj.path = Utils.fix_encoding( obj.path)
|
||||
obj.desc = Utils.fix_encoding( obj.desc)
|
||||
self.db.commit_media_object(obj,self.trans)
|
||||
self.progress.step()
|
||||
value = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
def check_for_broken_family_links(self):
|
||||
# Check persons referenced by the family objects
|
||||
@@ -559,11 +630,9 @@ class CheckIntegrity:
|
||||
self.progress.set_pass(_('Looking for source reference problems'),
|
||||
total)
|
||||
|
||||
cursor = self.db.get_person_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.person_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.person_map[handle]
|
||||
person = RelLib.Person()
|
||||
person.unserialize(info)
|
||||
handle_list = person.get_referenced_handles_recursively()
|
||||
@@ -576,14 +645,10 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_family_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.family_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.family_map[handle]
|
||||
family = RelLib.Family()
|
||||
family.unserialize(info)
|
||||
handle_list = family.get_referenced_handles_recursively()
|
||||
@@ -596,14 +661,10 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_place_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.place_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.place_map[handle]
|
||||
place = RelLib.Place()
|
||||
place.unserialize(info)
|
||||
handle_list = place.get_referenced_handles_recursively()
|
||||
@@ -612,18 +673,14 @@ class CheckIntegrity:
|
||||
item[1] not in known_handles ]
|
||||
if bad_handles:
|
||||
place.remove_source_references(bad_handles)
|
||||
self.db.commit_family(place,self.trans)
|
||||
self.db.commit_place(place,self.trans)
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_source_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in known_handles:
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.source_map[handle]
|
||||
source = RelLib.Source()
|
||||
source.unserialize(info)
|
||||
handle_list = source.get_referenced_handles_recursively()
|
||||
@@ -636,14 +693,10 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_media_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.media_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.media_map[handle]
|
||||
obj = RelLib.MediaObject()
|
||||
obj.unserialize(info)
|
||||
handle_list = obj.get_referenced_handles_recursively()
|
||||
@@ -656,14 +709,10 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_event_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.event_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.event_map[handle]
|
||||
event = RelLib.Event()
|
||||
event.unserialize(info)
|
||||
handle_list = event.get_referenced_handles_recursively()
|
||||
@@ -676,8 +725,6 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
def build_report(self,cl=0):
|
||||
self.progress.close()
|
||||
|
||||
@@ -112,13 +112,15 @@ class DescendantReport(Report.Report):
|
||||
if birth:
|
||||
bplace_handle = birth.get_place_handle()
|
||||
if bplace_handle:
|
||||
birth_place = self.database.get_place_from_handle(bplace_handle).get_title()
|
||||
birth_place = self.database.get_place_from_handle(
|
||||
bplace_handle).get_title()
|
||||
|
||||
death_place = ""
|
||||
if death:
|
||||
dplace_handle = death.get_place_handle()
|
||||
if dplace_handle:
|
||||
death_place = self.database.get_place_from_handle(dplace_handle).get_title()
|
||||
death_place = self.database.get_place_from_handle(
|
||||
dplace_handle).get_title()
|
||||
|
||||
if birth_year_valid:
|
||||
if birth_place:
|
||||
@@ -163,7 +165,6 @@ class DescendantReport(Report.Report):
|
||||
if level >= self.max_generations:
|
||||
return
|
||||
|
||||
childlist = []
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
|
||||
@@ -176,10 +177,9 @@ class DescendantReport(Report.Report):
|
||||
self.dump_dates(spouse)
|
||||
self.doc.end_paragraph()
|
||||
|
||||
for child_handle in family.get_child_handle_list():
|
||||
childlist.append(child_handle)
|
||||
|
||||
childlist = family.get_child_handle_list()[:]
|
||||
childlist.sort(self.by_birthdate)
|
||||
|
||||
for child_handle in childlist:
|
||||
child = self.database.get_person_from_handle(child_handle)
|
||||
self.dump(level+1,child)
|
||||
@@ -230,7 +230,8 @@ class DescendantOptions(ReportOptions.ReportOptions):
|
||||
p.set_bottom_margin(ReportUtils.pt2cm(f.get_size()*0.125))
|
||||
p.set_first_indent(-0.5)
|
||||
p.set_left_margin(min(10.0,float(i-0.5)))
|
||||
p.set_description(_("The style used for the level %d display.") % i)
|
||||
p.set_description(_("The style used for the "
|
||||
"level %d display.") % i)
|
||||
default_style.add_style("DR-Level%d" % i,p)
|
||||
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
@@ -238,7 +239,8 @@ class DescendantOptions(ReportOptions.ReportOptions):
|
||||
p.set_top_margin(ReportUtils.pt2cm(f.get_size()*0.125))
|
||||
p.set_bottom_margin(ReportUtils.pt2cm(f.get_size()*0.125))
|
||||
p.set_left_margin(min(10.0,float(i-0.5)))
|
||||
p.set_description(_("The style used for the spouse level %d display.") % i)
|
||||
p.set_description(_("The style used for the "
|
||||
"spouse level %d display.") % i)
|
||||
default_style.add_style("DR-Spouse%d" % i,p)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2002 Bruce J. DeGrasse
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -235,8 +235,9 @@ class DetAncestorReport(Report.Report):
|
||||
self.endnotes(self.database.get_event_from_handle(birth_handle))
|
||||
first = 0
|
||||
|
||||
age,units = self.calc_age(person)
|
||||
text = ReportUtils.died_str(self.database,person,first,
|
||||
self.EMPTY_DATE,self.EMPTY_PLACE)
|
||||
self.EMPTY_DATE,self.EMPTY_PLACE,age,units)
|
||||
if text:
|
||||
self.doc.write_text(text)
|
||||
death_handle = person.get_birth_handle()
|
||||
@@ -503,25 +504,29 @@ class DetAncestorReport(Report.Report):
|
||||
self.doc.start_paragraph('DAR-Endnotes',"%d." % key)
|
||||
self.doc.write_text(base.get_title())
|
||||
|
||||
for item in [ base.get_author(), base.get_publication_info(),
|
||||
base.get_abbreviation(),
|
||||
_dd.display(srcref.get_date_object()),]:
|
||||
if item:
|
||||
self.doc.write_text('; %s' % item)
|
||||
|
||||
item = srcref.get_text()
|
||||
if item:
|
||||
self.doc.write_text('; ')
|
||||
self.doc.write_text(_('Text:'))
|
||||
self.doc.write_text(' ')
|
||||
self.doc.write_text(item)
|
||||
|
||||
item = srcref.get_note()
|
||||
if item:
|
||||
self.doc.write_text('; ')
|
||||
self.doc.write_text(_('Comments:'))
|
||||
self.doc.write_text(' ')
|
||||
self.doc.write_text(item)
|
||||
# Disable writing reference details, because only the details
|
||||
# the first reference to this source will appear.
|
||||
# FIXME: need to properly change self.endnotes() to put
|
||||
# this feature back correclty.
|
||||
## for item in [ base.get_author(), base.get_publication_info(),
|
||||
## base.get_abbreviation(),
|
||||
## _dd.display(srcref.get_date_object()),]:
|
||||
## if item:
|
||||
## self.doc.write_text('; %s' % item)
|
||||
##
|
||||
## item = srcref.get_text()
|
||||
## if item:
|
||||
## self.doc.write_text('; ')
|
||||
## self.doc.write_text(_('Text:'))
|
||||
## self.doc.write_text(' ')
|
||||
## self.doc.write_text(item)
|
||||
##
|
||||
## item = srcref.get_note()
|
||||
## if item:
|
||||
## self.doc.write_text('; ')
|
||||
## self.doc.write_text(_('Comments:'))
|
||||
## self.doc.write_text(' ')
|
||||
## self.doc.write_text(item)
|
||||
|
||||
self.doc.write_text('.')
|
||||
self.doc.end_paragraph()
|
||||
@@ -551,9 +556,9 @@ class DetAncestorReport(Report.Report):
|
||||
self.sref_map[self.sref_index] = ref
|
||||
msg.write("%d" % self.sref_index)
|
||||
msg.write('</super>')
|
||||
str = msg.getvalue()
|
||||
the_str = msg.getvalue()
|
||||
msg.close()
|
||||
return str
|
||||
return the_str
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2002 Bruce J. DeGrasse
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -88,6 +88,7 @@ class DetDescendantReport(Report.Report):
|
||||
firstName - Whether to use first names instead of pronouns.
|
||||
fullDate - Whether to use full dates instead of just year.
|
||||
listChildren - Whether to list children.
|
||||
includeMates - Whether to include information about spouses
|
||||
includeNotes - Whether to include notes.
|
||||
blankPlace - Whether to replace missing Places with ___________.
|
||||
blankDate - Whether to replace missing Dates with ___________.
|
||||
@@ -116,6 +117,7 @@ class DetDescendantReport(Report.Report):
|
||||
self.includeNames = options_class.handler.options_dict['incnames']
|
||||
self.includeEvents = options_class.handler.options_dict['incevents']
|
||||
self.includeSources= options_class.handler.options_dict['incsources']
|
||||
self.includeMates = options_class.handler.options_dict['incmates']
|
||||
|
||||
self.gen_handles = {}
|
||||
self.prev_gen_handles= {}
|
||||
@@ -261,9 +263,10 @@ class DetDescendantReport(Report.Report):
|
||||
if birth_handle:
|
||||
self.endnotes(self.database.get_event_from_handle(birth_handle))
|
||||
first = 0
|
||||
|
||||
|
||||
age,units = self.calc_age(person)
|
||||
text = ReportUtils.died_str(self.database,person,first,
|
||||
self.EMPTY_DATE,self.EMPTY_PLACE)
|
||||
self.EMPTY_DATE,self.EMPTY_PLACE,age,units)
|
||||
if text:
|
||||
self.doc.write_text(text)
|
||||
death_handle = person.get_birth_handle()
|
||||
@@ -283,7 +286,7 @@ class DetDescendantReport(Report.Report):
|
||||
self.write_marriage(person)
|
||||
self.doc.end_paragraph()
|
||||
|
||||
if key == 1:
|
||||
if self.includeMates:
|
||||
self.write_mate(person)
|
||||
|
||||
if person.get_note() != "" and self.includeNotes:
|
||||
@@ -528,24 +531,28 @@ class DetDescendantReport(Report.Report):
|
||||
self.doc.start_paragraph('DDR-Endnotes',"%d." % key)
|
||||
self.doc.write_text(base.get_title())
|
||||
|
||||
for item in [ base.get_author(), base.get_publication_info(), base.get_abbreviation(),
|
||||
_dd.display(srcref.get_date_object()),]:
|
||||
if item:
|
||||
self.doc.write_text('; %s' % item)
|
||||
|
||||
item = srcref.get_text()
|
||||
if item:
|
||||
self.doc.write_text('; ')
|
||||
self.doc.write_text(_('Text:'))
|
||||
self.doc.write_text(' ')
|
||||
self.doc.write_text(item)
|
||||
|
||||
item = srcref.get_note()
|
||||
if item:
|
||||
self.doc.write_text('; ')
|
||||
self.doc.write_text(_('Comments:'))
|
||||
self.doc.write_text(' ')
|
||||
self.doc.write_text(item)
|
||||
# Disable writing reference details, because only the details
|
||||
# the first reference to this source will appear.
|
||||
# FIXME: need to properly change self.endnotes() to put
|
||||
# this feature back correclty.
|
||||
## for item in [ base.get_author(), base.get_publication_info(), base.get_abbreviation(),
|
||||
## _dd.display(srcref.get_date_object()),]:
|
||||
## if item:
|
||||
## self.doc.write_text('; %s' % item)
|
||||
##
|
||||
## item = srcref.get_text()
|
||||
## if item:
|
||||
## self.doc.write_text('; ')
|
||||
## self.doc.write_text(_('Text:'))
|
||||
## self.doc.write_text(' ')
|
||||
## self.doc.write_text(item)
|
||||
##
|
||||
## item = srcref.get_note()
|
||||
## if item:
|
||||
## self.doc.write_text('; ')
|
||||
## self.doc.write_text(_('Comments:'))
|
||||
## self.doc.write_text(' ')
|
||||
## self.doc.write_text(item)
|
||||
|
||||
self.doc.write_text('.')
|
||||
self.doc.end_paragraph()
|
||||
@@ -610,6 +617,7 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
'incnames' : 0,
|
||||
'incevents' : 0,
|
||||
'incsources' : 0,
|
||||
'incmates' : 1,
|
||||
}
|
||||
self.options_help = {
|
||||
'fulldates' : ("=0/1","Whether to use full dates instead of just year.",
|
||||
@@ -651,6 +659,9 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
'incsources' : ("=0/1","Whether to include source references.",
|
||||
["Do not include sources","Include sources"],
|
||||
True),
|
||||
'incmates' : ("=0/1","Whether to include detailed spouse information.",
|
||||
["Do not include spouse info","Include spouse info"],
|
||||
True),
|
||||
}
|
||||
|
||||
def enable_options(self):
|
||||
@@ -820,6 +831,10 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
self.include_sources_option = gtk.CheckButton(_("Include sources"))
|
||||
self.include_sources_option.set_active(self.options_dict['incsources'])
|
||||
|
||||
# Print Spouses
|
||||
self.include_spouses_option = gtk.CheckButton(_("Include spouses"))
|
||||
self.include_spouses_option.set_active(self.options_dict['incmates'])
|
||||
|
||||
# Add new options. The first argument is the tab name for grouping options.
|
||||
# if you want to put everyting in the generic "Options" category, use
|
||||
# self.add_option(text,widget) instead of self.add_frame_option(category,text,widget)
|
||||
@@ -834,6 +849,7 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
dialog.add_frame_option(_('Include'),'',self.include_names_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_events_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_sources_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_spouses_option)
|
||||
dialog.add_frame_option(_('Missing information'),'',self.place_option)
|
||||
dialog.add_frame_option(_('Missing information'),'',self.date_option)
|
||||
|
||||
@@ -854,6 +870,7 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
self.options_dict['incnames'] = int(self.include_names_option.get_active())
|
||||
self.options_dict['incevents'] = int(self.include_events_option.get_active())
|
||||
self.options_dict['incsources'] = int(self.include_sources_option.get_active())
|
||||
self.options_dict['incmates'] = int(self.include_spouses_option.get_active())
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
@@ -311,8 +311,9 @@ class DisplayChart:
|
||||
|
||||
titles = []
|
||||
index = 0
|
||||
for v in self.event_titles:
|
||||
titles.append((v,index,150))
|
||||
for event_name in self.event_titles:
|
||||
# Need to display localized event names
|
||||
titles.append((const.display_event(event_name),index,150))
|
||||
index = index + 1
|
||||
|
||||
self.list = ListModel.ListModel(self.eventlist,titles)
|
||||
@@ -435,10 +436,12 @@ class DisplayChart:
|
||||
|
||||
pstyle = BaseDoc.PaperStyle("junk",10,10)
|
||||
doc = OpenSpreadSheet.OpenSpreadSheet(pstyle,BaseDoc.PAPER_PORTRAIT)
|
||||
doc.creator(self.db.get_researcher().get_name())
|
||||
spreadsheet = TableReport(name,doc)
|
||||
spreadsheet.initialize(len(self.event_titles))
|
||||
|
||||
spreadsheet.write_table_head(self.event_titles)
|
||||
spreadsheet.write_table_head([const.display_event(event_name)
|
||||
for event_name in self.event_titles])
|
||||
|
||||
index = 0
|
||||
for top in self.row_data:
|
||||
|
||||
+353
-153
@@ -46,7 +46,7 @@ import Report
|
||||
import BaseDoc
|
||||
import ReportOptions
|
||||
from DateHandler import displayer as _dd
|
||||
|
||||
import const
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# FamilyGroup
|
||||
@@ -71,7 +71,7 @@ class FamilyGroup(Report.Report):
|
||||
"""
|
||||
Report.Report.__init__(self,database,person,options_class)
|
||||
|
||||
self.family = None
|
||||
self.family_handle = None
|
||||
|
||||
spouse_id = options_class.handler.options_dict['spouse_id']
|
||||
if spouse_id:
|
||||
@@ -85,9 +85,18 @@ class FamilyGroup(Report.Report):
|
||||
this_spouse = database.get_person_from_handle(this_spouse_handle)
|
||||
this_spouse_id = this_spouse.get_gramps_id()
|
||||
if spouse_id == this_spouse_id:
|
||||
self.family = family
|
||||
self.family_handle = family_handle
|
||||
break
|
||||
|
||||
self.recursive = options_class.handler.options_dict['recursive']
|
||||
self.missingInfo = options_class.handler.options_dict['missinginfo']
|
||||
self.generations = options_class.handler.options_dict['generations']
|
||||
self.incParEvents = options_class.handler.options_dict['incParEvents']
|
||||
self.incParAddr = options_class.handler.options_dict['incParAddr']
|
||||
self.incParNotes = options_class.handler.options_dict['incParNotes']
|
||||
self.incParNames = options_class.handler.options_dict['incParNames']
|
||||
self.incRelDates = options_class.handler.options_dict['incRelDates']
|
||||
|
||||
def define_table_styles(self):
|
||||
"""
|
||||
Define the table styles used by the report.
|
||||
@@ -151,18 +160,58 @@ class FamilyGroup(Report.Report):
|
||||
table.set_column_width(3,40)
|
||||
self.doc.add_table_style('FGR-ChildTable',table)
|
||||
|
||||
def dump_parent_event(self,name,event):
|
||||
place = ""
|
||||
date = ""
|
||||
if event:
|
||||
date = event.get_date()
|
||||
place_handle = event.get_place_handle()
|
||||
if place_handle:
|
||||
place = self.database.get_place_from_handle(place_handle).get_title()
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(date)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(place)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
def dump_parent_line(self,name,text):
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd",2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(text)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
def dump_parent(self,person_handle):
|
||||
|
||||
if not person_handle:
|
||||
return
|
||||
|
||||
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
|
||||
|
||||
if person.get_gender() == RelLib.Person.MALE:
|
||||
the_id = _("Husband")
|
||||
else:
|
||||
the_id = _("Wife")
|
||||
|
||||
|
||||
self.doc.start_table(the_id,'FGR-ParentTable')
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-ParentHead',3)
|
||||
@@ -172,62 +221,20 @@ class FamilyGroup(Report.Report):
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
|
||||
birth_handle = person.get_birth_handle()
|
||||
bdate = ""
|
||||
bplace = ""
|
||||
birth = None
|
||||
if birth_handle:
|
||||
birth = self.database.get_event_from_handle(birth_handle)
|
||||
bdate = birth.get_date()
|
||||
bplace_handle = birth.get_place_handle()
|
||||
if bplace_handle:
|
||||
bplace = self.database.get_place_from_handle(bplace_handle).get_title()
|
||||
|
||||
if birth or self.missingInfo:
|
||||
self.dump_parent_event(_("Birth"),birth)
|
||||
|
||||
death_handle = person.get_death_handle()
|
||||
ddate = ""
|
||||
dplace = ""
|
||||
death = None
|
||||
if death_handle:
|
||||
death = self.database.get_event_from_handle(death_handle)
|
||||
ddate = death.get_date()
|
||||
dplace_handle = death.get_place_handle()
|
||||
if dplace_handle:
|
||||
dplace = self.database.get_place_from_handle(dplace_handle).get_title()
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Birth"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(bdate)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(bplace)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Death"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(ddate)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(dplace)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
if death or self.missingInfo:
|
||||
self.dump_parent_event(_("Death"),death)
|
||||
|
||||
family_handle = person.get_main_parents_family_handle()
|
||||
father_name = ""
|
||||
@@ -236,36 +243,81 @@ class FamilyGroup(Report.Report):
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
father_handle = family.get_father_handle()
|
||||
if father_handle:
|
||||
father_name = self.database.get_person_from_handle(father_handle).get_primary_name().get_regular_name()
|
||||
father = self.database.get_person_from_handle(father_handle)
|
||||
father_name = father.get_primary_name().get_regular_name()
|
||||
if self.incRelDates:
|
||||
birth_handle = father.get_birth_handle()
|
||||
birth = " "
|
||||
if birth_handle:
|
||||
birth = self.database.get_event_from_handle(birth_handle).get_date()
|
||||
death_handle = father.get_death_handle()
|
||||
death = " "
|
||||
if death_handle:
|
||||
death = self.database.get_event_from_handle(death_handle).get_date()
|
||||
if birth_handle or death_handle:
|
||||
father_name = "%s (%s - %s)" % (father_name,birth,death)
|
||||
mother_handle = family.get_mother_handle()
|
||||
if mother_handle:
|
||||
mother_name = self.database.get_person_from_handle(mother_handle).get_primary_name().get_regular_name()
|
||||
mother = self.database.get_person_from_handle(mother_handle)
|
||||
mother_name = mother.get_primary_name().get_regular_name()
|
||||
if self.incRelDates:
|
||||
birth_handle = mother.get_birth_handle()
|
||||
birth = " "
|
||||
if birth_handle:
|
||||
birth = self.database.get_event_from_handle(birth_handle).get_date()
|
||||
death_handle = mother.get_death_handle()
|
||||
death = " "
|
||||
if death_handle:
|
||||
death = self.database.get_event_from_handle(death_handle).get_date()
|
||||
if birth_handle or death_handle:
|
||||
mother_name = "%s (%s - %s)" % (mother_name,birth,death)
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Father"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd",2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(father_name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
if self.missingInfo or father_name != "":
|
||||
self.dump_parent_line(_("Father"),father_name)
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Mother"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd",2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(mother_name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
if self.missingInfo or mother_name != "":
|
||||
self.dump_parent_line(_("Mother"),mother_name)
|
||||
|
||||
if self.incParEvents:
|
||||
for event_handle in person.get_event_list():
|
||||
event = self.database.get_event_from_handle(event_handle)
|
||||
evtName = event.get_name()
|
||||
if (evtName != "Death") and (evtName != "Birth"):
|
||||
self.dump_parent_event(_(evtName),event)
|
||||
|
||||
if self.incParAddr:
|
||||
addrlist = person.get_address_list()[:]
|
||||
for addr in addrlist:
|
||||
location = "%s %s %s %s" % (addr.get_street(),addr.get_city(),
|
||||
addr.get_state(),addr.get_country())
|
||||
date = addr.get_date()
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Address"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(date)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(location)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
if self.incParNotes and (person.get_note() != ""):
|
||||
self.dump_parent_line(_("Notes"),person.get_note())
|
||||
|
||||
if self.incParNames:
|
||||
for alt_name in person.get_alternate_names():
|
||||
type = const.NameTypesMap.find_value(alt_name.get_type())
|
||||
name = alt_name.get_regular_name()
|
||||
self.dump_parent_line(type,name)
|
||||
|
||||
self.doc.end_table()
|
||||
|
||||
@@ -303,22 +355,6 @@ class FamilyGroup(Report.Report):
|
||||
def dump_child(self,index,person_handle):
|
||||
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-TextChild1')
|
||||
self.doc.start_paragraph('FGR-ChildText')
|
||||
if person.get_gender() == RelLib.Person.MALE:
|
||||
self.doc.write_text("%dM" % index)
|
||||
else:
|
||||
self.doc.write_text("%dF" % index)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-ChildName',3)
|
||||
self.doc.start_paragraph('FGR-ChildText')
|
||||
self.doc.write_text(person.get_primary_name().get_regular_name())
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
families = len(person.get_family_handle_list())
|
||||
birth_handle = person.get_birth_handle()
|
||||
if birth_handle:
|
||||
@@ -330,14 +366,55 @@ class FamilyGroup(Report.Report):
|
||||
death = self.database.get_event_from_handle(death_handle)
|
||||
else:
|
||||
death = None
|
||||
self.dump_child_event('FGR-TextChild1',_('Birth'),birth)
|
||||
if families == 0:
|
||||
self.dump_child_event('FGR-TextChild2',_('Death'),death)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild1',_('Death'),death)
|
||||
|
||||
index = 1
|
||||
|
||||
spouse_count = 0;
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
spouse_id = None
|
||||
if person_handle == family.get_father_handle():
|
||||
spouse_id = family.get_mother_handle()
|
||||
else:
|
||||
spouse_id = family.get_father_handle()
|
||||
if spouse_id:
|
||||
spouse_count = spouse_count + 1
|
||||
|
||||
self.doc.start_row()
|
||||
if spouse_count != 0 or self.missingInfo or death != None or birth != None:
|
||||
self.doc.start_cell('FGR-TextChild1')
|
||||
else:
|
||||
self.doc.start_cell('FGR-TextChild2')
|
||||
self.doc.start_paragraph('FGR-ChildText')
|
||||
if person.get_gender() == RelLib.Person.MALE:
|
||||
self.doc.write_text("%dM" % index)
|
||||
elif person.get_gender() == RelLib.Person.FEMALE:
|
||||
self.doc.write_text("%dF" % index)
|
||||
else:
|
||||
self.doc.write_text("%dU" % index)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-ChildName',3)
|
||||
self.doc.start_paragraph('FGR-ChildText')
|
||||
self.doc.write_text(person.get_primary_name().get_regular_name())
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
if self.missingInfo or birth != None:
|
||||
if spouse_count != 0 or self.missingInfo or death != None:
|
||||
self.dump_child_event('FGR-TextChild1',_('Birth'),birth)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild2',_('Birth'),birth)
|
||||
|
||||
|
||||
if self.missingInfo or death != None:
|
||||
if spouse_count == 0:
|
||||
self.dump_child_event('FGR-TextChild2',_('Death'),death)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild1',_('Death'),death)
|
||||
|
||||
index = 0
|
||||
for family_handle in person.get_family_handle_list():
|
||||
index = index + 1
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
for event_handle in family.get_event_list():
|
||||
if event_handle:
|
||||
@@ -348,63 +425,98 @@ class FamilyGroup(Report.Report):
|
||||
else:
|
||||
m = None
|
||||
|
||||
spouse_id = None
|
||||
if person_handle == family.get_father_handle():
|
||||
spouse_id = family.get_mother_handle()
|
||||
else:
|
||||
spouse_id = family.get_father_handle()
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-TextChild1')
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-TextContents')
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Spouse"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-TextContentsEnd',2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
|
||||
if spouse_id:
|
||||
spouse = self.database.get_person_from_handle(spouse_id)
|
||||
self.doc.write_text(spouse.get_primary_name().get_regular_name())
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
if index == families:
|
||||
self.dump_child_event('FGR-TextChild2',_("Married"),m)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild1',_("Married"),m)
|
||||
|
||||
|
||||
def write_report(self):
|
||||
self.doc.start_paragraph('FGR-Title')
|
||||
self.doc.write_text(_("Family Group Report"))
|
||||
self.doc.end_paragraph()
|
||||
|
||||
if self.family:
|
||||
self.dump_parent(self.family.get_father_handle())
|
||||
self.doc.start_paragraph("FGR-blank")
|
||||
self.doc.end_paragraph()
|
||||
self.dump_parent(self.family.get_mother_handle())
|
||||
|
||||
length = len(self.family.get_child_handle_list())
|
||||
if length > 0:
|
||||
self.doc.start_paragraph("FGR-blank")
|
||||
self.doc.end_paragraph()
|
||||
self.doc.start_table('FGR-Children','FGR-ChildTable')
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-ParentHead',4)
|
||||
self.doc.start_paragraph('FGR-ParentName')
|
||||
self.doc.write_text(_("Children"))
|
||||
self.doc.start_cell('FGR-TextChild1')
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-TextContents')
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Spouse"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-TextContentsEnd',2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
if spouse_id:
|
||||
spouse = self.database.get_person_from_handle(spouse_id)
|
||||
spouse_name = spouse.get_primary_name().get_regular_name()
|
||||
if self.incRelDates:
|
||||
birth_handle = spouse.get_birth_handle()
|
||||
birth = " "
|
||||
if birth_handle:
|
||||
birth = self.database.get_event_from_handle(birth_handle).get_date()
|
||||
death_handle = spouse.get_death_handle()
|
||||
death = " "
|
||||
if death_handle:
|
||||
death = self.database.get_event_from_handle(death_handle).get_date()
|
||||
if birth_handle or death_handle:
|
||||
spouse_name = "%s (%s - %s)" % (spouse_name,birth,death)
|
||||
self.doc.write_text(spouse_name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
index = 1
|
||||
for child_handle in self.family.get_child_handle_list():
|
||||
self.dump_child(index,child_handle)
|
||||
index = index + 1
|
||||
self.doc.end_table()
|
||||
|
||||
if m:
|
||||
if index == families:
|
||||
self.dump_child_event('FGR-TextChild2',_("Married"),m)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild1',_("Married"),m)
|
||||
|
||||
def dump_family(self,family_handle,generation):
|
||||
self.doc.start_paragraph('FGR-Title')
|
||||
if self.recursive and self.generations:
|
||||
self.doc.write_text(_("Family Group Report - Generation %d") % generation)
|
||||
else:
|
||||
self.doc.write_text(_("Family Group Report") )
|
||||
self.doc.end_paragraph()
|
||||
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
|
||||
self.dump_parent(family.get_father_handle())
|
||||
self.doc.start_paragraph("FGR-blank")
|
||||
self.doc.end_paragraph()
|
||||
self.dump_parent(family.get_mother_handle())
|
||||
|
||||
length = len(family.get_child_handle_list())
|
||||
if length > 0:
|
||||
self.doc.start_paragraph("FGR-blank")
|
||||
self.doc.end_paragraph()
|
||||
self.doc.start_table('FGR-Children','FGR-ChildTable')
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-ParentHead',4)
|
||||
self.doc.start_paragraph('FGR-ParentName')
|
||||
self.doc.write_text(_("Children"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
index = 1
|
||||
for child_handle in family.get_child_handle_list():
|
||||
self.dump_child(index,child_handle)
|
||||
index = index + 1
|
||||
self.doc.end_table()
|
||||
|
||||
if self.recursive:
|
||||
for child_handle in family.get_child_handle_list():
|
||||
child = self.database.get_person_from_handle(child_handle)
|
||||
for child_family_handle in child.get_family_handle_list():
|
||||
if child_family_handle != family_handle:
|
||||
self.doc.page_break()
|
||||
self.dump_family(child_family_handle,(generation+1))
|
||||
|
||||
def write_report(self):
|
||||
if self.family_handle:
|
||||
self.dump_family(self.family_handle,1)
|
||||
else:
|
||||
self.doc.start_paragraph('FGR-Title')
|
||||
self.doc.write_text(_("Family Group Report"))
|
||||
self.doc.end_paragraph()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -424,6 +536,14 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
|
||||
# Options specific for this report
|
||||
self.options_dict = {
|
||||
'spouse_id' : '',
|
||||
'recursive' : 0,
|
||||
'missinginfo' : 1,
|
||||
'generations' : 1,
|
||||
'incParEvents' : 0,
|
||||
'incParAddr' : 0,
|
||||
'incParNotes' : 0,
|
||||
'incParNames' : 0,
|
||||
'incRelDates' : 0,
|
||||
}
|
||||
|
||||
self.options_help = {
|
||||
@@ -432,6 +552,37 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
|
||||
#[item[0] for item in self.get_spouses(None,None)],
|
||||
#False
|
||||
),
|
||||
'recursive' : ("=0/1","Create reports for all decendants of this family.",
|
||||
["Do not create reports for decendants","Create reports for decendants"],
|
||||
False),
|
||||
|
||||
'missinginfo' : ("=0/1","Whether to include fields for missing information.",
|
||||
["Do not include missing info","Include missing info"],
|
||||
True),
|
||||
|
||||
'generations' : ("=0/1","Whether to include the generation on each report (recursive only).",
|
||||
["Do not include the generation","Include the generation"],
|
||||
True),
|
||||
|
||||
'incParEvents' : ("=0/1","Whether to include events for parents.",
|
||||
["Do not include parental events","Include parental events"],
|
||||
True),
|
||||
|
||||
'incParAddr' : ("=0/1","Whether to include addresses for parents.",
|
||||
["Do not include parental addresses","Include parental addresses"],
|
||||
True),
|
||||
|
||||
'incParNotes' : ("=0/1","Whether to include notes for parents.",
|
||||
["Do not include parental notes","Include parental notes"],
|
||||
True),
|
||||
|
||||
'incParNames' : ("=0/1","Whether to include alternate names for parents.",
|
||||
["Do not include parental names","Include parental names"],
|
||||
True),
|
||||
|
||||
'incRelDates' : ("=0/1","Whether to include dates for relatives.",
|
||||
["Do not include dates of relatives","Include dates of relatives"],
|
||||
True),
|
||||
}
|
||||
|
||||
def get_spouses(self,database,person):
|
||||
@@ -476,8 +627,48 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
|
||||
spouse_index = index
|
||||
index = index + 1
|
||||
self.spouse_menu.set_active(spouse_index)
|
||||
|
||||
# Recursive
|
||||
self.recursive_option = gtk.CheckButton()
|
||||
self.recursive_option.set_active(self.options_dict['recursive'])
|
||||
|
||||
# Missing Info
|
||||
self.missing_info_option = gtk.CheckButton(_("Print fields for missing information"))
|
||||
self.missing_info_option.set_active(self.options_dict['missinginfo'])
|
||||
|
||||
# Generations
|
||||
self.include_generations_option = gtk.CheckButton(_("Generation numbers (recursive only)"))
|
||||
self.include_generations_option.set_active(self.options_dict['generations'])
|
||||
|
||||
# Parental Events
|
||||
self.include_par_events_option = gtk.CheckButton(_("Parent Events"))
|
||||
self.include_par_events_option.set_active(self.options_dict['incParEvents'])
|
||||
|
||||
# Parental Addresses
|
||||
self.include_par_addr_option = gtk.CheckButton(_("Parent Addresses"))
|
||||
self.include_par_addr_option.set_active(self.options_dict['incParAddr'])
|
||||
|
||||
# Parental Notes
|
||||
self.include_par_notes_option = gtk.CheckButton(_("Parent Notes"))
|
||||
self.include_par_notes_option.set_active(self.options_dict['incParNotes'])
|
||||
|
||||
# Parental Names
|
||||
self.include_par_names_option = gtk.CheckButton(_("Alternate Parent Names"))
|
||||
self.include_par_names_option.set_active(self.options_dict['incParNames'])
|
||||
|
||||
# Relatives Dates
|
||||
self.include_rel_dates_option = gtk.CheckButton(_("Dates of Relatives (father, mother, spouse)"))
|
||||
self.include_rel_dates_option.set_active(self.options_dict['incRelDates'])
|
||||
|
||||
dialog.add_option(_("Spouse"),self.spouse_menu)
|
||||
dialog.add_option(_("Recursive"),self.recursive_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_generations_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_par_events_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_par_addr_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_par_notes_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_par_names_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_rel_dates_option)
|
||||
dialog.add_frame_option(_('Missing Information'),'',self.missing_info_option)
|
||||
|
||||
def parse_user_options(self,dialog):
|
||||
"""
|
||||
@@ -487,6 +678,15 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
|
||||
spouse_index = self.spouse_menu.get_active()
|
||||
if spouses:
|
||||
self.options_dict['spouse_id'] = spouses[spouse_index][0]
|
||||
|
||||
self.options_dict['recursive'] = int(self.recursive_option.get_active())
|
||||
self.options_dict['missinginfo'] = int(self.missing_info_option.get_active())
|
||||
self.options_dict['generations'] = int(self.include_generations_option.get_active())
|
||||
self.options_dict['incParEvents'] = int(self.include_par_events_option.get_active())
|
||||
self.options_dict['incParAddr'] = int(self.include_par_addr_option.get_active())
|
||||
self.options_dict['incParNotes'] = int(self.include_par_notes_option.get_active())
|
||||
self.options_dict['incParNames'] = int(self.include_par_names_option.get_active())
|
||||
self.options_dict['incRelDates'] = int(self.include_rel_dates_option.get_active())
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
"""Make default output style for the Family Group Report."""
|
||||
|
||||
+407
-236
@@ -18,7 +18,6 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
"Generate files/Relationship graph"
|
||||
@@ -68,19 +67,42 @@ class _options:
|
||||
("gif", "GIF image", _("GIF image")),
|
||||
)
|
||||
fonts = (
|
||||
# Last items tells whether strings need to be converted to Latin1
|
||||
("", "Default", _("Default"), 1),
|
||||
("Helvetica", "Postscript / Helvetica", _("Postscript / Helvetica"), 1),
|
||||
("FreeSans", "Truetype / FreeSans", _("Truetype / FreeSans"), 0),
|
||||
("", "Default", _("Default")),
|
||||
("Helvetica", "Postscript / Helvetica", _("Postscript / Helvetica")),
|
||||
("FreeSans", "Truetype / FreeSans", _("Truetype / FreeSans")),
|
||||
)
|
||||
colors = (
|
||||
("outline", "B&W Outline", _("B&W outline")),
|
||||
("colored", "Colored outline", _("Colored outline")),
|
||||
("filled", "Color fill", _("Color fill")),
|
||||
)
|
||||
ratio = (
|
||||
("compress", "Minimal size", _("Minimal size")),
|
||||
("fill", "Fill the given area", _("Fill the given area")),
|
||||
("expand", "Automatically use optimal number of pages", _("Automatically use optimal number of pages"))
|
||||
)
|
||||
attract = (
|
||||
("parents", "Parents", _("Parents")),
|
||||
("children", "Children", _("Children")),
|
||||
("none", "Neither", _("Neither"))
|
||||
)
|
||||
rankdir = (
|
||||
("TB", "Vertical", _("Vertical")),
|
||||
("LR", "Horizontal", _("Horizontal")),
|
||||
("RL", "Vertical", _("Vertical")),
|
||||
)
|
||||
pagedir = (
|
||||
("BL", "Bottom, left", _("Bottom, left")),
|
||||
("BR", "Bottom, right", _("Bottom, right")),
|
||||
("TL", "Top, left", _("Top, left")),
|
||||
("TR", "Top, right", _("Top, Right")),
|
||||
("RB", "Right, bottom", _("Right, bottom")),
|
||||
("RT", "Right, top", _("Right, top")),
|
||||
("LB", "Left, bottom", _("Left, bottom")),
|
||||
("LT", "Left, top", _("Left, top")),
|
||||
)
|
||||
noteloc = (
|
||||
("t", "Top", _("Top")),
|
||||
("b", "Bottom", _("Bottom")),
|
||||
)
|
||||
arrowstyles = (
|
||||
('d', "Descendants <- Ancestors", _("Descendants <- Ancestors")),
|
||||
@@ -115,7 +137,7 @@ class GraphViz:
|
||||
The option class carries its number, and the function
|
||||
returning the list of filters.
|
||||
font - Font to use.
|
||||
latin - Set if font supports only Latin1
|
||||
latin - Set if text needs to be converted to latin-1
|
||||
arrow - Arrow styles for heads and tails.
|
||||
showfamily - Whether to show family nodes.
|
||||
incid - Whether to include IDs.
|
||||
@@ -123,12 +145,16 @@ class GraphViz:
|
||||
justyears - Use years only.
|
||||
placecause - Whether to replace missing dates with place or cause
|
||||
url - Whether to include URLs.
|
||||
rankdir - Graph direction
|
||||
rankdir - Graph direction, LR or RL
|
||||
ratio - Output aspect ration, fill/compress/auto
|
||||
color - Whether to use outline, colored outline or filled color in graph
|
||||
dashedl - Whether to use dashed lines for non-birth relationships.
|
||||
margin - Margins, in cm.
|
||||
pagesh - Number of pages in horizontal direction.
|
||||
pagesv - Number of pages in vertical direction.
|
||||
pagedir - Paging direction
|
||||
note - Note to add to the graph
|
||||
noteloc - Note location t/b
|
||||
"""
|
||||
colored = {
|
||||
'male': 'dodgerblue4',
|
||||
@@ -151,11 +177,14 @@ class GraphViz:
|
||||
self.height = self.paper.get_height_inches()
|
||||
|
||||
options = options_class.handler.options_dict
|
||||
self.pagedir = options['pagedir']
|
||||
self.hpages = options['pagesh']
|
||||
self.vpages = options['pagesv']
|
||||
margin_cm = options['margin']
|
||||
self.margin = round(margin_cm/2.54,2)
|
||||
if margin_cm > 0.1:
|
||||
# GraphViz has rounding errors so have to make the real
|
||||
# margins slightly smaller than (page - content size)
|
||||
self.margin_small = round((margin_cm-0.1)/2.54,2)
|
||||
else:
|
||||
self.margin_small = 0
|
||||
@@ -167,8 +196,9 @@ class GraphViz:
|
||||
self.just_years = options['justyears']
|
||||
self.placecause = options['placecause']
|
||||
self.rankdir = options['rankdir']
|
||||
self.attract = options['attract']
|
||||
self.ratio = options['ratio']
|
||||
self.fontname = options['font']
|
||||
self.latin = options['latin']
|
||||
self.colorize = options['color']
|
||||
if self.colorize == 'colored':
|
||||
self.colors = colored
|
||||
@@ -184,184 +214,300 @@ class GraphViz:
|
||||
else:
|
||||
self.arrowtailstyle = 'none'
|
||||
|
||||
self.latin = options['latin']
|
||||
self.noteloc = options['noteloc']
|
||||
self.note = options['note']
|
||||
|
||||
filter_num = options_class.get_filter_number()
|
||||
filters = options_class.get_report_filters(person)
|
||||
filters.extend(GenericFilter.CustomFilters.get_filters())
|
||||
self.filter = filters[filter_num]
|
||||
|
||||
buffer = self.get_report()
|
||||
self.f = open(options_class.get_output(),'w')
|
||||
self.write_report()
|
||||
if self.latin:
|
||||
self.f.write(buffer.encode('iso-8859-1'))
|
||||
else:
|
||||
self.f.write(buffer)
|
||||
self.f.close()
|
||||
|
||||
def write_report(self):
|
||||
|
||||
self.ind_list = self.filter.apply(self.database,
|
||||
|
||||
def get_report(self):
|
||||
"return string of the .dot file contents"
|
||||
self.person_handles = self.filter.apply(self.database,
|
||||
self.database.get_person_handles(sort_handles=False))
|
||||
|
||||
self.write_header()
|
||||
self.f.write("digraph GRAMPS_relationship_graph {\n")
|
||||
self.f.write("bgcolor=white;\n")
|
||||
self.f.write("rankdir=%s;\n" % self.rankdir)
|
||||
self.f.write("center=1;\n")
|
||||
self.f.write("margin=%3.2f;\n" % self.margin_small)
|
||||
self.f.write("ratio=fill;\n")
|
||||
# graph size
|
||||
if self.orient == PAPER_LANDSCAPE:
|
||||
self.f.write("size=\"%3.2f,%3.2f\";\n" % (
|
||||
(self.height-self.margin*2)*self.hpages,
|
||||
(self.width-self.margin*2)*self.vpages
|
||||
))
|
||||
rotate = 90
|
||||
sizew = (self.height - self.margin*2) * self.hpages
|
||||
sizeh = (self.width - self.margin*2) * self.vpages
|
||||
else:
|
||||
self.f.write("size=\"%3.2f,%3.2f\";\n" % (
|
||||
(self.width-self.margin*2)*self.hpages,
|
||||
(self.height-self.margin*2)*self.vpages
|
||||
))
|
||||
self.f.write("page=\"%3.2f,%3.2f\";\n" % (self.width,self.height))
|
||||
rotate = 0
|
||||
sizew = (self.width - self.margin*2) * self.hpages
|
||||
sizeh = (self.height - self.margin*2) * self.vpages
|
||||
|
||||
|
||||
buffer = self.get_comment_header()
|
||||
buffer += """
|
||||
digraph GRAMPS_relationship_graph {
|
||||
/* whole graph attributes */
|
||||
bgcolor=white;
|
||||
center=1;
|
||||
ratio=%s;
|
||||
rankdir=%s;
|
||||
mclimit=2.0;
|
||||
margin="%3.2f";
|
||||
pagedir="%s";
|
||||
page="%3.2f,%3.2f";
|
||||
size="%3.2f,%3.2f";
|
||||
rotate=%d;
|
||||
/* default node and edge attributes */
|
||||
nodesep=0.25;
|
||||
edge [syle=solid, arrowhead=%s arrowtail=%s];
|
||||
""" % (
|
||||
self.ratio,
|
||||
self.rankdir,
|
||||
self.margin_small,
|
||||
self.pagedir,
|
||||
self.width, self.height,
|
||||
sizew, sizeh,
|
||||
rotate,
|
||||
self.arrowheadstyle,
|
||||
self.arrowtailstyle
|
||||
)
|
||||
|
||||
if self.orient == PAPER_LANDSCAPE:
|
||||
self.f.write("rotate=90;\n")
|
||||
if self.fontname:
|
||||
font = 'fontname="%s"' % self.fontname
|
||||
else:
|
||||
font = ''
|
||||
if self.colorize == 'filled':
|
||||
buffer += 'node [style=filled %s];\n' % font
|
||||
else:
|
||||
buffer += 'node [%s];\n' % font
|
||||
if self.latin:
|
||||
# GraphViz default is UTF-8
|
||||
buffer += 'charset="iso-8859-1";\n'
|
||||
|
||||
if len(self.person_handles) > 1:
|
||||
buffer += "/* persons and their families */\n"
|
||||
buffer += self.get_persons_and_families()
|
||||
buffer += "/* link children to families */\n"
|
||||
buffer += self.get_child_links_to_families()
|
||||
|
||||
if len(self.ind_list) > 1:
|
||||
self.dump_index()
|
||||
self.dump_person()
|
||||
if self.note:
|
||||
buffer += 'labelloc="%s";\n' % self.noteloc
|
||||
buffer += 'label="%s";\n' % self.note.replace('\n', '\\n').replace('"', '\\\"')
|
||||
buffer += 'fontsize="20";\n' # in points
|
||||
|
||||
self.f.write("}\n")
|
||||
return buffer + "}\n"
|
||||
|
||||
def dump_person(self):
|
||||
# Hash people in a dictionary for faster inclusion checking.
|
||||
|
||||
def get_comment_header(self):
|
||||
"return comment of Gramps options which are not Graphviz options"
|
||||
return """/*
|
||||
GRAMPS - Relationship graph
|
||||
|
||||
Generated on %s.
|
||||
|
||||
Report content options:
|
||||
include URLs : %s
|
||||
IDs : %s
|
||||
dates : %s
|
||||
just year : %s
|
||||
place or cause : %s
|
||||
colorize : %s
|
||||
dotted adoptions : %s
|
||||
show family nodes : %s
|
||||
pages horizontal : %s
|
||||
vertical : %s
|
||||
|
||||
For other options, see graph settings below.
|
||||
|
||||
If you need to switch between iso-8859-1 and utf-8 text encodings,
|
||||
e.g. because you're using different font or -T output format,
|
||||
just use iconv:
|
||||
iconv -f iso-8859-1 -t utf-8 old.dot > new.dot
|
||||
iconv -t utf-8 -f iso-8859-1 old.dot > new.dot
|
||||
*/
|
||||
""" % (
|
||||
asctime(),
|
||||
bool(self.includeurl),
|
||||
bool(self.includeid),
|
||||
bool(self.includedates),
|
||||
bool(self.just_years),
|
||||
bool(self.placecause),
|
||||
bool(self.colorize),
|
||||
bool(self.adoptionsdashed),
|
||||
bool(self.show_families),
|
||||
self.hpages, self.vpages
|
||||
)
|
||||
|
||||
|
||||
def get_child_links_to_families(self):
|
||||
"returns string of GraphViz edges linking parents to families or children"
|
||||
person_dict = {}
|
||||
for p_id in self.ind_list:
|
||||
person_dict[p_id] = 1
|
||||
|
||||
for person_handle in self.ind_list:
|
||||
# Hash people in a dictionary for faster inclusion checking
|
||||
for person_handle in self.person_handles:
|
||||
person_dict[person_handle] = 1
|
||||
buffer = ""
|
||||
for person_handle in self.person_handles:
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
pid = person.get_gramps_id().replace('-','_')
|
||||
for family_handle, mrel, frel in person.get_parent_family_handle_list():
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
p_id = person.get_gramps_id()
|
||||
for fam_handle,mrel,frel in person.get_parent_family_handle_list():
|
||||
family = self.database.get_family_from_handle(fam_handle)
|
||||
father_handle = family.get_father_handle()
|
||||
mother_handle = family.get_mother_handle()
|
||||
fadopted = frel != RelLib.Person.CHILD_REL_BIRTH
|
||||
madopted = mrel != RelLib.Person.CHILD_REL_BIRTH
|
||||
famid = family.get_gramps_id().replace('-','_')
|
||||
if (self.show_families and
|
||||
(father_handle and person_dict.has_key(father_handle) or
|
||||
mother_handle and person_dict.has_key(mother_handle))):
|
||||
# Link to the family node.
|
||||
self.f.write('p%s -> f%s [' % (pid, famid))
|
||||
self.f.write('arrowhead=%s, arrowtail=%s, ' %
|
||||
(self.arrowheadstyle, self.arrowtailstyle))
|
||||
if self.adoptionsdashed and (fadopted or madopted):
|
||||
self.f.write('style=dotted')
|
||||
else:
|
||||
self.f.write('style=solid')
|
||||
self.f.write('];\n')
|
||||
((father_handle and father_handle in person_dict) or
|
||||
(mother_handle and mother_handle in person_dict))):
|
||||
# Link to the family node if either parent is in graph
|
||||
buffer += self.get_family_link(p_id, family, frel, mrel)
|
||||
else:
|
||||
# Link to the parents' nodes directly.
|
||||
if father_handle and person_dict.has_key(father_handle):
|
||||
father = self.database.get_person_from_handle(father_handle)
|
||||
fid = father.get_gramps_id().replace('-','_')
|
||||
self.f.write('p%s -> p%s [' % (pid, fid))
|
||||
self.f.write('arrowhead=%s, arrowtail=%s, ' %
|
||||
(self.arrowheadstyle, self.arrowtailstyle))
|
||||
if self.adoptionsdashed and fadopted:
|
||||
self.f.write('style=dotted')
|
||||
else:
|
||||
self.f.write('style=solid')
|
||||
self.f.write('];\n')
|
||||
if mother_handle and person_dict.has_key(mother_handle):
|
||||
mother = self.database.get_person_from_handle(mother_handle)
|
||||
mid = mother.get_gramps_id().replace('-','_')
|
||||
self.f.write('p%s -> p%s [' % (pid, mid))
|
||||
self.f.write('arrowhead=%s, arrowtail=%s, ' %
|
||||
(self.arrowheadstyle, self.arrowtailstyle))
|
||||
if self.adoptionsdashed and madopted:
|
||||
self.f.write('style=dotted')
|
||||
else:
|
||||
self.f.write('style=solid')
|
||||
self.f.write('];\n')
|
||||
|
||||
def dump_index(self):
|
||||
# The list of families for which we have output the node, so we
|
||||
# don't do it twice.
|
||||
families_done = []
|
||||
for person_handle in self.ind_list:
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
# Output the person's node.
|
||||
label = person.get_primary_name().get_name()
|
||||
the_id = person.get_gramps_id().replace('-','_')
|
||||
if self.includeid:
|
||||
label = label + " (%s)" % the_id
|
||||
if self.includedates:
|
||||
birth_handle = person.get_birth_handle()
|
||||
if birth_handle:
|
||||
birth_event = self.database.get_event_from_handle(birth_handle)
|
||||
birth = self.dump_event(birth_event)
|
||||
else:
|
||||
birth = ''
|
||||
death_handle = person.get_death_handle()
|
||||
if death_handle:
|
||||
death_event = self.database.get_event_from_handle(death_handle)
|
||||
death = self.dump_event(death_event)
|
||||
else:
|
||||
death = ''
|
||||
label = label + '\\n(%s - %s)' % (birth, death)
|
||||
self.f.write('p%s [shape=box, ' % the_id)
|
||||
if self.includeurl:
|
||||
self.f.write('URL="%s.html", ' % the_id)
|
||||
if self.colorize != 'outline':
|
||||
if self.colorize == 'filled':
|
||||
style = 'style=filled, fillcolor'
|
||||
else:
|
||||
style = 'color'
|
||||
gender = person.get_gender()
|
||||
if gender == person.MALE:
|
||||
self.f.write('%s=%s, ' % (style, self.colors['male']))
|
||||
elif gender == person.FEMALE:
|
||||
self.f.write('%s=%s, ' % (style, self.colors['female']))
|
||||
else:
|
||||
self.f.write('%s=%s, ' % (style, self.colors['unknown']))
|
||||
if self.latin:
|
||||
label = label.encode('iso-8859-1')
|
||||
self.f.write('fontname="%s", label="%s"];\n' % (self.fontname,label))
|
||||
# Link to the parents' nodes directly, if they are in graph
|
||||
if father_handle and father_handle in person_dict:
|
||||
buffer += self.get_parent_link(p_id, father_handle, frel)
|
||||
if mother_handle and mother_handle in person_dict:
|
||||
buffer += self.get_parent_link(p_id, mother_handle, mrel)
|
||||
return buffer
|
||||
|
||||
# Output families's nodes.
|
||||
|
||||
def get_family_link(self, p_id, family, frel, mrel):
|
||||
"returns string of GraphViz edge linking child to family"
|
||||
weight = style = ''
|
||||
adopted = ((frel != RelLib.Person.CHILD_REL_BIRTH) or
|
||||
(mrel != RelLib.Person.CHILD_REL_BIRTH))
|
||||
if adopted and self.adoptionsdashed:
|
||||
style = 'style=dotted'
|
||||
if self.attract == "children":
|
||||
weight = 'weight="5"'
|
||||
return '"p%s" -> "f%s" [%s %s];\n' % (p_id,
|
||||
family.get_gramps_id(), style, weight)
|
||||
|
||||
def get_parent_link(self, p_id, parent_handle, rel):
|
||||
"returns string of GraphViz edge linking child to parent"
|
||||
style = ''
|
||||
if (rel != RelLib.Person.CHILD_REL_BIRTH) and self.adoptionsdashed:
|
||||
style = 'style=dotted'
|
||||
parent = self.database.get_person_from_handle(parent_handle)
|
||||
return '"p%s" -> "p%s" [%s];\n' % (p_id, parent.get_gramps_id(), style)
|
||||
|
||||
|
||||
def get_persons_and_families(self):
|
||||
"returns string of GraphViz nodes for persons and their families"
|
||||
# The list of families for which we have output the node,
|
||||
# so we don't do it twice
|
||||
buffer = ""
|
||||
families_done = {}
|
||||
for person_handle in self.person_handles:
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
p_id = person.get_gramps_id()
|
||||
# Output the person's node
|
||||
label = self.get_person_label(person)
|
||||
style = self.get_gender_style(person)
|
||||
url = ""
|
||||
if self.includeurl:
|
||||
h = person_handle
|
||||
url = ', URL="ppl/%s/%s/%s.html", ' % (h[0],h[1],h)
|
||||
buffer += '"p%s" [label="%s", %s%s];\n' % (p_id, label, style, url)
|
||||
|
||||
# Output families where person is a parent
|
||||
if self.show_families:
|
||||
family_list = person.get_family_handle_list()
|
||||
for fam_handle in family_list:
|
||||
fam = self.database.get_family_from_handle(fam_handle)
|
||||
fid = fam.get_gramps_id().replace('-','_')
|
||||
fam_id = fam.get_gramps_id()
|
||||
if fam_handle not in families_done:
|
||||
families_done.append(fam_handle)
|
||||
self.f.write('f%s [shape=ellipse, ' % fid)
|
||||
if self.colorize == 'colored':
|
||||
self.f.write('color=%s, ' % self.colors['family'])
|
||||
elif self.colorize == 'filled':
|
||||
self.f.write('style=filled fillcolor=%s, ' % self.colors['family'])
|
||||
|
||||
marriage = ""
|
||||
families_done[fam_handle] = 1
|
||||
label = ""
|
||||
for event_handle in fam.get_event_list():
|
||||
if event_handle:
|
||||
event = self.database.get_event_from_handle(event_handle)
|
||||
if event.get_name() == "Marriage":
|
||||
m = event
|
||||
label = self.get_event_string(event)
|
||||
break
|
||||
else:
|
||||
m = None
|
||||
|
||||
if m:
|
||||
marriage = self.dump_event(m)
|
||||
if self.includeid:
|
||||
marriage = marriage + " (%s)" % fid
|
||||
self.f.write('fontname="%s", label="%s"];\n'
|
||||
% (self.fontname,marriage))
|
||||
label = "%s (%s)" % (label, fam_id)
|
||||
color = ""
|
||||
if self.colorize == 'colored':
|
||||
color = ', color="%s"' % self.colors['family']
|
||||
elif self.colorize == 'filled':
|
||||
color = ', fillcolor="%s"' % self.colors['family']
|
||||
buffer += '"f%s" [shape=ellipse, label="%s"%s];\n' % (fam_id, label, color)
|
||||
# Link this person to all his/her families.
|
||||
self.f.write('f%s -> p%s [' % (fid, the_id))
|
||||
self.f.write('arrowhead=%s, arrowtail=%s, ' %
|
||||
(self.arrowheadstyle, self.arrowtailstyle))
|
||||
self.f.write('style=solid];\n')
|
||||
if self.attract == "parents":
|
||||
weight = 'weight="5"'
|
||||
else:
|
||||
weight = ''
|
||||
buffer += '"f%s" -> "p%s" [%s];\n' % (fam_id, p_id, weight)
|
||||
return buffer
|
||||
|
||||
|
||||
def get_gender_style(self, person):
|
||||
"return gender specific person style"
|
||||
gender = person.get_gender()
|
||||
if gender == person.MALE:
|
||||
shape = 'shape="box"'
|
||||
elif gender == person.FEMALE:
|
||||
shape = 'shape="box", style="rounded"'
|
||||
else:
|
||||
shape = 'shape="hexagon"'
|
||||
if self.colorize == 'outline':
|
||||
return shape
|
||||
else:
|
||||
if gender == person.MALE:
|
||||
color = self.colors['male']
|
||||
elif gender == person.FEMALE:
|
||||
color = self.colors['female']
|
||||
else:
|
||||
color = self.colors['unknown']
|
||||
if self.colorize == 'filled':
|
||||
# In current GraphViz boxes cannot be both rounded and filled
|
||||
return 'shape="box", fillcolor="%s"' % color
|
||||
else:
|
||||
return '%s, color="%s"' % (shape, color)
|
||||
|
||||
def get_person_label(self, person):
|
||||
"return person label string"
|
||||
label = person.get_primary_name().get_name()
|
||||
p_id = person.get_gramps_id()
|
||||
if self.includeid:
|
||||
label = label + " (%s)" % p_id
|
||||
if self.includedates:
|
||||
birth, death = self.get_date_strings(person)
|
||||
label = label + '\\n(%s - %s)' % (birth, death)
|
||||
return label.replace('"', '\\\"')
|
||||
|
||||
def dump_event(self,event):
|
||||
def get_date_strings(self, person):
|
||||
"returns tuple of birth/christening and death/burying date strings"
|
||||
birth_handle = person.get_birth_handle()
|
||||
if birth_handle:
|
||||
birth_event = self.database.get_event_from_handle(birth_handle)
|
||||
birth = self.get_event_string(birth_event)
|
||||
else:
|
||||
birth = ''
|
||||
death_handle = person.get_death_handle()
|
||||
if death_handle:
|
||||
death_event = self.database.get_event_from_handle(death_handle)
|
||||
death = self.get_event_string(death_event)
|
||||
else:
|
||||
death = ''
|
||||
if birth and death:
|
||||
return (birth, death)
|
||||
# missing info, use (first) christening/burial instead
|
||||
for event_handle in person.get_event_list():
|
||||
event = self.database.get_event_from_handle(event_handle)
|
||||
if event.get_name() == "Christening":
|
||||
if not birth:
|
||||
birth = self.get_event_string(event)
|
||||
elif event.get_name() == "Burial":
|
||||
if not death:
|
||||
death = self.get_event_string(event)
|
||||
return (birth, death)
|
||||
|
||||
def get_event_string(self, event):
|
||||
"""
|
||||
Compile an event label.
|
||||
return string for for an event label.
|
||||
|
||||
Based on the data availability and preferences, we select one
|
||||
of the following for a given event:
|
||||
@@ -385,33 +531,6 @@ class GraphViz:
|
||||
return event.get_cause()
|
||||
return ''
|
||||
|
||||
def write_header(self):
|
||||
"""
|
||||
Write header listing the options used.
|
||||
"""
|
||||
self.f.write("/* GRAMPS - Relationship graph\n")
|
||||
self.f.write(" *\n")
|
||||
self.f.write(" * Report options:\n")
|
||||
self.f.write(" * font style : %s\n" % self.fontname)
|
||||
self.f.write(" * style arrow head : %s\n" % self.arrowheadstyle)
|
||||
self.f.write(" * tail : %s\n" % self.arrowtailstyle)
|
||||
self.f.write(" * graph direction : %s\n" % self.rankdir)
|
||||
self.f.write(" * include URLs : %s\n" % bool(self.includeurl))
|
||||
self.f.write(" * IDs : %s\n" % bool(self.includeid))
|
||||
self.f.write(" * dates : %s\n" % bool(self.includedates))
|
||||
self.f.write(" * just year : %s\n" % bool(self.just_years))
|
||||
self.f.write(" * place or cause : %s\n" % bool(self.placecause))
|
||||
self.f.write(" * colorize : %s\n" % bool(self.colorize))
|
||||
self.f.write(" * dotted adoptions : %s\n" % bool(self.adoptionsdashed))
|
||||
self.f.write(" * show family nodes : %s\n" % bool(self.show_families))
|
||||
self.f.write(" * margin : %3.2fin\n" % self.margin_small)
|
||||
self.f.write(" * pages horizontal : %s\n" % self.hpages)
|
||||
self.f.write(" * vertical : %s\n" % self.vpages)
|
||||
self.f.write(" * page width : %3.2fin\n" % self.width)
|
||||
self.f.write(" * height : %3.2fin\n" % self.height)
|
||||
self.f.write(" *\n")
|
||||
self.f.write(" * Generated on %s by GRAMPS\n" % asctime())
|
||||
self.f.write(" */\n\n")
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -439,12 +558,17 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
'justyears' : 0,
|
||||
'placecause' : 1,
|
||||
'url' : 1,
|
||||
'ratio' : "compress",
|
||||
'attract' : "none",
|
||||
'rankdir' : "LR",
|
||||
'color' : "filled",
|
||||
'dashedl' : 1,
|
||||
'margin' : 1.0,
|
||||
'pagedir' : 'BL',
|
||||
'pagesh' : 1,
|
||||
'pagesv' : 1,
|
||||
'note' : '',
|
||||
'noteloc' : 'b',
|
||||
'gvof' : 'ps',
|
||||
}
|
||||
|
||||
@@ -476,7 +600,13 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
'url' : ("=0/1","Whether to include URLs.",
|
||||
["Do not include URLs","Include URLs"],
|
||||
True),
|
||||
'rankdir' : ("=str","Graph direction.",
|
||||
'ratio' : ("=str","Graph aspect ratio.",
|
||||
[ "%s\t%s" % (item[0],item[1]) for item in _options.ratio ],
|
||||
False),
|
||||
'attract' : ("=str","What to group closer.",
|
||||
[ "%s\t%s" % (item[0],item[1]) for item in _options.attract ],
|
||||
False),
|
||||
'rankdir' : ("=str","Graph direction.",
|
||||
[ "%s\t%s" % (item[0],item[1]) for item in _options.rankdir ],
|
||||
False),
|
||||
'color' : ("=str","Whether and how to colorize graph.",
|
||||
@@ -487,10 +617,18 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
True),
|
||||
'margin' : ("=num","Margin size.",
|
||||
"Floating point value, in cm"),
|
||||
'pagedir' : ("=str","Paging direction.",
|
||||
[ "%s\t%s" % (item[0],item[1]) for item in _options.pagedir ],
|
||||
False),
|
||||
'pagesh' : ("=num","Number of pages in horizontal direction.",
|
||||
"Integer values"),
|
||||
'pagesv' : ("=num","Number of pages in vertical direction.",
|
||||
"Integer values"),
|
||||
'note' : ("=str","Note to add to the graph.",
|
||||
"Text"),
|
||||
'noteloc' : ("=str","Note location.",
|
||||
[ "%s\t%s" % (item[0],item[1]) for item in _options.noteloc ],
|
||||
False),
|
||||
'gvof' : ("=str","Output format to convert dot file into.",
|
||||
[ "%s\t%s" % (item[0],item[1]) for item in _options.formats ],
|
||||
False),
|
||||
@@ -532,6 +670,22 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
def make_doc_menu(self,dialog,active=None):
|
||||
pass
|
||||
|
||||
def add_list(self, options, default):
|
||||
"returns compobox of given options and default value"
|
||||
box = gtk.ComboBox()
|
||||
store = gtk.ListStore(str)
|
||||
box.set_model(store)
|
||||
cell = gtk.CellRendererText()
|
||||
box.pack_start(cell,True)
|
||||
box.add_attribute(cell,'text',0)
|
||||
index = 0
|
||||
for item in options:
|
||||
store.append(row=[item[2]])
|
||||
if item[0] == default:
|
||||
box.set_active(index)
|
||||
index = index + 1
|
||||
return box
|
||||
|
||||
def add_user_options(self,dialog):
|
||||
if self.handler.module_name == "rel_graph2":
|
||||
dialog.make_doc_menu = self.make_doc_menu
|
||||
@@ -585,36 +739,16 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
_("Include individual and family IDs."))
|
||||
|
||||
# GraphViz output options tab
|
||||
self.rank_box = gtk.ComboBox()
|
||||
store = gtk.ListStore(str)
|
||||
self.rank_box.set_model(store)
|
||||
cell = gtk.CellRendererText()
|
||||
self.rank_box.pack_start(cell,True)
|
||||
self.rank_box.add_attribute(cell,'text',0)
|
||||
index = 0
|
||||
for item in _options.rankdir:
|
||||
store.append(row=[item[2]])
|
||||
if item[0] == self.options_dict['rankdir']:
|
||||
self.rank_box.set_active(index)
|
||||
index = index + 1
|
||||
self.rank_box = self.add_list(_options.rankdir,
|
||||
self.options_dict['rankdir'])
|
||||
dialog.add_frame_option(_("GraphViz Options"),
|
||||
_("Graph direction"),
|
||||
self.rank_box,
|
||||
_("Whether generations go from top to bottom "
|
||||
"or left to right."))
|
||||
|
||||
self.color_box = gtk.ComboBox()
|
||||
store = gtk.ListStore(str)
|
||||
self.color_box.set_model(store)
|
||||
cell = gtk.CellRendererText()
|
||||
self.color_box.pack_start(cell,True)
|
||||
self.color_box.add_attribute(cell,'text',0)
|
||||
index = 0
|
||||
for item in _options.colors:
|
||||
store.append(row=[item[2]])
|
||||
if item[0] == self.options_dict['color']:
|
||||
self.color_box.set_active(index)
|
||||
index = index + 1
|
||||
self.color_box = self.add_list(_options.colors,
|
||||
self.options_dict['color'])
|
||||
dialog.add_frame_option(_("GraphViz Options"),
|
||||
_("Graph coloring"),
|
||||
self.color_box,
|
||||
@@ -622,39 +756,15 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
"with red. If the sex of an individual "
|
||||
"is unknown it will be shown with gray."))
|
||||
|
||||
self.arrowstyle_box = gtk.ComboBox()
|
||||
store = gtk.ListStore(str)
|
||||
self.arrowstyle_box.set_model(store)
|
||||
cell = gtk.CellRendererText()
|
||||
self.arrowstyle_box.pack_start(cell,True)
|
||||
self.arrowstyle_box.add_attribute(cell,'text',0)
|
||||
index = 0
|
||||
for item in _options.arrowstyles:
|
||||
store.append(row=[item[2]])
|
||||
if item[0] == self.options_dict['arrow']:
|
||||
self.arrowstyle_box.set_active(index)
|
||||
index = index + 1
|
||||
self.arrowstyle_box = self.add_list(_options.arrowstyles,
|
||||
self.options_dict['arrow'])
|
||||
dialog.add_frame_option(_("GraphViz Options"),
|
||||
_("Arrowhead direction"),
|
||||
self.arrowstyle_box,
|
||||
_("Choose the direction that the arrows point."))
|
||||
|
||||
self.font_box = gtk.ComboBox()
|
||||
store = gtk.ListStore(str)
|
||||
self.font_box.set_model(store)
|
||||
cell = gtk.CellRendererText()
|
||||
self.font_box.pack_start(cell,True)
|
||||
self.font_box.add_attribute(cell,'text',0)
|
||||
index = 0
|
||||
for item in _options.fonts:
|
||||
if item[3]:
|
||||
name = "%s (iso-latin1 font)" % item[2]
|
||||
else:
|
||||
name = item[2]
|
||||
store.append(row=[name])
|
||||
if item[0] == self.options_dict['font']:
|
||||
self.font_box.set_active(index)
|
||||
index = index + 1
|
||||
self.font_box = self.add_list(_options.fonts,
|
||||
self.options_dict['font'])
|
||||
dialog.add_frame_option(_("GraphViz Options"),
|
||||
_("Font family"),
|
||||
self.font_box,
|
||||
@@ -663,6 +773,13 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
"FreeSans is available from: "
|
||||
"http://www.nongnu.org/freefont/"))
|
||||
|
||||
self.latin_cb = gtk.CheckButton(_("Output format/font requires text as latin-1"))
|
||||
self.latin_cb.set_active(self.options_dict['latin'])
|
||||
dialog.add_frame_option(_("GraphViz Options"), '',
|
||||
self.latin_cb,
|
||||
_("If text doesn't show correctly in report, use this. "
|
||||
"Required e.g. for default font with PS output."))
|
||||
|
||||
self.adoptionsdashed_cb = gtk.CheckButton(_("Indicate non-birth relationships with dotted lines"))
|
||||
self.adoptionsdashed_cb.set_active(self.options_dict['dashedl'])
|
||||
dialog.add_frame_option(_("GraphViz Options"), '',
|
||||
@@ -677,13 +794,31 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
_("Families will show up as ellipses, linked "
|
||||
"to parents and children."))
|
||||
|
||||
# Page options tab
|
||||
# Page/layout options tab
|
||||
self.attract_box = self.add_list(_options.attract,
|
||||
self.options_dict['attract'])
|
||||
dialog.add_frame_option(_("Layout Options"),
|
||||
_("What to group closer together"),
|
||||
self.attract_box,
|
||||
_("Whether to group parents or children "
|
||||
"together or whether both have same "
|
||||
"weights."))
|
||||
|
||||
self.ratio_box = self.add_list(_options.ratio,
|
||||
self.options_dict['ratio'])
|
||||
dialog.add_frame_option(_("Layout Options"),
|
||||
_("Aspect ratio"),
|
||||
self.ratio_box,
|
||||
_("Affects greatly how the graph is layed out "
|
||||
"on the page. Multiple pages overrides the "
|
||||
"pages settings below."))
|
||||
|
||||
margin_adj = gtk.Adjustment(value=self.options_dict['margin'],
|
||||
lower=0.0, upper=10.0, step_incr=1.0)
|
||||
|
||||
self.margin_sb = gtk.SpinButton(adjustment=margin_adj, digits=1)
|
||||
|
||||
dialog.add_frame_option(_("Page Options"),
|
||||
dialog.add_frame_option(_("Layout Options"),
|
||||
_("Margin size"),
|
||||
self.margin_sb)
|
||||
|
||||
@@ -695,14 +830,14 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
self.hpages_sb = gtk.SpinButton(adjustment=hpages_adj, digits=0)
|
||||
self.vpages_sb = gtk.SpinButton(adjustment=vpages_adj, digits=0)
|
||||
|
||||
dialog.add_frame_option(_("Page Options"),
|
||||
dialog.add_frame_option(_("Layout Options"),
|
||||
_("Number of Horizontal Pages"),
|
||||
self.hpages_sb,
|
||||
_("GraphViz can create very large graphs by "
|
||||
"spreading the graph across a rectangular "
|
||||
"array of pages. This controls the number "
|
||||
"pages in the array horizontally."))
|
||||
dialog.add_frame_option(_("Page Options"),
|
||||
dialog.add_frame_option(_("Layout Options"),
|
||||
_("Number of Vertical Pages"),
|
||||
self.vpages_sb,
|
||||
_("GraphViz can create very large graphs "
|
||||
@@ -710,6 +845,32 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
"rectangular array of pages. This "
|
||||
"controls the number pages in the array "
|
||||
"vertically."))
|
||||
self.pagedir_box = self.add_list(_options.pagedir,
|
||||
self.options_dict['pagedir'])
|
||||
dialog.add_frame_option(_("Layout Options"),
|
||||
_("Paging direction"),
|
||||
self.pagedir_box,
|
||||
_("The order in which the graph pages are output."))
|
||||
|
||||
# Notes tab
|
||||
self.textbox = gtk.TextView()
|
||||
self.textbox.get_buffer().set_text(self.options_dict['note'])
|
||||
self.textbox.set_editable(1)
|
||||
swin = gtk.ScrolledWindow()
|
||||
swin.set_shadow_type(gtk.SHADOW_IN)
|
||||
swin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
|
||||
swin.add(self.textbox)
|
||||
dialog.add_frame_option(_("Notes"),
|
||||
_("Note to add to the graph"),
|
||||
swin,
|
||||
_("This text will be added to the graph."))
|
||||
self.noteloc_box = self.add_list(_options.noteloc,
|
||||
self.options_dict['noteloc'])
|
||||
dialog.add_frame_option(_("Notes"),
|
||||
_("Note location"),
|
||||
self.noteloc_box,
|
||||
_("Whether note will on top or bottom of the page."))
|
||||
|
||||
|
||||
def toggle_date(self, obj):
|
||||
self.just_years_cb.set_sensitive(self.includedates_cb.get_active())
|
||||
@@ -726,6 +887,10 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
self.options_dict['incid'] = int(self.includeid_cb.get_active())
|
||||
self.options_dict['justyears'] = int(self.just_years_cb.get_active())
|
||||
self.options_dict['placecause'] = int(self.place_cause_cb.get_active())
|
||||
self.options_dict['attract'] = \
|
||||
_options.attract[self.attract_box.get_active()][0]
|
||||
self.options_dict['ratio'] = \
|
||||
_options.ratio[self.ratio_box.get_active()][0]
|
||||
self.options_dict['rankdir'] = \
|
||||
_options.rankdir[self.rank_box.get_active()][0]
|
||||
self.options_dict['color'] = \
|
||||
@@ -734,8 +899,14 @@ class GraphVizOptions(ReportOptions.ReportOptions):
|
||||
_options.arrowstyles[self.arrowstyle_box.get_active()][0]
|
||||
self.options_dict['font'] = \
|
||||
_options.fonts[self.font_box.get_active()][0]
|
||||
self.options_dict['latin'] = \
|
||||
_options.fonts[self.font_box.get_active()][3]
|
||||
self.options_dict['pagedir'] = \
|
||||
_options.pagedir[self.pagedir_box.get_active()][0]
|
||||
self.options_dict['noteloc'] = \
|
||||
_options.noteloc[self.noteloc_box.get_active()][0]
|
||||
b = self.textbox.get_buffer()
|
||||
self.options_dict['note'] = \
|
||||
b.get_text(b.get_start_iter(), b.get_end_iter(), False)
|
||||
|
||||
if self.handler.module_name == "rel_graph2":
|
||||
self.options_dict['gvof'] = dialog.format_menu.get_format_str()
|
||||
|
||||
|
||||
@@ -113,7 +113,10 @@ class GeneWebParser:
|
||||
self.lineno += 1
|
||||
line = self.f.readline()
|
||||
if line:
|
||||
line = unicode( line.strip())
|
||||
try:
|
||||
line = unicode(line.strip())
|
||||
except UnicodeDecodeError:
|
||||
line = unicode(line.strip(),'iso-8859-1')
|
||||
else:
|
||||
line = None
|
||||
return line
|
||||
@@ -260,8 +263,6 @@ class GeneWebParser:
|
||||
else:
|
||||
(idx,child) = self.parse_person(fields,1,RelLib.Person.UNKNOWN,father_surname)
|
||||
|
||||
print child.get_gender(),":",fields[1], child.get_primary_name().get_name()
|
||||
|
||||
if child:
|
||||
self.current_family.add_child_handle(child.get_handle())
|
||||
self.db.commit_family(self.current_family,self.trans)
|
||||
@@ -304,7 +305,7 @@ class GeneWebParser:
|
||||
def read_notes_lines(self,line,fields):
|
||||
(idx,person) = self.parse_person(fields,1,None,None)
|
||||
note_txt = ""
|
||||
while 1:
|
||||
while True:
|
||||
line = self.get_next_line()
|
||||
if line == None:
|
||||
break
|
||||
@@ -404,16 +405,18 @@ class GeneWebParser:
|
||||
if not father_surname:
|
||||
if not idx < len(fields):
|
||||
print "Missing surname of person in line %d!" % self.lineno
|
||||
return (idx,None)
|
||||
surname = self.decode(fields[idx])
|
||||
surname =""
|
||||
else:
|
||||
surname = self.decode(fields[idx])
|
||||
idx = idx + 1
|
||||
else:
|
||||
surname = father_surname
|
||||
|
||||
if not idx < len(fields):
|
||||
print "Missing firstname of person in line %d!" % self.lineno
|
||||
return (idx,None)
|
||||
firstname = self.decode(fields[idx])
|
||||
firstname = ""
|
||||
else:
|
||||
firstname = self.decode(fields[idx])
|
||||
idx = idx + 1
|
||||
if idx < len(fields) and father_surname:
|
||||
noSurnameRe = re.compile("^[({\[~><?0-9#].*$")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2003-2005 Donald N. Allingham
|
||||
# Copyright (C) 2003-2006 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
|
||||
@@ -31,6 +31,7 @@ Show uncollected objects in a window.
|
||||
#------------------------------------------------------------------------
|
||||
import os
|
||||
from gettext import gettext as _
|
||||
from bsddb.db import DBError
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -114,10 +115,15 @@ class Leak(Tool.Tool):
|
||||
mylist = []
|
||||
if len(gc.garbage):
|
||||
for each in gc.garbage:
|
||||
mylist.append(str(each))
|
||||
self.ebuf.set_text(_("Uncollected objects:\n\n") + '\n\n'.join(mylist))
|
||||
try:
|
||||
mylist.append(str(each))
|
||||
except DBError:
|
||||
mylist.append('db.DB instance at %s' % id(each))
|
||||
self.ebuf.set_text(_("Uncollected objects:\n\n")
|
||||
+ '\n\n'.join(mylist))
|
||||
else:
|
||||
self.ebuf.set_text(_("No uncollected objects\n") + str(gc.get_debug()))
|
||||
self.ebuf.set_text(_("No uncollected objects\n")
|
||||
+ str(gc.get_debug()))
|
||||
|
||||
def apply_clicked(self,obj):
|
||||
self.display()
|
||||
|
||||
@@ -11,6 +11,7 @@ pkgdata_PYTHON = \
|
||||
AncestorReport.py\
|
||||
Ancestors.py\
|
||||
BookReport.py\
|
||||
Calendar.py \
|
||||
ChangeTypes.py\
|
||||
ChangeNames.py\
|
||||
Check.py\
|
||||
@@ -96,7 +97,10 @@ GLADEFILES = \
|
||||
GRAPHICS = \
|
||||
stock_link.png
|
||||
|
||||
dist_pkgdata_DATA = $(GLADEFILES) $(GRAPHICS)
|
||||
DATAFILES = \
|
||||
holidays.xml
|
||||
|
||||
dist_pkgdata_DATA = $(GLADEFILES) $(GRAPHICS) $(DATAFILES)
|
||||
|
||||
GRAMPS_PY_MODPATH = "../:../docgen"
|
||||
|
||||
|
||||
@@ -111,12 +111,12 @@ _character_sets = [
|
||||
]
|
||||
|
||||
_cc = [
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nd/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-sa/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by/2.5/"><img alt="Creative Commons License - By attribution" title="Creative Commons License - By attribution" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nd/2.5/"><img alt="Creative Commons License - By attribution, No derivations" title="Creative Commons License - By attribution, No derivations" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-sa/2.5/"><img alt="Creative Commons License - By attribution, Share-alike" title="Creative Commons License - By attribution, Share-alike" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc/2.5/"><img alt="Creative Commons License - By attribution, Non-commercial" title="Creative Commons License - By attribution, Non-commercial" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.5/"><img alt="Creative Commons License - By attribution, Non-commercial, No derivations" title="Creative Commons License - By attribution, Non-commercial, No derivations" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/"><img alt="Creative Commons License - By attribution, Non-commerical, Share-alike" title="Creative Commons License - By attribution, Non-commerical, Share-alike" src="#PATH#images/somerights20.gif" /></a>',
|
||||
]
|
||||
|
||||
|
||||
@@ -1664,6 +1664,14 @@ class IndividualPage(BasePage):
|
||||
|
||||
of.write('</td>\n</tr>\n')
|
||||
|
||||
# Gender
|
||||
|
||||
nick = self.person.get_nick_name()
|
||||
if nick:
|
||||
of.write('<tr><td class="field">%s</td>\n' % _('Nickname'))
|
||||
of.write('<td class="data">%s</td>\n' % nick)
|
||||
of.write('</tr>\n')
|
||||
|
||||
# Gender
|
||||
of.write('<tr><td class="field">%s</td>\n' % _('Gender'))
|
||||
gender = self.gender_map[self.person.gender]
|
||||
@@ -2099,7 +2107,7 @@ class WebReport(Report.Report):
|
||||
|
||||
# Copy the Creative Commons icon if the a Creative Commons
|
||||
# license is requested
|
||||
if 1 < self.copyright < 7:
|
||||
if 0 < self.copyright < 7:
|
||||
from_path = os.path.join(const.dataDir,"somerights20.gif")
|
||||
to_path = os.path.join("images","somerights20.gif")
|
||||
self.store_file(archive,self.target_path,from_path,to_path)
|
||||
@@ -2836,7 +2844,7 @@ def nameof(person,private):
|
||||
if person.private and private:
|
||||
return _("Private")
|
||||
else:
|
||||
return _nd.display(person)
|
||||
return _nd.display_with_nick(person)
|
||||
|
||||
def name_nameof(name,private):
|
||||
if name.private and private:
|
||||
|
||||
@@ -66,8 +66,10 @@ prefix_list = [
|
||||
|
||||
_title_re = re.compile(r"^([A-Za-z][A-Za-z]+\.)\s+(.*)$")
|
||||
_nick_re = re.compile(r"(.+)\s*[(\"](.*)[)\"]")
|
||||
_fn_prefix_re = re.compile("(.*)\s+(%s)\s*$" % '|'.join(prefix_list),re.IGNORECASE)
|
||||
_sn_prefix_re = re.compile("^\s*(%s)\s+(.*)" % '|'.join(prefix_list),re.IGNORECASE)
|
||||
_fn_prefix_re = re.compile("(.*)\s+(%s)\s*$" % '|'.join(prefix_list),
|
||||
re.IGNORECASE)
|
||||
_sn_prefix_re = re.compile("^\s*(%s)\s+(.*)" % '|'.join(prefix_list),
|
||||
re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -111,19 +113,22 @@ class PatchNames(Tool.Tool):
|
||||
first = name.get_first_name()
|
||||
sname = name.get_surname()
|
||||
|
||||
match = _title_re.match(first)
|
||||
if name.get_title():
|
||||
current_title = [name.get_title()]
|
||||
old_title = [name.get_title()]
|
||||
else:
|
||||
current_title = []
|
||||
old_title = []
|
||||
new_title = []
|
||||
|
||||
match = _title_re.match(first)
|
||||
while match:
|
||||
groups = match.groups()
|
||||
first = groups[1]
|
||||
current_title.append(groups[0])
|
||||
new_title.append(groups[0])
|
||||
match = _title_re.match(first)
|
||||
|
||||
if current_title:
|
||||
self.title_list.append((key," ".join(current_title),first))
|
||||
if new_title:
|
||||
self.title_list.append((key," ".join(old_title+new_title),
|
||||
first))
|
||||
continue
|
||||
|
||||
match = _nick_re.match(first)
|
||||
@@ -131,15 +136,24 @@ class PatchNames(Tool.Tool):
|
||||
groups = match.groups()
|
||||
self.nick_list.append((key,groups[0],groups[1]))
|
||||
continue
|
||||
|
||||
old_prefix = name.get_surname_prefix()
|
||||
|
||||
match = _fn_prefix_re.match(first)
|
||||
if match:
|
||||
groups = match.groups()
|
||||
self.prefix1_list.append((key,groups[0],groups[1]))
|
||||
self.prefix1_list.append((key,groups[0],
|
||||
" ".join([groups[1],old_prefix]))
|
||||
)
|
||||
continue
|
||||
|
||||
match = _sn_prefix_re.match(sname)
|
||||
if match:
|
||||
groups = match.groups()
|
||||
self.prefix2_list.append((key,groups[1],groups[0]))
|
||||
self.prefix2_list.append((key,groups[1],
|
||||
" ".join([old_prefix,groups[0]]))
|
||||
)
|
||||
|
||||
self.progress.step()
|
||||
|
||||
if self.nick_list or self.title_list or self.prefix1_list or self.prefix2_list:
|
||||
@@ -217,38 +231,38 @@ class PatchNames(Tool.Tool):
|
||||
self.nick_hash[id] = handle
|
||||
self.progress.step()
|
||||
|
||||
for (id,title,nick) in self.title_list:
|
||||
for (id,title,name) in self.title_list:
|
||||
p = self.db.get_person_from_handle(id)
|
||||
gid = p.get_gramps_id()
|
||||
handle = self.model.append()
|
||||
self.model.set_value(handle,0,1)
|
||||
self.model.set_value(handle,1,gid)
|
||||
self.model.set_value(handle,2,_('Title'))
|
||||
self.model.set_value(handle,3,nick)
|
||||
self.model.set_value(handle,3,title)
|
||||
self.model.set_value(handle,4,p.get_primary_name().get_name())
|
||||
self.title_hash[id] = handle
|
||||
self.progress.step()
|
||||
|
||||
for (id,prefix,fname) in self.prefix1_list:
|
||||
for (id,fname,prefix) in self.prefix1_list:
|
||||
p = self.db.get_person_from_handle(id)
|
||||
gid = p.get_gramps_id()
|
||||
handle = self.model.append()
|
||||
self.model.set_value(handle,0,1)
|
||||
self.model.set_value(handle,1,gid)
|
||||
self.model.set_value(handle,2,_('Prefix'))
|
||||
self.model.set_value(handle,3,fname)
|
||||
self.model.set_value(handle,3,prefix)
|
||||
self.model.set_value(handle,4,p.get_primary_name().get_name())
|
||||
self.prefix1_hash[id] = handle
|
||||
self.progress.step()
|
||||
|
||||
for (id,prefix,fname) in self.prefix2_list:
|
||||
for (id,sname,prefix) in self.prefix2_list:
|
||||
p = self.db.get_person_from_handle(id)
|
||||
gid = p.get_gramps_id()
|
||||
handle = self.model.append()
|
||||
self.model.set_value(handle,0,1)
|
||||
self.model.set_value(handle,1,gid)
|
||||
self.model.set_value(handle,2,_('Prefix'))
|
||||
self.model.set_value(handle,3,fname)
|
||||
self.model.set_value(handle,3,prefix)
|
||||
self.model.set_value(handle,4,p.get_primary_name().get_name())
|
||||
self.prefix2_hash[id] = handle
|
||||
self.progress.step()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -55,44 +55,51 @@ import TarFile
|
||||
#-------------------------------------------------------------------------
|
||||
def impData(database, name,cb=None,cl=0):
|
||||
# Create tempdir, if it does not exist, then check for writability
|
||||
tmpdir_path = os.path.expanduser("~/.gramps/tmp" )
|
||||
# THE TEMP DIR is named as the filname.gpkg.media and is created
|
||||
# in the same dir as the database that we are importing into.
|
||||
db_path = os.path.dirname(database.get_save_path())
|
||||
media_dir = "%s.media" % os.path.basename(name)
|
||||
tmpdir_path = os.path.join(db_path,media_dir)
|
||||
if not os.path.isdir(tmpdir_path):
|
||||
try:
|
||||
os.mkdir(tmpdir_path,0700)
|
||||
except:
|
||||
ErrorDialog( _("Could not create temporary directory %s") %
|
||||
tmpdir_path )
|
||||
tmpdir_path )
|
||||
return
|
||||
elif not os.access(tmpdir_path,os.W_OK):
|
||||
ErrorDialog( _("Temporary directory %s is not writable") % tmpdir_path )
|
||||
ErrorDialog(_("Temporary directory %s is not writable") % tmpdir_path)
|
||||
return
|
||||
else: # tempdir exists and writable -- clean it up if not empty
|
||||
files = os.listdir(tmpdir_path) ;
|
||||
for filename in files:
|
||||
os.remove( os.path.join(tmpdir_path,filename) )
|
||||
os.remove(os.path.join(tmpdir_path,filename))
|
||||
|
||||
try:
|
||||
t = TarFile.ReadTarFile(name,tmpdir_path)
|
||||
t.extract()
|
||||
t.close()
|
||||
except:
|
||||
ErrorDialog(_("Error extracting into %s") % tmpdir_path )
|
||||
ErrorDialog(_("Error extracting into %s") % tmpdir_path)
|
||||
return
|
||||
|
||||
dbname = os.path.join(tmpdir_path,const.xmlFile)
|
||||
imp_db_name = os.path.join(tmpdir_path,const.xmlFile)
|
||||
|
||||
try:
|
||||
ReadXML.importData(database,dbname,cb)
|
||||
ReadXML.importData(database,imp_db_name,cb)
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
|
||||
# Clean up tempdir after ourselves
|
||||
files = os.listdir(tmpdir_path)
|
||||
for filename in files:
|
||||
os.remove(os.path.join(tmpdir_path,filename))
|
||||
# THIS HAS BEEN CHANGED, because now we want to keep images
|
||||
# stay after the import is over. Just delete the XML file.
|
||||
os.remove(imp_db_name)
|
||||
|
||||
os.rmdir(tmpdir_path)
|
||||
## files = os.listdir(tmpdir_path)
|
||||
## for filename in files:
|
||||
## os.remove(os.path.join(tmpdir_path,filename))
|
||||
## os.rmdir(tmpdir_path)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 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
|
||||
@@ -65,16 +65,13 @@ class Rebuild(Tool.Tool):
|
||||
# checking of a read only database
|
||||
return
|
||||
|
||||
total = db.get_number_of_people() + \
|
||||
db.get_number_of_families() + \
|
||||
db.get_number_of_places() + \
|
||||
db.get_number_of_sources() + \
|
||||
db.get_number_of_media_objects()
|
||||
|
||||
db.disable_signals()
|
||||
if parent:
|
||||
progress = Utils.ProgressMeter(
|
||||
_('Rebuilding Secondary Indices'))
|
||||
# Six indices to rebuild, and the first step is removing
|
||||
# old ones
|
||||
total = 7
|
||||
progress.set_pass('',total)
|
||||
db.rebuild_secondary(progress.step)
|
||||
progress.close()
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<calendar>
|
||||
<country name="US">
|
||||
<date name="New Year's Day" value="*/1/1" type="national" />
|
||||
<date name="Independence Day" value="*/7/4" type="national" />
|
||||
<date name="Veterans Day" value="*/11/11" type="national" />
|
||||
<date name="Christmas" value="*/12/25" type="national" />
|
||||
<date name="Labor Day" value="*/1/mon/sep" type="national" />
|
||||
<date name="Thanksgiving" value="*/4/thu/nov" type="national" />
|
||||
<date name="Inauguration Day" value="*/1/20" if="(y - 1980) % 4 == 0" type="national" />
|
||||
<date name="Groundhog Day" value="*/2/2" type="secular" />
|
||||
<date name="Lincoln's Birthday" value="*/2/12" type="secular" />
|
||||
<date name="Valentine's Day" value="*/2/14" type="secular" />
|
||||
<date name="Presidents' Day" value="*/3/mon/feb" type="secular" />
|
||||
<date name="Washington's Birthday" value="*/2/22" type="secular" />
|
||||
<date name="St. Patrick's Day" value="*/3/17" type="secular" />
|
||||
<date name="April Fools's Day" value="*/4/1" type="secular" />
|
||||
<date name="Earth Day" value="*/4/22" type="secular" />
|
||||
<date name="Assistants' Day" value="*/-1/sat/apr" offset="-3" type="secular" />
|
||||
<date name="Arbor Day" value="*/-1/fri/apr" type="secular" />
|
||||
<date name="Mothers' Day" value="*/2/sun/may" type="secular" />
|
||||
<date name="Fathers' Day" value="*/3/sun/jun" type="secular" />
|
||||
<date name="Parents' Day" value="*/4/sun/jul" type="secular" />
|
||||
<date name="Grandparents' Day" value="*/1/mon/sep" offset="6" type="secular" />
|
||||
<date name="Columbus Day" value="*/2/mon/oct" type="secular" />
|
||||
<date name="United Nations Day" value="*/10/24" type="secular" />
|
||||
<date name="Halloween" value="*/10/31" type="secular" />
|
||||
<date name="ML Kings's Birthday" value="*/3/mon/jan" type="secular" />
|
||||
<date name="Armed Forces Day" value="*/3/sat/may" type="secular" />
|
||||
<date name="Memorial Day" value="*/-1/mon/may" type="secular" />
|
||||
<date name="Flag Day" value="*/6/14" type="secular" />
|
||||
<date name="Election Day" value="*/11/2" offset="tue" type="secular" />
|
||||
<date name="Daylight Savings begins" value="*/1/sun/apr" type="informational" />
|
||||
<date name="Income Taxes due" value="*/4/15" type="national"
|
||||
if="date.weekday().__cmp__(4)-1" />
|
||||
<date name="Income Taxes due" value="*/4/16" type="national"
|
||||
if="date.weekday() == 0" />
|
||||
<date name="Income Taxes due" value="*/4/17" type="national"
|
||||
if="date.weekday() == 0" />
|
||||
<date name="Daylight Savings ends" value="*/-1/sun/oct" type="informational" />
|
||||
<date name="Easter" type="religious" value="1980/4/6" />
|
||||
<date name="Easter" type="religious" value="1981/4/19" />
|
||||
<date name="Easter" type="religious" value="1982/4/11" />
|
||||
<date name="Easter" type="religious" value="1983/4/3" />
|
||||
<date name="Easter" type="religious" value="1984/4/22" />
|
||||
<date name="Easter" type="religious" value="1985/4/7" />
|
||||
<date name="Easter" type="religious" value="1986/3/30" />
|
||||
<date name="Easter" type="religious" value="1987/4/19" />
|
||||
<date name="Easter" type="religious" value="1988/4/3" />
|
||||
<date name="Easter" type="religious" value="1989/3/26" />
|
||||
<date name="Easter" type="religious" value="1990/4/15" />
|
||||
<date name="Easter" type="religious" value="1991/3/31" />
|
||||
<date name="Easter" type="religious" value="1992/4/19" />
|
||||
<date name="Easter" type="religious" value="1993/4/11" />
|
||||
<date name="Easter" type="religious" value="1994/4/3" />
|
||||
<date name="Easter" type="religious" value="1995/4/16" />
|
||||
<date name="Easter" type="religious" value="1996/4/7" />
|
||||
<date name="Easter" type="religious" value="1997/3/30" />
|
||||
<date name="Easter" type="religious" value="1998/4/12" />
|
||||
<date name="Easter" type="religious" value="1999/4/4" />
|
||||
<date name="Easter" type="religious" value="2000/4/23" />
|
||||
<date name="Easter" type="religious" value="2001/4/15" />
|
||||
<date name="Easter" type="religious" value="2002/3/31" />
|
||||
<date name="Easter" type="religious" value="2003/4/20" />
|
||||
<date name="Easter" type="religious" value="2004/4/11" />
|
||||
<date name="Easter" type="religious" value="2005/3/27" />
|
||||
<date name="Easter" type="religious" value="2006/4/16" />
|
||||
<date name="Easter" type="religious" value="2007/4/8" />
|
||||
<date name="Easter" type="religious" value="2008/3/23" />
|
||||
<date name="Easter" type="religious" value="2009/4/12" />
|
||||
<date name="Easter" type="religious" value="2010/4/4" />
|
||||
<date name="Easter" type="religious" value="2011/4/24" />
|
||||
<date name="Easter" type="religious" value="2012/4/8" />
|
||||
<date name="Easter" type="religious" value="2013/3/31" />
|
||||
<date name="Easter" type="religious" value="2014/4/20" />
|
||||
<date name="Easter" type="religious" value="2015/4/5" />
|
||||
<date name="Easter" type="religious" value="2016/3/27" />
|
||||
<date name="Easter" type="religious" value="2017/4/16" />
|
||||
<date name="Easter" type="religious" value="2018/4/1" />
|
||||
<date name="Easter" type="religious" value="2019/4/21" />
|
||||
<date name="Easter" type="religious" value="2020/4/12" />
|
||||
<date name="Easter" type="religious" value="2021/4/4" />
|
||||
<date name="Easter" type="religious" value="2022/4/17" />
|
||||
<date name="Easter" type="religious" value="2023/4/9" />
|
||||
<date name="Easter" type="religious" value="2024/3/31" />
|
||||
<date name="Passover" value="2005/4/24" type="religious" />
|
||||
<date name="Passover" value="2006/4/13" type="religious" />
|
||||
<date name="Passover" value="2007/4/03" type="religious" />
|
||||
<date name="Passover" value="2008/4/20" type="religious" />
|
||||
<date name="Passover" value="2009/4/09" type="religious" />
|
||||
<date name="Passover" value="2010/3/30" type="religious" />
|
||||
<date name="Passover" value="2011/4/19" type="religious" />
|
||||
<date name="Yom Kippur" value="2005/10/13" type="religious" />
|
||||
<date name="Yom Kippur" value="2006/10/02" type="religious" />
|
||||
<date name="Yom Kippur" value="2007/9/27" type="religious" />
|
||||
<date name="Yom Kippur" value="2008/10/09" type="religious" />
|
||||
<date name="Yom Kippur" value="2009/9/28" type="religious" />
|
||||
<date name="Yom Kippur" value="2010/9/18" type="religious" />
|
||||
<date name="Hanukkah begins" value="2004/10/07" type="religious" />
|
||||
<date name="Hanukkah begins" value="2005/10/26" type="religious" />
|
||||
<date name="Hanukkah begins" value="2006/10/15" type="religious" />
|
||||
<date name="Hanukkah begins" value="2007/10/05" type="religious" />
|
||||
<date name="Hanukkah begins" value="2008/10/22" type="religious" />
|
||||
<date name="Hanukkah begins" value="2009/10/12" type="religious" />
|
||||
<date name="Hanukkah begins" value="2010/10/22" type="religious" />
|
||||
<date name="Ramadan begins" value="2006/9/24" type="religious" />
|
||||
<date name="Ramadan begins" value="2007/9/13" type="religious" />
|
||||
<date name="Ramadan begins" value="2008/9/2" type="religious" />
|
||||
<date name="Kwanzaa begins" value="*/12/26" type="religious" />
|
||||
<date name="Cinco de Mayo" value="*/5/5" type="secular" />
|
||||
</country>
|
||||
<country name="CN">
|
||||
<date name="Chinese New Year" value="2006/1/29" type="national" />
|
||||
</country>
|
||||
<country name="FI">
|
||||
<date name="Chinese New Year" value="2006/1/29" type="national" />
|
||||
<date name="Card Night" value="*/-1/thu/*" type="personal" />
|
||||
</country>
|
||||
</calendar>
|
||||
@@ -20,7 +20,4 @@ uninstall-local:
|
||||
SUFFIXES = .po .mo
|
||||
|
||||
.po.mo:
|
||||
$(MSGCONV) --to-code=UTF-8 $< -o temp.po
|
||||
$(MSGFMT) temp.po -o $@
|
||||
rm temp.po
|
||||
|
||||
$(MSGCONV) --to-code=UTF-8 $< | $(MSGFMT) - -o $@
|
||||
|
||||
+1461
-1254
File diff suppressed because it is too large
Load Diff
+1246
-1366
File diff suppressed because it is too large
Load Diff
+1587
-1396
File diff suppressed because it is too large
Load Diff
+6609
-4583
File diff suppressed because it is too large
Load Diff
+4369
-2999
File diff suppressed because it is too large
Load Diff
+5613
-4768
File diff suppressed because it is too large
Load Diff
+4369
-2999
File diff suppressed because it is too large
Load Diff
+9979
-5704
File diff suppressed because it is too large
Load Diff
+1675
-1373
File diff suppressed because it is too large
Load Diff
+1998
-1942
File diff suppressed because it is too large
Load Diff
+1459
-1272
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@ OPTS="-i $EXAMPLE_XML"
|
||||
GRPH_FMT="sxw ps pdf svg"
|
||||
TEXT_FMT="sxw pdf kwd abw rtf txt html tex"
|
||||
|
||||
GRPH_REP="ancestor_chart2 descend_chart2 fan_chart statistics_chart timeline"
|
||||
GRPH_REP="ancestor_chart2 descend_chart2 fan_chart statistics_chart timeline calendar"
|
||||
TEXT_REP="ancestor_report ancestors_report descend_report det_ancestor_report det_descendant_report family_group"
|
||||
|
||||
# Single run with all graphical reports in all formats
|
||||
|
||||
Reference in New Issue
Block a user