Compare commits

..

117 Commits

Author SHA1 Message Date
Richard Taylor 20bac63011 SVN reorganisation: Move current maintenance branches
svn: r12907
2009-08-07 08:11:43 +00:00
Eero Tamminen 2bf08ece8f Major updates to GraphViz plugin.
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


svn: r6010
2006-02-27 22:02:27 +00:00
Alex Roitman 9209f7eca9 * configure.in: Bump up version number.
svn: r6009
2006-02-27 18:51:38 +00:00
Alex Roitman d01c7bcfe5 * configure.in: Bump up release number.
* Release: Version 2.0.10 "Holy Hand Grenade of Antioch" released.


svn: r6007
2006-02-27 17:43:51 +00:00
Alex Roitman 80bc471b59 Update
svn: r6006
2006-02-27 16:24:11 +00:00
Martin Hawlisch 766bcc6060 translation update
svn: r6005
2006-02-27 14:25:19 +00:00
Julio Sánchez 267905f17d * src/po/es.po: Translation update
svn: r6004
2006-02-27 13:59:23 +00:00
Jérôme Rapinat dd917aa4c5 * src/po/fr.po update translation
svn: r6003
2006-02-27 07:57:05 +00:00
Alex Roitman 8bae700b80 * src/po/template.po: Update.
* src/po/template.po: Update.


svn: r6002
2006-02-27 06:19:25 +00:00
Doug Blank e697e7de4c Added (my first) Calendar.py edits
svn: r6001
2006-02-27 05:17:50 +00:00
Doug Blank 638fcd1b09 1) Fixed bug in primary family selection
2) Fixed reversed meaning in maiden name checkbox
3) Added translation gettext around "name and name" because "and" is english


svn: r6000
2006-02-27 05:12:37 +00:00
Don Allingham bf25a9582b * src/EditPerson.py: strip names of trailing whitespace before
assigning them


svn: r5999
2006-02-27 03:29:31 +00:00
Don Allingham 94056f3602 * src/plugins/ImportGeneWeb.py: handle people with no firstname
or lastname, if encoding fails, attempt and iso-8859-1 conversion


svn: r5998
2006-02-26 23:52:43 +00:00
Alex Roitman 0043572c35 * gramps.sh.in: Update copyright year.
svn: r5996
2006-02-26 18:13:03 +00:00
Alex Roitman 877faeb4c4 * src/po/Makefile.am (.po.mo): Avoid using temp file as it breaks
distcheck -- use pipe instead.


svn: r5995
2006-02-26 18:07:44 +00:00
Alex Roitman 264d06b2a9 * src/plugins/Calendar.py (Widget.register): Do not add help
strings to style widgets.


svn: r5994
2006-02-26 16:44:48 +00:00
Alex Roitman 622c870879 * NEWS: Update.
svn: r5992
2006-02-25 07:08:05 +00:00
Alex Roitman 754cd97f3c * configure.in: Bump up the release number.
svn: r5991
2006-02-25 06:45:38 +00:00
Alex Roitman ed287a85d3 * test/runtest.sh (GRPH_REP): Add calendar to the list of reports.
svn: r5990
2006-02-25 06:42:07 +00:00
Marcos Bedinelli 29a5a1397d Brazilian-Portuguese translation for GRAMPS 2.0.10
svn: r5988
2006-02-25 00:15:56 +00:00
Martin Hawlisch a19bd16975 updated translation
svn: r5986
2006-02-24 21:54:07 +00:00
Alex Roitman 082b2a7b88 * src/plugins/Calendar.py: Remove the unsupported flag.
svn: r5985
2006-02-24 20:56:24 +00:00
Alex Roitman ea72d0db93 * src/po/pt_BR.po: Update.
svn: r5982
2006-02-24 17:58:15 +00:00
Jérôme Rapinat 221a880136 * src/po/fr.po update translation
svn: r5981
2006-02-24 15:03:17 +00:00
Alex Roitman cc7027ca56 * src/plugins/Calendar.py: Remove translation from help strings;
do not import unused modules.
* src/po/template.po: Update.


svn: r5978
2006-02-23 19:23:29 +00:00
Jérôme Rapinat d6dce0ecff * src/po/fr.po update translation (2.0.10)
svn: r5977
2006-02-23 11:09:21 +00:00
Alex Roitman 8dc650bd01 Update
svn: r5974
2006-02-23 01:13:40 +00:00
Alex Roitman 4e5c3b529f * src/plugins/Calendar.py (Calendar.__getitem__,
Widget.__getitem__): No translation for exception messages.
* src/po/template.po: Update.
* src/po/ru.po: Update.


svn: r5973
2006-02-23 00:47:20 +00:00
Don Allingham 429cb7b4ee * src/dates/Date_lt.py: new Lithuanian date handler
* src/po/lt.po: updated Lithuanian translation


svn: r5972
2006-02-22 21:05:54 +00:00
Jérôme Rapinat 9fded8b80c * src/po/fr.po translation improvement
svn: r5965
2006-02-20 11:59:42 +00:00
Don Allingham e8d471d4ee * src/WriteXML.py: encode paths for objects in XML to handle
&, > and < in paths.


svn: r5963
2006-02-19 22:23:47 +00:00
Don Allingham acc52f6816 * src/ImageSelect.py: fix already_loaded initalization
svn: r5962
2006-02-19 18:40:30 +00:00
Don Allingham 5e7041cae4 added
svn: r5961
2006-02-19 17:54:19 +00:00
Don Allingham e7b45e9937 Fix typo
svn: r5960
2006-02-19 17:49:57 +00:00
Jérôme Rapinat 219fa3312e * src/po/fr.po add Calendar.py translation
svn: r5959
2006-02-19 17:23:28 +00:00
Don Allingham 0daf58b604 * src/plugins/Makefile.am: added Calendary.py and
holidays.xml
* src/po/template.po: updated

* src/plugins/Calendar.py: added
* src/plugins/holidays.xml: added


svn: r5957
2006-02-19 05:25:29 +00:00
Don Allingham 95298549d8 added
svn: r5955
2006-02-19 00:52:49 +00:00
Jérôme Rapinat 1a7c66fa8d * src/po/fr.po update translation (with the new fixed template)
svn: r5954
2006-02-18 11:42:47 +00:00
Jérôme Rapinat 10deeaf7ac * src/po/fr.po translation improvement
svn: r5953
2006-02-18 11:05:43 +00:00
Martin Hawlisch 59c9e4802b updated translation
svn: r5951
2006-02-17 21:13:29 +00:00
Alex Roitman 96c3789009 * src/plugins/FamilyGroup.py (dump_parent): Translate event names.
svn: r5950
2006-02-17 17:46:33 +00:00
Don Allingham ed4b649f39 typo fix
svn: r5949
2006-02-17 14:58:43 +00:00
Martin Hawlisch b829978252 * src/po/de.po: Translation update
svn: r5948
2006-02-17 14:42:23 +00:00
Jérôme Rapinat 26baf4cbf6 * src/po/fr.po update translation (2.0.10)
svn: r5947
2006-02-17 11:14:49 +00:00
Don Allingham f25bdabcb7 * src/po/template.po: update for the string freeze for 2.0.10
svn: r5946
2006-02-17 04:48:58 +00:00
Alex Roitman bc75ced306 * src/plugins/FamilyGroup.py (add_user_options): Do not use _("")
to create empty checkbox.


svn: r5945
2006-02-16 22:17:13 +00:00
Don Allingham a7b12c2ec0 * src/ReadGedcom.py: remove debugging statements
svn: r5944
2006-02-16 21:38:42 +00:00
Alex Roitman 7309f0234a * src/ReportUtils.py (old_calc_age): Correct the logic.
svn: r5941
2006-02-15 18:26:50 +00:00
Don Allingham cb0ca84064 * src/plugins/NavWebPage.py: include more information about CC licenses
in the ALT and TITLE tags.


svn: r5940
2006-02-15 04:45:55 +00:00
Don Allingham d445b84dac * src/plugins/GraphViz.py: use new style links for narrative web page
generator


svn: r5939
2006-02-15 04:16:22 +00:00
Don Allingham 810a80da51 * 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


svn: r5938
2006-02-14 19:27:03 +00:00
Alex Roitman c1b12a893f * 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.


svn: r5937
2006-02-14 19:03:58 +00:00
Alex Roitman 8c50ca9c9c * 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.


svn: r5936
2006-02-14 18:50:46 +00:00
Jérôme Rapinat 4eedcb1b35 * src/po/fr.po update translation for the tool Extracting information from name
svn: r5935
2006-02-14 11:01:05 +00:00
Alex Roitman df630cee0d Update
svn: r5934
2006-02-14 05:34:45 +00:00
Don Allingham 2d39167929 * src/EditPerson.py: don't double add a place
svn: r5933
2006-02-14 04:34:13 +00:00
Alex Roitman 98aab9b503 * src/ReportUtils.py (buried_partial_date_no_place): Typo.
svn: r5932
2006-02-14 02:37:42 +00:00
Alex Roitman 16563fcf32 * src/ArgHandler.py (ArgHandler.cl_export): Do not strip path from
the media oject references.


svn: r5931
2006-02-14 01:48:01 +00:00
Stefan Bjork c41fbcaf18 * src/po/sv.po: Minor update.
svn: r5930
2006-02-13 20:00:25 +00:00
Jérôme Rapinat 69d2994491 * src/po/fr.po fix mistake died on/died
svn: r5929
2006-02-13 11:11:54 +00:00
Don Allingham 312044b831 * src/EventEdit.py: don't report the false "new event added" message
svn: r5928
2006-02-13 03:58:25 +00:00
Don Allingham f5f6442504 * src/EditPerson.py: display LDS temple correctly
* src/plugins/NavWebpage.py: print nickname


svn: r5927
2006-02-12 23:58:52 +00:00
Alex Roitman 524becc3cd * src/po/Makefile.am (.po.mo): Allow for parallel building.
svn: r5926
2006-02-12 22:03:07 +00:00
Alex Roitman fa8dde68bc * 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.


svn: r5925
2006-02-12 20:39:52 +00:00
Alex Roitman 34e7c8c67d * src/plugins/ReadPkg.py (impData): Use persistent directory for
unpacking the tarball: we need images to stay there.


svn: r5924
2006-02-12 19:07:33 +00:00
Don Allingham bc47111822 * 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


svn: r5923
2006-02-12 05:25:17 +00:00
Alex Roitman 64d8eb7417 * src/DbPrompter.py (open_native): Use empty GRDB when opening fails.
svn: r5922
2006-02-12 04:08:24 +00:00
Alex Roitman c01f2f714e * src/plugins/DetDescendantReport.py
(DetDescendantReport.write_endnotes): Disable writing reference
details.
* src/plugins/DetAncestralReport.py
(DetAncestorReport.write_endnotes): Disable writing reference details.


svn: r5920
2006-02-10 19:58:41 +00:00
Alex Roitman 8a700ceabc * src/docgen/ODFDoc.py: Typo.
svn: r5919
2006-02-10 16:48:23 +00:00
Alex Roitman cca81f693f * src/WriteGedcom.py (write_sources): Export data_map.
svn: r5911
2006-02-09 21:10:56 +00:00
Alex Roitman fde077914c * src/data/gramps.desktop: Improve Russian string, add Office
category.


svn: r5910
2006-02-09 19:00:44 +00:00
Alex Roitman d643aa3936 * src/QuestionDialog.py (MissingMediaDialog): Catch delete event
and warn the user.
* src/Utils.py (ProgressMeter) Catch delete event and warn the user.


svn: r5906
2006-02-09 03:04:33 +00:00
Alex Roitman cb52b7d9c6 * src/WriteGedcom.py (write_source_ref): Write confidence level
(the QUAY tag) of the source reference into GEDCOM.


svn: r5905
2006-02-09 02:05:50 +00:00
Alex Roitman de81e15969 * src/gramps.glade: Correct +/- tooltips for Data tab in Source Editor.
svn: r5904
2006-02-09 01:18:31 +00:00
Alex Roitman bdf496ebb2 * src/plugins/Leak.py (display): Catch exception coming from
trying to call __repr__ on a closed db.DB.


svn: r5903
2006-02-09 01:10:10 +00:00
Don Allingham 18e8cb6478 * src/plugins/FamilyGroup.py: correctly put borders on the
children cells.

* src/plugins/DetDescendantReport.py: include spouse option


svn: r5896
2006-02-08 05:18:46 +00:00
Alex Roitman 556b5cd371 * src/docgen/ODFDoc.py: Correct typos.
svn: r5888
2006-02-05 19:16:12 +00:00
Alex Roitman c284652cc3 * 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.


svn: r5870
2006-02-03 04:33:14 +00:00
Alex Roitman f37c2d5ccb * src/docgen/ODFDoc.py (init): Correct name for parent style;
Use handling program name obtained from the mime system.


svn: r5835
2006-01-26 18:11:27 +00:00
Alex Roitman 92906e88cd * 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.


svn: r5832
2006-01-25 20:15:16 +00:00
Alex Roitman e0aab07c3e * src/po/nl.po: Translation update.
svn: r5831
2006-01-25 19:49:33 +00:00
Don Allingham d3753628c9 * src/plugings/FamiyGroup.py: options for "Recursive", "Generation
Number", "Parent Events", "Parent Addresses", "Parent Alternate
Names", "Parent Notes".


svn: r5830
2006-01-25 19:10:09 +00:00
Don Allingham 8eddbe7462 * src/plugins/DetDescendantReport.py: include spouse option
svn: r5793
2006-01-19 03:50:29 +00:00
Jérôme Rapinat 523af4b182 * /doc/gramps-manual/fr/cmdplug.xml: update
svn: r5779
2006-01-17 20:58:16 +00:00
Alex Roitman b3bab9607d * src/EditPlace.py, src/EditSource.py, src/ImageSelect.py: Provide
default value for the second argument on close().


svn: r5763
2006-01-16 20:02:25 +00:00
Alex Roitman 8ba376dd86 * src/GenericFilter.py
(IsLessThanNthGenerationAncestorOfBookmarked): Typo.


svn: r5762
2006-01-16 19:39:35 +00:00
Jérôme Rapinat 882d9c0b17 * data\gramps.desktop: Add french entry and comment
* plugins\DetDescendantReport.py: Same patch as DetAncestralReport (age calculated bug)


svn: r5761
2006-01-16 15:17:37 +00:00
Don Allingham 28b56af746 * src/RelLib.py: improve Event is_equal method
svn: r5757
2006-01-16 02:24:05 +00:00
Frode Jemtland 481a797b28 Translated more strings. 85 fuzzy left. They are translated, need to be washed.
svn: r5717
2006-01-11 23:31:10 +00:00
Stefan Bjork 0574fd2489 * src/plugins/DetAncestralReport.py: Calculate age for indiviuals.
* src/po/sv.po: Updates.


svn: r5713
2006-01-11 13:27:14 +00:00
Frode Jemtland dcfe9af6cb Changing "Hjemperson" to "Proband". This is the more correct name, I have learned during the last week.....
svn: r5706
2006-01-10 21:49:35 +00:00
Alex Roitman f79520e845 * 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.

* doc/man/fr/gramps.1.in: Add translated manpage.


svn: r5675
2006-01-05 19:49:43 +00:00
Stefan Bjork 654e2af90d * src/po/sv.po: Updates.
svn: r5672
2006-01-05 12:59:30 +00:00
Jérôme Rapinat df4d3c3309 * doc/gramps-manual/fr/usage.xml: Add Sub-subsection Substitution Values
svn: r5665
2006-01-04 09:48:26 +00:00
Alex Roitman 9a357b844b * src/gedcomimport.glade: Make dialog non-resizable.
svn: r5660
2006-01-03 23:23:47 +00:00
Jérôme Rapinat efb66d212f * src/po/fr.po fix mistake county/country
svn: r5659
2006-01-03 23:05:53 +00:00
Don Allingham 2700788f54 update
svn: r5657
2006-01-03 04:45:20 +00:00
Don Allingham 8c2563ad05 * doc/gramps-manual/C/usage.xml: more updates
svn: r5656
2006-01-03 04:38:20 +00:00
Jérôme Rapinat 6963b95eec # src\po\fr.po update french translation
svn: r5650
2006-01-01 13:14:16 +00:00
Frode Jemtland 9e8462bffa msgmerge with last template file..... 0 strings translated
svn: r5649
2005-12-30 23:18:36 +00:00
Don Allingham 840569cea7 * src/dates/Date_nl.py: fix index for "merz"
svn: r5635
2005-12-27 14:56:22 +00:00
Jérôme Rapinat 608960a3e2 updates
svn: r5630
2005-12-24 12:25:35 +00:00
Jérôme Rapinat c43f8c61a5 add local and historical variants for months
svn: r5628
2005-12-23 22:43:05 +00:00
Alex Roitman e96641fa81 * 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.


svn: r5619
2005-12-23 00:17:33 +00:00
Don Allingham be83003e5c * src/ReadGedcom.py: handle overlapping on source and family ID values
svn: r5602
2005-12-21 17:20:40 +00:00
Don Allingham 86835434c6 typo edits
svn: r5589
2005-12-20 04:11:36 +00:00
Don Allingham 4482378716 update
svn: r5582
2005-12-19 05:01:05 +00:00
Don Allingham 1c5ad3f57f * doc/gramps-manual/C/usage.xml: updates
* doc/gramps-manual/C/usage.xml: updates
* doc/gramps-manual/C/mainwin.xml: updates


svn: r5580
2005-12-18 02:44:05 +00:00
Alex Roitman d6c4ffe649 * src/GrampsDbBase.py (transaction_commit): Typo.
svn: r5574
2005-12-17 21:37:33 +00:00
Don Allingham a5e9312678 update
svn: r5568
2005-12-17 05:34:10 +00:00
Don Allingham f3e2c25f21 update
svn: r5567
2005-12-17 05:26:38 +00:00
Don Allingham f1de6cc347 * src/gramps-manual/C/usuage.xml: updates
svn: r5566
2005-12-17 04:52:17 +00:00
Don Allingham 751a7911fb * src/gramps-manual/C/mainwin.xml: updates
svn: r5565
2005-12-16 23:03:18 +00:00
Don Allingham 37bfa319a7 * doc/gramps-manual/C/getstart.xml: updates
* doc/gramps-manual/C/mainwin.xml: updates


svn: r5552
2005-12-15 04:51:09 +00:00
Alex Roitman 8c0ad73c2e * src/plugins/DescendReport.py (dump): Initialize child list for
each family.


svn: r5550
2005-12-15 00:00:47 +00:00
Alex Roitman 10b86050d1 * src/plugins/PatchNames.py: Fix title/name mixup, only detect new
title, keep old title, keep old prefix.


svn: r5549
2005-12-14 23:03:54 +00:00
Alex Roitman 4f5fc60743 * configure.in: bump up the version number.
svn: r5542
2005-12-12 08:11:39 +00:00
83 changed files with 55395 additions and 32585 deletions
+307
View File
@@ -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.
+12
View File
@@ -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 -2
View File
@@ -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
View File
@@ -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
+3 -5
View File
@@ -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
+3 -3
View File
@@ -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 &quot;quit without
saving.&quot; 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>
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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>
+113 -1
View File
@@ -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>
+3
View File
@@ -0,0 +1,3 @@
gramps.1
Makefile.in
Makefile
+13
View File
@@ -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)
+3
View File
@@ -0,0 +1,3 @@
gramps.1
Makefile.in
Makefile
+13
View File
@@ -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)
+214
View File
@@ -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.
+1 -1
View File
@@ -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
View File
@@ -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"""
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+11 -2
View File
@@ -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()
+12 -3
View File
@@ -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()
+17 -8
View File
@@ -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()
-1
View File
@@ -67,7 +67,6 @@ from DdTargets import DdTargets
_BORN = _('b.')
_DIED = _('d.')
column_names = [
(_('#'),0) ,
(_('ID'),1) ,
+1 -1
View File
@@ -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
View File
@@ -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()
+1 -1
View File
@@ -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
+13
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+18
View File
@@ -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
View File
@@ -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():
+21 -3
View File
@@ -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
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -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)
+9
View File
@@ -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
+17 -2
View File
@@ -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.
+1 -1
View File
@@ -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 -2
View File
@@ -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
View File
@@ -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)
+149
View File
@@ -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)
+1 -1
View File
@@ -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
+1
View File
@@ -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\
+1
View File
@@ -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
+2 -2
View File
@@ -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)
+1 -3
View File
@@ -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">
+3 -3
View File
@@ -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>
+943
View File
@@ -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"),
)
+12 -9
View File
@@ -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)
+96 -49
View File
@@ -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()
+10 -8
View File
@@ -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)
#------------------------------------------------------------------------
+28 -23
View File
@@ -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
#------------------------------------------------------------------------
#
+39 -22
View File
@@ -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())
#------------------------------------------------------------------------
#
+6 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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()
+11 -8
View File
@@ -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#].*$")
+10 -4
View File
@@ -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()
+5 -1
View File
@@ -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"
+16 -8
View File
@@ -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:
+30 -16
View File
@@ -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()
+19 -12
View File
@@ -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)
#------------------------------------------------------------------------
#
+4 -7
View File
@@ -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()
+119
View File
@@ -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>
+1 -4
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1246 -1366
View File
File diff suppressed because it is too large Load Diff
+1587 -1396
View File
File diff suppressed because it is too large Load Diff
+6609 -4583
View File
File diff suppressed because it is too large Load Diff
+4369 -2999
View File
File diff suppressed because it is too large Load Diff
+5613 -4768
View File
File diff suppressed because it is too large Load Diff
+4369 -2999
View File
File diff suppressed because it is too large Load Diff
+9979 -5704
View File
File diff suppressed because it is too large Load Diff
+1675 -1373
View File
File diff suppressed because it is too large Load Diff
+1998 -1942
View File
File diff suppressed because it is too large Load Diff
+1459 -1272
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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