Compare commits

...

91 Commits

Author SHA1 Message Date
Richard Taylor ba7fae7062 SVN reorganisation: Move current maintenance branches
svn: r12908
2009-08-07 08:12:15 +00:00
Benny Malengier ab1e0183f7 0002512: [Python 2.6 support] Change sets module by built-in set types
svn: r11413
2008-12-04 14:33:24 +00:00
Benny Malengier 663b2aead9 backport to suppport bsddb 4.7 / python 2.6
svn: r11391
2008-12-02 13:38:09 +00:00
Benny Malengier 677af32e5e 2008-02-27 Benny Malengier <benny.malengier@gramps-project.org>
* src/GrampsDb/_ReadXML.py: don't create empty objects in bookmarks
	* src/Bookmarks.py: don't store duplicates, backport



svn: r10129
2008-02-27 10:44:52 +00:00
Raphael Ackermann 967a48abdc 2008-02-02 Raphael Ackermann <raphael.ackermann@gmail.com>
* src/GrampsDb/_WriteGedcom.py
	* src/plugins/WriteGeneWeb.py
	0001414: "Living" is not translated in GEDCOM export file

svn: r9974
2008-02-02 10:35:01 +00:00
Peter Landgren d547e773b4 Found one error
svn: r9969
2008-01-31 17:14:21 +00:00
Benny Malengier 10ae727aa1 2008-01-23 Brian Matherly <brian@gramps-project.org>
Benny Malengier <benny.malengier@gramps-project.org>: backport trunk
	* src/ReportBase/_StyleComboBox.py:
	* src/ReportBase/_StyleEditor.py:
	Modify the style editor to properly handle unicode style names.



svn: r9919
2008-01-23 13:35:33 +00:00
Benny Malengier 65dcc697ac 2008-01-22 Benny Malengier <benny.malengier@gramps-project.org>
* src/Editors/_EditPerson.py: callback for gallerytab no longer needed



svn: r9907
2008-01-22 07:45:49 +00:00
Benny Malengier 098be7de14 * src/plugins/Check.py: bug (buglist) wrong method call
2008-01-21 Benny Malengier <benny.malengier@gramps-project.org>


svn: r9901
2008-01-21 08:38:17 +00:00
Benny Malengier 020fdef1ce 2008-01-21 Benny Malengier <benny.malengier@gramps-project.org>
* src/docgen/SvgDrawDoc.py: backport patch so that text in svgbox shows



svn: r9900
2008-01-21 08:14:34 +00:00
James G Sack d4c3d51d2a fix #1621 .. use os.path.samefile in write_photo
svn: r9892
2008-01-18 21:40:27 +00:00
Benny Malengier e5a4f0c906 2008-01-17 Benny Malengier <benny.malengier@gramps-project.org>
* src/DataViews/_RelationView.py: isue #1605, not twice in same family



svn: r9862
2008-01-17 09:57:49 +00:00
Stéphane Charette d72778f1ea update version number
svn: r9805
2008-01-14 07:43:47 +00:00
Stéphane Charette b49f4ce088 2.2.10 (Lemon Curry?)
svn: r9803
2008-01-14 06:09:49 +00:00
Jérôme Rapinat 7bb51faef7 2008-01-13 Boril Gourinov <boril.gourinov@gmail.com>
* bg.po: Translation update



svn: r9793
2008-01-13 14:59:17 +00:00
Julio Sánchez b3009fa5c5 Update for 2.2.10
svn: r9791
2008-01-13 06:24:06 +00:00
Jérôme Rapinat b401e09477 2008-01-09 Lubo Vasko <pgval@inMail.sk>
* sk.po: Translation update



svn: r9762
2008-01-09 08:53:13 +00:00
Jérôme Rapinat fdf26dab90 2008-01-09 Boril Gourinov <boril.gourinov@gmail.com>
* bg.po: Translation update



svn: r9761
2008-01-09 08:33:59 +00:00
Jérôme Rapinat 53e931b8b3 2008-01-08 Boril Gourinov <boril.gourinov@gmail.com>
* bg.po: Translation update



svn: r9750
2008-01-08 08:42:01 +00:00
Peter Landgren 3f9e7f68df sv.po 1 fuzzy + improvments
svn: r9741
2008-01-07 12:41:19 +00:00
Peter Landgren 9b368b02fb 1 fuzzy, + users improvments
svn: r9740
2008-01-07 12:40:34 +00:00
Stéphane Charette 1ccf2a6da6 release candidate 2.2.10
svn: r9734
2008-01-07 00:06:24 +00:00
Stéphane Charette 1392071612 added WinMime.py and GrampsType.py
svn: r9733
2008-01-07 00:02:57 +00:00
Stéphane Charette 103e843be3 resize and link to very large images, included sources for media objects
svn: r9728
2008-01-06 21:26:59 +00:00
Stéphane Charette 42e84d399e new pot prior to 2.2.10
svn: r9726
2008-01-06 20:11:44 +00:00
Peter Landgren 49250f97db Update for 2.2.10
svn: r9721
2008-01-06 10:47:08 +00:00
Arturas Sleinius c61cb14958 Updated Lithuanian translation
svn: r9717
2008-01-06 08:09:59 +00:00
Erik De Richter 1b7386f6ec new translation strings nl
svn: r9711
2008-01-05 10:05:30 +00:00
Jérôme Rapinat 861f94524b 2008-01-04 Jerome Rapinat <romjerome@yahoo.fr>
* src/DateHandler/_Date_fr.py : typo



svn: r9706
2008-01-04 18:05:42 +00:00
Jérôme Rapinat 751c314939 2008-01-03 Mirko Leonhaeuser <mirko@leonhaeuser.de>
* de.po: update



svn: r9705
2008-01-03 20:16:04 +00:00
Benny Malengier 3463abdfe4 * data/gramps.desktop.in: list more mime types, item 851
2008-01-03 Benny Malengier <benny.malengier@gramps-project.org>


svn: r9703
2008-01-03 16:37:58 +00:00
Benny Malengier 6a9f70948f * src/GrampsDb/_WriteXML.py: wrong escape of &, bug 1430
2008-01-03 Benny Malengier <benny.malengier@gramps-project.org>


svn: r9701
2008-01-03 15:25:17 +00:00
Benny Malengier 1e2d017c92 2008-01-03 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/RelCalc.py: managed window error, bug 1499



svn: r9699
2008-01-03 14:50:15 +00:00
Gary Burton 22b32f3ca3 2008-01-03 Gary Burton <gary.burton@zen.co.uk>
* src/GrampsWidgets.py: allow MonitoredEntry widgets to be updated with
	empty strings. I fixed this issue in trunk 2 months ago and no ill effects
	have been reported. issue #1314



svn: r9697
2008-01-03 13:56:03 +00:00
Jérôme Rapinat c1f5b81d95 2008-01-03 Jerome Rapinat <romjerome@yahoo.fr>
* src/GrampsDb/_ReadGrdb.py
        * src/GrampsDb/_ReadXML.py: removed "Family Tree" on translation string, used "database"



svn: r9694
2008-01-03 13:10:04 +00:00
Jérôme Rapinat 0a16676385 2008-01-03 Jerome Rapinat <romjerome@yahoo.fr>
* fr.po: Translation update



svn: r9693
2008-01-03 12:14:31 +00:00
Benny Malengier b589f2dff4 * src/ViewManager.py: remove unneeded show, remove tabs
2008-01-02 Benny Malengier <benny.malengier@gramps-project.org>


svn: r9690
2008-01-03 09:10:03 +00:00
Benny Malengier 9f0a5402bd 2008-01-02 Benny Malengier <benny.malengier@gramps-project.org>
* src/Filters/SideBar/_PlaceSidebarFilter.py: correct string, bug #1275

2008-01-02 Jerome Rapinat  <romjerome@yahoo.fr>


svn: r9685
2008-01-02 19:19:32 +00:00
Jérôme Rapinat 517c25720b 2008-1-2 Jerome Rapinat <romjerome@yahoo.fr>
* configure.in: update of bg.po



svn: r9684
2008-01-02 17:39:47 +00:00
Jérôme Rapinat 899cf744c7 2008-01-02 Boril Gourinov <boril.gourinov@gmail.com>
* bg.po: New language, bulgarian



svn: r9683
2008-01-02 14:04:36 +00:00
Peter Landgren d2721f9343 Minor update.
svn: r9673
2008-01-01 14:00:03 +00:00
Benny Malengier 5303197ef8 2007-12-23 Benny Malengier <benny.malengier@gramps-project.org>
* src/glade/gramps.glade: accel (Role and Date) in Event Ref, bug #1449



svn: r9563
2007-12-23 09:02:38 +00:00
Espen Berg d7d776f214 Updated Norwegian translation
svn: r9561
2007-12-22 17:02:01 +00:00
Benny Malengier 8b7136ddd9 2007-12-17 Benny Malengier <benny.malengier@gramps-project.org>
* src/RelLib/_Person.py: sources in attributes of eventref are not seen
		 in ref tables
	* src/RelLib/_EventRef.py: can contain sources, add methods for that
	* src/plugins/Check.py: low level check of repo table, add check to 
		clean up referenced but not existing repos



svn: r9531
2007-12-19 09:28:43 +00:00
Gary Burton ab29b78e6d 2007-12-15 Gary Burton <gary.burton@zen.co.uk>
* src/Editors/_EditFamily.py: emit family-update signal #1416



svn: r9511
2007-12-15 21:55:08 +00:00
Benny Malengier 65c99d23b5 2007-12-14 Benny Malengier <benny.malengier@gramps-project.org>
* src/RelLib/_Repository.py: Repo has address which can have source, so
		backref of source to repo must be allowed and added!
	* src/DisplayTabs/_BackRefModel.py: Repo can be backref, add
	* src/DisplayTabs/_BackRefList.py: Repo can be backref, add



svn: r9505
2007-12-14 14:06:18 +00:00
Benny Malengier 0bad0de909 2007-12-11 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/IndivComplete.py: bug on buglist, wrong parameter



svn: r9488
2007-12-11 08:25:16 +00:00
Benny Malengier 6911aa415a 2007-12-10 Benny Malengier <benny.malengier@gramps-project.org>
* src/RelLib/_Event.py: add attr to list of sec objects, bug #1318



svn: r9483
2007-12-10 21:50:45 +00:00
Alex Roitman 037893413b 2007-12-09 Alex Roitman <shura@gramps-project.org>
* data/grampsxml.rng: Add namemaps.
	* data/grampsxml.dtd: Add namemaps.



svn: r9472
2007-12-09 20:11:05 +00:00
Eero Tamminen 00ec7a7ddb minor improvements
svn: r9469
2007-12-09 18:54:49 +00:00
Benny Malengier 3e5f1350dd wrong comment string
svn: r9459
2007-12-08 13:43:35 +00:00
Benny Malengier e385af623d 2007-11-24 Benny Malengier <benny.malengier@gramps-project.org>
Add support for name grouping import/export
	* src/GrampsDb/_GrampsDbBase.py: obtain grouping keys
	* src/GrampsDb/_ReadXML.py: read in group table
	* src/GrampsDb/_DbUtils.py: grdb -> grdb copy of grouping table
	* src/GrampsDb/_ReadGrdb.py: read in group table
	* src/GrampsDb/_WriteXML.py: write group table out
	* src/GrampsDb/_GrampsBSDDB.py: group table is no sec table, init it
	together with primary tables!



svn: r9457
2007-12-07 22:47:40 +00:00
Peter Landgren b7d7a060f5 Fixed uncollected objects
svn: r9451
2007-12-06 18:58:59 +00:00
Peter Landgren 5968ba16eb Fixed Living in GEDCOM export
svn: r9444
2007-12-05 14:36:35 +00:00
James G Sack 004024a2b3 fix #1399 trailing whitespace causes bogus handle
svn: r9423
2007-11-28 22:58:33 +00:00
James G Sack b775d17dda revert r9410 -- better leave it broken
svn: r9413
2007-11-26 11:21:57 +00:00
James G Sack 3559bd6826 #1378 (interim?) fix by testing isfile() before the remove()
svn: r9410
2007-11-26 10:17:36 +00:00
Benny Malengier 0a10de647e 2007-11-24 Benny Malengier <benny.malengier@gramps-project.org>
* src/Editors/_EditPerson.py: callback family update bug removed



svn: r9395
2007-11-24 13:54:20 +00:00
Benny Malengier 5755e456e4 2007-11-23 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/Check.py: fix wrong event ref (was fixed in trunk in 2007/02)



svn: r9392
2007-11-23 22:01:42 +00:00
Jérôme Rapinat cfefb8b47d /po/fr.po update
svn: r9378
2007-11-21 14:31:18 +00:00
Jérôme Rapinat b0d15be93d /po/fr.po regression issue
svn: r9376
2007-11-20 15:07:29 +00:00
Jérôme Rapinat a88fe2be2b src/plugins/Makefile.am add missing reference for rel_nl
svn: r9373
2007-11-20 12:09:20 +00:00
Benny Malengier 766f2c4551 2007-11-13 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/GraphViz.py: issue #1362, code generation should not show
	open with ghostview, ..., instead show app with text/plain.



svn: r9346
2007-11-13 10:32:51 +00:00
Gary Burton 59dd029306 2007-11-12 Gary Burton <gary.burton@zen.co.uk>
* src/ScratchPad.py: fixed a crash when building tooltip. Not enough
	place holders in format string



svn: r9343
2007-11-12 21:29:28 +00:00
Peter Landgren 0054f537d1 Translation clean up
svn: r9340
2007-11-12 19:44:34 +00:00
James G Sack 4e33489607 fix #1365 typo in lds_ord_name
svn: r9333
2007-11-12 08:29:49 +00:00
Gary Burton b6a5f46caa 2007-11-10 Gary Burton <gary.burton@zen.co.uk>
* src/plugins/IndivComplete.py: added support for printing
	non-primary, non-family events.



svn: r9327
2007-11-10 23:22:17 +00:00
James G Sack 5c2e433ff3 fix typos in cl_export (exporting gedcom) bug #353
svn: r9319
2007-11-07 19:35:42 +00:00
Benny Malengier e9db9568cb * src/AddMedia.py: fix issue #1350, relative path not working addmedia
* src/Editors/_EditPerson.py: family rebuild callback error

2007-11-07 Benny Malengier <benny.malengier@gramps-project.org>


svn: r9318
2007-11-07 18:50:57 +00:00
Benny Malengier 805103387d 2007-11-07 Benny Malengier <benny.malengier@gramps-project.org>
* src/AddMedia.py: add media crash, fix issue #1349



svn: r9315
2007-11-07 11:04:10 +00:00
James G Sack 803a4dc9d2 fix old typo in ansel_utf8
svn: r9314
2007-11-06 22:15:54 +00:00
James G Sack c5138eac36 remove 2 configure-generated files from version control
svn: r9298
2007-11-05 22:20:51 +00:00
Gary Burton ce79322bdf 2007-11-03 Gary Burton <gary.burton@zen.co.uk>
* src/plugins/DetDescendantReport.py
	* src/plugins/DetAncestralReport.py
	Added functionality to print event and event reference notes. issue #1335



svn: r9293
2007-11-03 22:11:52 +00:00
Stéphane Charette d89d56af71 issue #1340, don't display mime-type
svn: r9291
2007-11-03 05:43:49 +00:00
James G Sack 7a3316e492 fix termination problem with CLI operations
svn: r9280
2007-10-31 08:25:14 +00:00
Gary Burton 51159df14e * src/RelLib/_Person.py: setting the death index wrongly.
2007-10-29 Gary Burton <gary.burton@zen.co.uk>


svn: r9276
2007-10-30 15:05:53 +00:00
Gary Burton 86a5f53dd5 2007-10-29 Gary Burton <gary.burton@zen.co.uk>
* src/RelLib/_Person.py: reset birth and death indexes after deleting
	an event. Fixes #1327



svn: r9268
2007-10-29 22:32:41 +00:00
Gary Burton 0f22a6ef69 * src/Editors/_EditPlace.py: fixed name of street MonitoredEntry
* src/Editors/_EditLocation.py: fixed name of street MonitoredEntry
	MonitoredEntry field for street wrongly named as city.
	Caused strange occasional drag and drop bug. issue #1304

2007-10-28 Gary Burton <gary.burton@zen.co.uk>


svn: r9263
2007-10-28 21:54:39 +00:00
Gary Burton 47c63757bd 2007-10-28 Gary Burton <gary.burton@zen.co.uk>
* src/DisplayTabs/_EnbeddedList.py: Fixed crash when doing a drag and
	drop with an object that was deleted from a list. issue # 1326



svn: r9261
2007-10-28 16:40:18 +00:00
Stéphane Charette 36ad798989 various fixes
svn: r9252
2007-10-26 06:15:50 +00:00
Benny Malengier 224c185a24 2007-10-26 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/rel_nl.py: various improvements



svn: r9249
2007-10-25 22:28:56 +00:00
Benny Malengier 8220a39d65 * src/DisplayTabs/_GalleryTab.py: remove edit_callback, works via signals now
2007-10-22 Benny Malengier <benny.malengier@gramps-project.org>


svn: r9235
2007-10-22 20:38:29 +00:00
Benny Malengier c51d00bc77 * src/DisplayTabs/_EmbeddedList.py: during rebuild, don't do select change
* src/DisplayTabs/_ButtonTab.py: avoid double call of selection_change
	* src/DisplayTabs/_GrampsTab.py: method to add db connects, and set connects
	* src/Editors/_EditPrimary.py: on add tab pass db connection method
	* src/Editors/_EditSecondary.py: on add tab pass db connection method
	* src/Editors/_EditReference.py: on add tab pass db connection method
	* src/DisplayTabs/_GalleryTab.py: use new structure to correctly update
	displaytab

2007-10-22 Benny Malengier <benny.malengier@gramps-project.org>


svn: r9234
2007-10-22 20:28:42 +00:00
Benny Malengier 026d966e9f 2007-10-22 Benny Malengier <benny.malengier@gramps-project.org>
* src/GrampsDb/_GrampsInMemDB.py: xml load/save not working, fixed #1319


svn: r9232
2007-10-22 18:46:28 +00:00
James G Sack 680c09f5c2 update changelog per r9227 commit of src/ansel_utf8.py
svn: r9228
2007-10-21 17:36:06 +00:00
James G Sack 99a70817ad fix ansel input & output (ref: issue #831)
svn: r9227
2007-10-21 17:12:56 +00:00
Benny Malengier 734d81bc79 2007-10-21 Benny Malengier <benny.malengier@gramps-project.org>
* src/Editors/_EditPerson.py: If a family changes, rebuild family backref of all 
	open editors. issue #1309, causing corrupt database.
	Also remove unneeded associations rebuild when family changes



svn: r9225
2007-10-21 07:59:42 +00:00
Alex Roitman 6ca81346cf 2007-10-19 Piotr Czubaszek <pioterus@gmail.com>
* src/docgen/PdfDoc.py (PdfDoc.add_media_object): Missing period.



svn: r9216
2007-10-20 02:34:28 +00:00
Benny Malengier 8cd1a019cc 2007-10-19 Gary Burton <gary.burton@zen.co.uk>
* src/DisplayTabs/_EmbeddedList.py:
	* src/DisplayTabs/_ButtonTab.py:
	ENTER is edit on embedded lists, issue #1296



svn: r9213
2007-10-19 20:51:18 +00:00
Alex Roitman 4592913700 2007-10-19 Frank S. Thomas <frank@thomas-alfeld.de>
* src/glade/gramps.glade: Remove extra space.



svn: r9212
2007-10-19 15:31:16 +00:00
Stéphane Charette f7e8065ce8 update version string to 2.2.10
svn: r9205
2007-10-18 15:14:27 +00:00
74 changed files with 28597 additions and 16571 deletions
+248
View File
@@ -1,3 +1,251 @@
2008-02-27 Benny Malengier <benny.malengier@gramps-project.org>
* src/GrampsDb/_ReadXML.py: don't create empty objects in bookmarks
* src/Bookmarks.py: don't store duplicates, backport
2008-02-02 Raphael Ackermann <raphael.ackermann@gmail.com>
* src/GrampsDb/_WriteGedcom.py
* src/plugins/WriteGeneWeb.py
0001414: "Living" is not translated in GEDCOM export file
2008-01-23 Brian Matherly <brian@gramps-project.org>
Benny Malengier <benny.malengier@gramps-project.org>: backport trunk
* src/ReportBase/_StyleComboBox.py:
* src/ReportBase/_StyleEditor.py:
Modify the style editor to properly handle unicode style names.
2008-01-22 Benny Malengier <benny.malengier@gramps-project.org>
* src/Editors/_EditPerson.py: callback for gallerytab no longer needed
2008-01-21 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/Check.py: bug (buglist) wrong method call
2008-01-21 Benny Malengier <benny.malengier@gramps-project.org>
* src/docgen/SvgDrawDoc.py: backport patch so that text in svgbox shows
2008-01-18 Jim Sack <jgsack@san.rr.com>
* src/GrampsDb/_WriteGedcom.py : #1621 use os.path.samefile in write_photo
2008-01-17 Benny Malengier <benny.malengier@gramps-project.org>
* src/DataViews/_RelationView.py: isue #1605, not twice in same family
2008-01-13 Stéphane Charette <stephanecharette@gmail.com>
* configure.in: released 2.2.10; update version number to 2.2.11
2008-01-06 Stéphane Charette <stephanecharette@gmail.com>
* NEWS: release candidate for version 2.2.10 "Lemon Curry?"
2008-01-06 Stéphane Charette <stephanecharette@gmail.com>
* src/plugins/NarrativeWeb.py: resize and link to very large images,
include sources (when available) for media objects
2008-01-04 Jerome Rapinat <romjerome@yahoo.fr>
* src/DateHandler/_Date_fr.py : typo
2008-01-03 Benny Malengier <benny.malengier@gramps-project.org>
* data/gramps.desktop.in: list more mime types, item 851
2008-01-03 Benny Malengier <benny.malengier@gramps-project.org>
* src/GrampsDb/_WriteXML.py: wrong escape of &, bug 1430
2008-01-03 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/RelCalc.py: managed window error, bug 1499
2008-01-03 Gary Burton <gary.burton@zen.co.uk>
* src/GrampsWidgets.py: allow MonitoredEntry widgets to be updated with
empty strings. I fixed this issue in trunk 2 months ago and no ill effects
have been reported. issue #1314
2008-01-03 Jerome Rapinat <romjerome@yahoo.fr>
* src/GrampsDb/_ReadGrdb.py
* src/GrampsDb/_ReadXML.py: removed "Family Tree" on translation string, used "database"
2008-01-02 Benny Malengier <benny.malengier@gramps-project.org>
* src/ViewManager.py: remove unneeded show, remove tabs
2008-01-02 Benny Malengier <benny.malengier@gramps-project.org>
* src/Filters/SideBar/_PlaceSidebarFilter.py: correct string, bug #1275
2008-01-02 Jerome Rapinat <romjerome@yahoo.fr>
* configure.in: update of bg.po
2007-12-23 Benny Malengier <benny.malengier@gramps-project.org>
* src/glade/gramps.glade: accel (Role and Date) in Event Ref, bug #1449
2007-12-17 Benny Malengier <benny.malengier@gramps-project.org>
* src/RelLib/_Person.py: sources in attributes of eventref are not seen
in ref tables
* src/RelLib/_EventRef.py: can contain sources, add methods for that
* src/plugins/Check.py: low level check of repo table, add check to
clean up referenced but not existing repos
2007-12-15 Gary Burton <gary.burton@zen.co.uk>
* src/Editors/_EditFamily.py: emit family-update signal #1416
2007-12-14 Benny Malengier <benny.malengier@gramps-project.org>
* src/RelLib/_Repository.py: Repo has address which can have source, so
backref of source to repo must be allowed and added!
* src/DisplayTabs/_BackRefModel.py: Repo can be backref, add
* src/DisplayTabs/_BackRefList.py: Repo can be backref, add
2007-12-11 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/IndivComplete.py: bug on buglist, wrong parameter
2007-12-10 Benny Malengier <benny.malengier@gramps-project.org>
* src/RelLib/_Event.py: add attr to list of sec objects, bug #1318
2007-12-09 Alex Roitman <shura@gramps-project.org>
* data/grampsxml.rng: Add namemaps.
* data/grampsxml.dtd: Add namemaps.
2007-12-07 Benny Malengier <benny.malengier@gramps-project.org>
Add support for name grouping import/export
* src/GrampsDb/_GrampsDbBase.py: obtain grouping keys
* src/GrampsDb/_ReadXML.py: read in group table
* src/GrampsDb/_DbUtils.py: grdb -> grdb copy of grouping table
* src/GrampsDb/_ReadGrdb.py: read in group table
* src/GrampsDb/_WriteXML.py: write group table out
* src/GrampsDb/_GrampsBSDDB.py: group table is no sec table, init it
together with primary tables!
2007-11-28 Jim Sack <jgsack@san.rr.com>
* src/GrampsDb/_ReadGedcom.py : #1399 remove trail whitespace (readahead)
fixes discarded reference due to bogus handles that get created
when the reference looks like "@REF_ID@ " (note space after)
2007-11-26 Jim Sack <jgsack@san.rr.com>
* src/plugins/ReadPkg.py : reverted previous change
better to leave it broken than to risk worse
2007-11-26 Jim Sack <jgsack@san.rr.com>
* src/plugins/ReadPkg.py : #1378 add isfile() before remove()
Note: this may be part a larger "relative path" problem
2007-11-24 Benny Malengier <benny.malengier@gramps-project.org>
* src/Editors/_EditPerson.py: callback family update bug removed
2007-11-23 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/Check.py: fix wrong event ref (was fixed in trunk in 2007/02)
2007-11-13 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/GraphViz.py: issue #1362, code generation should not show
open with ghostview, ..., instead show app with text/plain.
2007-11-12 Gary Burton <gary.burton@zen.co.uk>
* src/ScratchPad.py: fixed a crash when building tooltip. Not enough
place holders in format string
2007-11-11 Jim Sack <jgsack@san.rr.com>
* src/GrampsDb/_WriteGedcom.py: fix #1365 s/SGLS/SLGS/
backport fix from trunk (issue #1364 there).
2007-11-10 Gary Burton <gary.burton@zen.co.uk>
* src/plugins/IndivComplete.py: added support for printing
non-primary, non-family events.
2007-11-07 Jim Sack <jgsack@san.rr.com>
* src/ArgHandler.py: typos in cl_export at L562,3 bug #1353
triggered by exporting gedcom
2007-11-07 Benny Malengier <benny.malengier@gramps-project.org>
* src/AddMedia.py: fix issue #1350, relative path not working addmedia
* src/Editors/_EditPerson.py: family rebuild callback error
2007-11-07 Benny Malengier <benny.malengier@gramps-project.org>
* src/AddMedia.py: add media crash, fix issue #1349
2007-11-05 Jim Sack <jgsack@san.rr.com>
* src/ansel_utf8.py: fix old typo in ansel char 0xAE
was U+02BE, changed to U+02BC (now same as 3.0 code)
2007-11-05 Jim Sack <jgsack@san.rr.com>
* remove 2 files from version control: config.guess and config.sub
These are generated by configure (via autogen.sh).
2007-11-03 Gary Burton <gary.burton@zen.co.uk>
* src/plugins/DetDescendantReport.py
* src/plugins/DetAncestralReport.py
Added functionality to print event and event reference notes. issue #1335
2007-11-02 Stéphane Charette <stephanecharette@gmail.com>
* src/plugins/NarrativeWeb.py: issue #1340, do not display mime-types
in NarrativeWeb for image/*
2007-10-31 Jim Sack <jgsack@san.rr.com>
* src/Gramps.py In run(), skip error-dialog for things like
exit(0) such as used when processing command-line operations.
Add missing gtk.main_quit needed to terminate process
2007-10-29 Gary Burton <gary.burton@zen.co.uk>
* src/RelLib/_Person.py: setting the death index wrongly.
2007-10-29 Gary Burton <gary.burton@zen.co.uk>
* src/RelLib/_Person.py: reset birth and death indexes after deleting
an event. Fixes #1327
2007-10-28 Gary Burton <gary.burton@zen.co.uk>
* src/Editors/_EditPlace.py: fixed name of street MonitoredEntry
* src/Editors/_EditLocation.py: fixed name of street MonitoredEntry
MonitoredEntry field for street wrongly named as city.
Caused strange occasional drag and drop bug. issue #1304
2007-10-28 Gary Burton <gary.burton@zen.co.uk>
* src/DisplayTabs/_EnbeddedList.py: Fixed crash when doing a drag and
drop with an object that was deleted from a list. issue # 1326
2007-10-26 Stéphane Charette <stephanecharette@gmail.com>
* src/plugins/NarrativeWeb.py: various: EOL should be <br> not <p>,
date is now displayed in the user's locale, source references no
longer skipped on media pages, allow half-sibling to be shown, allow
columns to be configurable, event notes are no longer skipped, progress
indicator no longer gets stuck at 100% for long periods of time with
large databases
2007-10-26 Benny Malengier <benny.malengier@gramps-project.org>
* src/plugins/rel_nl.py: various improvements
2007-10-22 Benny Malengier <benny.malengier@gramps-project.org>
* src/DisplayTabs/_GalleryTab.py: remove edit_callback, works via signals now
2007-10-22 Benny Malengier <benny.malengier@gramps-project.org>
* src/DisplayTabs/_EmbeddedList.py: during rebuild, don't do select change
* src/DisplayTabs/_ButtonTab.py: avoid double call of selection_change
* src/DisplayTabs/_GrampsTab.py: method to add db connects, and set connects
* src/Editors/_EditPrimary.py: on add tab pass db connection method
* src/Editors/_EditSecondary.py: on add tab pass db connection method
* src/Editors/_EditReference.py: on add tab pass db connection method
* src/DisplayTabs/_GalleryTab.py: use new structure to correctly update
displaytab
2007-10-22 Benny Malengier <benny.malengier@gramps-project.org>
* src/GrampsDb/_GrampsInMemDB.py: xml load/save not working, fixed #1319
2007-10-21 Jim Sack <jgsack@san.rr.com>
* src/ansel_utf8.py: (see tracker issue #831) fix inoperative
Gedcom/ANSEL input & output somewhat following pattern of robocoder
patch, but with data corrections, additions, and testing. Rewrote code
functions ansel_to_utf8 and utf8_to_ansel. Added note that utf8
references (including function names) should be changed to unicode.
(This changelog accounts for the r9227 commit)
2007-10-21 Benny Malengier <benny.malengier@gramps-project.org>
* src/Editors/_EditPerson.py: If a family changes, rebuild family backref of all
open editors. issue #1309, causing corrupt database.
Also remove unneeded associations rebuild when family changes
2007-10-19 Piotr Czubaszek <pioterus@gmail.com>
* src/docgen/PdfDoc.py (PdfDoc.add_media_object): Missing period.
2007-10-19 Gary Burton <gary.burton@zen.co.uk>
* src/DisplayTabs/_EmbeddedList.py:
* src/DisplayTabs/_ButtonTab.py:
ENTER is edit on embedded lists, issue #1296
2007-10-19 Frank S. Thomas <frank@thomas-alfeld.de>
* src/glade/gramps.glade: Remove extra space.
2007-10-18 Stephane Charette <stephanecharette@gmail.com>
* configure.in: release 2.2.9, update version string to 2.2.10
2007-10-17 Stephane Charette <stephanecharette@gmail.com>
* NEWS: describe version 2.2.9
* configure.in: version 2.2.9
+6
View File
@@ -1,3 +1,9 @@
Version 2.2.10 -- the "Lemon Curry?" release
* fixes for several database corruption issues and crashes (Benny, Gary, Jim)
* fixes for Gedcom, ANSEL and XML import/export issues (Jim, Benny)
* translation updates (various: bg, de, fi, fr, lt, nb, nl, no)
* various small fixes to several reports (Stéphane, Gary, Benny)
Version 2.2.9 -- the "Here's your ninepence" release
* Many bug fixes & translation update (especially reports)
* Brazilian Portugese translation (Luiz)
-1516
View File
File diff suppressed because it is too large Load Diff
Vendored
-1622
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -4,16 +4,16 @@ 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.2.9, [gramps-bugs@lists.sourceforge.net])
AC_INIT(gramps, 2.2.11, [gramps-bugs@lists.sourceforge.net])
AC_CONFIG_SRCDIR(configure.in)
AM_INIT_AUTOMAKE(1.6.3)
AC_CONFIG_MACRO_DIR([m4])
GNOME_DOC_INIT
dnl RELEASE=0.SVN$(svnversion -n .)
RELEASE=0.SVN$(svnversion -n .)
dnl RELEASE=0rc1
RELEASE=1
dnl RELEASE=1
VERSIONSTRING=$VERSION
if test x"$RELEASE" != "x"
@@ -52,7 +52,7 @@ AC_SUBST(HELPPATH)
AC_SUBST(FONTPATH)
dnl Add the languages which your application supports here.
ALL_LINGUAS="hu zh_CN cs da de es fr it nb nl no pl pt_BR ro ru sv eo fi lt sk tr sl"
ALL_LINGUAS="hu zh_CN cs da de es fr it nb nl no pl pt_BR ro ru sv eo fi lt sk tr sl bg"
GETTEXT_PACKAGE=gramps
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define to the Gettext package name.])
+1 -1
View File
@@ -8,5 +8,5 @@ Type=Application
StartupNotify=true
Categories=GTK;Office;
X-GNOME-DocPath=gramps/gramps-manual.xml
MimeType=application/x-gramps;
MimeType=application/x-gramps;application/x-gedcom;application/x-gramps-package;application/x-gramps-xml
Exec=gramps %F
+13 -1
View File
@@ -52,7 +52,8 @@ DATABASE
-->
<!ELEMENT database (header, name-formats?, events?, people?, families?,
sources?, places?, objects?, repositories?, bookmark?)>
sources?, places?, objects?, repositories?,
bookmarks?, namemaps?)>
<!ATTLIST database xmlns CDATA #FIXED "http://gramps-project.org/xml/1.1.4/">
<!-- ************************************************************
@@ -315,6 +316,17 @@ BOOKMARKS
hlink IDREF #REQUIRED
>
<!-- ************************************************************
NAME MAPS
-->
<!ELEMENT namemaps (map)*>
<!ELEMENT map EMPTY>
<!ATTLIST map
type CDATA #REUIRED
key CDATA #REQUIRED
value CDATA #REQUIRED
>
<!-- ************************************************************
NAME FORMATS
-->
+13
View File
@@ -104,6 +104,11 @@
</element></zeroOrMore>
</element></optional>
<optional><element name="namemaps">
<zeroOrMore><element name="map">
<ref name="map-content"/>
</element></zeroOrMore>
</element></optional>
</element></start>
<define name="researcher-content">
@@ -451,6 +456,14 @@
<attribute name="hlink"><data type="IDREF"/></attribute>
</define>
<define name="map-content">
<attribute name="type"><choice>
<value>group_as</value>
</choice></attribute>
<attribute name="key"><text/></attribute>
<attribute name="value"><text/></attribute>
</define>
<define name="format-content">
<attribute name="number"><text/></attribute>
<attribute name="name"><text/></attribute>
+43
View File
@@ -1,3 +1,46 @@
2008-01-13 Boril Gourinov <boril.gourinov@gmail.com>
* bg.po: Translation update
2008-01-09 Lubo Vasko <pgval@inMail.sk>
* sk.po: Translation update
2008-01-09 Boril Gourinov <boril.gourinov@gmail.com>
* bg.po: Translation update
2008-01-08 Boril Gourinov <boril.gourinov@gmail.com>
* bg.po: Translation update
2008-01-07 Peter Landgren <peter.talken@telia.com>
* sv.po: Found 1 fuzzy. Improvments due to input from user
2008-01-06 Stéphane Charette <stephanecharette@gmail.com>
* POTFILES.in: added src/Mime/_WinMime.py and src/RelLib/_GrampsType.py
2008-01-06 Stéphane Charette <stephanecharette@gmail.com>
* gramps.pot: generate new grampt.pot prior to 2.2.10
2008-01-06 Arturas Sleinius <asleinius@users.sourceforge.net>
* lt.po: updated Lithuanian translation
2008-01-05 Erik De Richter <frederik;de.richter@pandora.be>
* nl.po: all strings translated gramps.pot 3/1/2008
2008-01-03 Mirko Leonhaeuser <mirko@leonhaeuser.de>
* de.po: update
2008-01-03 Jerome Rapinat <romjerome@yahoo.fr>
* fr.po: Translation update
2008-01-02 Boril Gourinov <boril.gourinov@gmail.com>
* bg.po: New language, bulgarian
2007-12-22 Espen Berg <espenbe@gmail.com>
* nb.po: Norwegian translation updated
* no.po: Norwegian translation updated
2007-12-15 Eero Tamminen <eerot@sf>
* fi_FI.po: väli->välillä, liitännäinen->laajennus, kerronnallinen->johdannolla
2007-10-15 Stephane Charette <stephanecharette@gmail.com>
* sl.po: contributed by Bernard Banko <bernard.banko@siol.net>
+2
View File
@@ -213,6 +213,7 @@ src/GrampsLogger/_RotateHandler.py
src/Mime/_GnomeMime.py
src/Mime/__init__.py
src/Mime/_PythonMime.py
src/Mime/_WinMime.py
# Models package
# src/Models/_FastFilterModel.py
@@ -361,6 +362,7 @@ src/RelLib/_Event.py
src/RelLib/_EventRef.py
src/RelLib/_Family.py
src/RelLib/_GenderStats.py
src/RelLib/_GrampsType.py
src/RelLib/__init__.py
src/RelLib/_LdsOrd.py
src/RelLib/_LdsOrdBase.py
+15648
View File
File diff suppressed because it is too large Load Diff
+713 -654
View File
File diff suppressed because it is too large Load Diff
+639 -596
View File
File diff suppressed because it is too large Load Diff
+15 -18
View File
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: fi\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-10-10 23:43-0700\n"
"PO-Revision-Date: 2007-10-15 00:25+0300\n"
"PO-Revision-Date: 2007-12-09 00:25+0300\n"
"Last-Translator: Eero Tamminen <eerot@sf>\n"
"Language-Team: <fi@li.org>\n"
"MIME-Version: 1.0\n"
@@ -245,7 +245,7 @@ msgstr "Noin"
#: ../src/DateEdit.py:83
msgid "Range"
msgstr "Väli"
msgstr "Välillä"
#: ../src/DateEdit.py:84
msgid "Span"
@@ -706,7 +706,7 @@ msgstr "Älä näytä varoitusta perumisesta kun tietoja on muutettu"
#: ../src/GrampsCfg.py:181
msgid "Show plugin status dialog on plugin load error"
msgstr "Näytä liitännäisten tila -dialogi kun liitännäisen lataaminen epäonnistuu"
msgstr "Näytä laajennusten tila -dialogi kun laajennusten lataaminen epäonnistuu"
#: ../src/GrampsCfg.py:192 ../src/GrampsLogger/_ErrorReportAssistant.py:47
#: ../src/RelLib/_MarkerType.py:47
@@ -1762,7 +1762,7 @@ msgstr "_Tietoja"
#: ../src/ViewManager.py:341
msgid "_Plugin status"
msgstr "_Liitännäisten tila"
msgstr "_Laajennusten tila"
#: ../src/ViewManager.py:343
msgid "_FAQ"
@@ -1863,7 +1863,7 @@ msgstr "Ladataan tiedostomuotoja..."
#: ../src/ViewManager.py:475
msgid "Loading plugins..."
msgstr "Ladataan liitännäisiä..."
msgstr "Ladataan laajennuksia..."
#: ../src/ViewManager.py:487
msgid "Ready"
@@ -2787,8 +2787,7 @@ msgstr "LaTeX"
#: ../src/docgen/LPRDoc.py:51
msgid "Cannot be loaded because python bindings for GNOME print are not installed"
msgstr ""
"Ei voida ladata, koska GNOME tulostuslaajennuksia ei ole asennettu Python-"
"tulkille"
"Ei voida ladata, koska GNOME tulostuslaajennuksia ei ole asennettu Python-tulkille"
#: ../src/docgen/LPRDoc.py:1206
msgid "Print Preview"
@@ -6850,7 +6849,7 @@ msgstr "Kohdehakemisto"
#: ../src/plugins/NarrativeWeb.py:3006
msgid "Narrative Web Site"
msgstr "Kerronnallinen www-sivusto"
msgstr "Www-sivusto johdannolla"
#: ../src/plugins/NarrativeWeb.py:3010
msgid "Generates web (HTML) pages for individuals, or a set of individuals."
@@ -7661,8 +7660,7 @@ msgstr "Tarkistaa tiedot käyttäjän määrittelemillä testeillä"
#: ../src/plugins/WriteCD.py:56
msgid "Cannot be loaded because python bindings for GNOME are not installed"
msgstr ""
"Lataaminen epäonnistui, koska GNOME laajennuksia Pythontulkille ei ole "
"asennettu"
"Lataaminen epäonnistui, koska GNOME laajennuksia Python-tulkille ei ole asennettu"
#: ../src/plugins/WriteCD.py:77
msgid "Export to CD"
@@ -7830,13 +7828,12 @@ msgstr "Avaa valittu työkalu"
#: ../src/PluginUtils/_Plugins.py:435
msgid "Reload plugins"
msgstr "Uudelleenlataa liitännäiset"
msgstr "Uudelleenlataa laajennukset"
#: ../src/PluginUtils/_Plugins.py:436
msgid "Attempt to reload plugins. Note: This tool itself is not reloaded!"
msgstr ""
"Yrittää uudelleenladata liitännäiset. Huom. Työkalua itseään ei "
"uudelleenladata!"
"Yrittää uudelleenladata laajennukset. Huom: Uudelleenlataustyökalua ei uudelleenladata!"
#: ../src/PluginUtils/_Tool.py:68
msgid "Debug"
@@ -7885,7 +7882,7 @@ msgstr "_Jatka työkalun käyttöä"
#: ../src/PluginUtils/_PluginStatus.py:57
#: ../src/PluginUtils/_PluginStatus.py:129
msgid "Plugin Status"
msgstr "Liitännäisten tila"
msgstr "Laajennusten tila"
#: ../src/PluginUtils/_PluginStatus.py:79
msgid "File"
@@ -14093,7 +14090,7 @@ msgstr "GeneWeb lähdetiedosto"
#: ../data/gramps.schemas.in.h:1
msgid "Automatically pop plugin status window"
msgstr "Näytä automaattisesti liitännäisten tilaikkuna"
msgstr "Näytä automaattisesti laajennusten tilaikkuna"
#: ../data/gramps.schemas.in.h:2
msgid "Backup database on exit"
@@ -14328,8 +14325,8 @@ msgid ""
"If set to 1, Plugin Status Window will pop automatically when problems are "
"detected on plugins load and reload."
msgstr ""
"Jos asetettu arvoon 1, liitännäisten tilaikkuna aukeaa automaattisesti kun "
"liitännäisten (uudelleen)lataamisessa havaitaan ongelmia."
"Jos asetettu arvoon 1, laajennusten tilaikkuna aukeaa automaattisesti kun "
"laajennusten (uudelleen) lataamisessa havaitaan ongelmia."
#: ../data/gramps.schemas.in.h:57
msgid "If set to 1, Tip of the Day will be displayed on startup."
@@ -15356,7 +15353,7 @@ msgid ""
"gramps-project.org"
msgstr ""
"Edistyneemmät käyttäjät voivat luoda omia erikoisraporttejaan kirjoittamalla "
"sitä varten GRAMPS &quot;liitännäisen&quot;. Enemmän tietoja "
"sitä varten GRAMPS &quot;laajennuksen&quot;. Enemmän tietoja "
"erikoisraporteista löytyy osoitteesta http://developers.gramps-project.org"
#: ../src/data/tips.xml.in.h:36
+1083 -1675
View File
File diff suppressed because it is too large Load Diff
+636 -589
View File
File diff suppressed because it is too large Load Diff
+699 -651
View File
File diff suppressed because it is too large Load Diff
+1243 -2801
View File
File diff suppressed because it is too large Load Diff
+640 -582
View File
File diff suppressed because it is too large Load Diff
+1243 -2801
View File
File diff suppressed because it is too large Load Diff
+3441 -1620
View File
File diff suppressed because it is too large Load Diff
+852 -808
View File
File diff suppressed because it is too large Load Diff
+17 -2
View File
@@ -58,7 +58,14 @@ import Mime
import GrampsDisplay
import ManagedWindow
#-------------------------------------------------------------------------
#
# global variables
#
#-------------------------------------------------------------------------
_last_directory = None
_relative_path = False
#-------------------------------------------------------------------------
#
@@ -97,6 +104,7 @@ class AddMediaObject(ManagedWindow.ManagedWindow):
self.internal = self.glade.get_widget('internal')
self.internal.connect('toggled', self.internal_toggled)
self.relpath = self.glade.get_widget('relpath')
self.relpath.set_active(_relative_path)
self.temp_name = ""
self.object = None
@@ -120,7 +128,7 @@ class AddMediaObject(ManagedWindow.ManagedWindow):
Callback function called with the save button is pressed.
A new media object is created, and added to the database.
"""
global _last_directory
global _last_directory, _relative_path
description = unicode(self.description.get_text())
@@ -130,6 +138,12 @@ class AddMediaObject(ManagedWindow.ManagedWindow):
mobj.set_handle(Utils.create_id())
mobj.set_mime_type(None)
else:
if self.file_text.get_filename() is None:
msgstr = _("Import failed")
msgstr2 = _("The filename supplied could not be found.")
ErrorDialog(msgstr, msgstr2)
return
filename = Utils.get_unicode_path(self.file_text.get_filename())
full_file = filename
@@ -154,7 +168,8 @@ class AddMediaObject(ManagedWindow.ManagedWindow):
mobj.set_mime_type(mtype)
name = filename
mobj.set_path(name)
_last_directory = os.path.dirname(filename)
_last_directory = os.path.dirname(full_file)
_relative_path = self.relpath.get_active()
mobj.set_handle(Utils.create_id())
if not mobj.get_gramps_id():
+2 -2
View File
@@ -559,8 +559,8 @@ class ArgHandler:
gw = GrampsDb.GedcomWriter(self.state.db,None,1,filename)
ret = gw.export_data(filename)
except:
print "Error exporting %s" % filename
sys._xit(msg)
msg = "Error exporting %s" % filename
sys.exit(msg)
elif format == 'gramps-xml':
filename = os.path.normpath(os.path.abspath(filename))
if filename:
+1
View File
@@ -104,6 +104,7 @@ class Bookmarks :
if self.active != DISABLED:
self.uistate.uimanager.remove_ui(self.active)
self.uistate.uimanager.remove_action_group(self.action_group)
self.action_group = gtk.ActionGroup('Bookmarks')
self.active = DISABLED
def redraw_and_report_change(self):
+2 -1
View File
@@ -1080,7 +1080,8 @@ class RelationshipView(PageView.PersonNavView):
phandle = self.dbstate.get_active_person().handle
person = self.dbstate.db.get_person_from_handle(phandle)
skip = set(person.get_family_handle_list())
skip = set(person.get_family_handle_list() +
person.get_parent_family_handle_list())
dialog = SelectFamily(self.dbstate, self.uistate, skip=skip)
family = dialog.run()
+1 -1
View File
@@ -191,7 +191,7 @@ class DateDisplayFR(DateDisplay):
formats = (
"AAAA-MM-JJ (ISO)", "Numérique", "Mois Jour, Année",
"MOI Jour, Année", "Jour Mois, Année", "Jour MOI Année"
"MOI Jour, Année", "Jour. Mois Année", "Jour. MOI Année"
)
def _display_gregorian(self,date_val):
+8
View File
@@ -160,3 +160,11 @@ class BackRefList(EmbeddedList):
EditEvent(self.dbstate, self.uistate, [], event)
except Errors.WindowActiveError:
pass
elif reftype == 'Repository':
try:
from Editors import EditRepository
repo = self.dbstate.db.get_repository_from_handle(ref)
EditRepository(self.dbstate, self.uistate, [], repo)
except Errors.WindowActiveError:
pass
+5
View File
@@ -87,6 +87,11 @@ class BackRefModel(gtk.ListStore):
name = p.get_title()
gid = p.gramps_id
handle = p.handle
elif dtype == 'Repository':
p = self.db.get_repository_from_handle(ref[1])
name = p.get_name()
gid = p.gramps_id
handle = p.handle
else:
p = self.db.get_object_from_handle(ref[1])
name = p.get_description()
+20
View File
@@ -43,6 +43,9 @@ from GrampsWidgets import SimpleButton
from _GrampsTab import GrampsTab
import Errors
_KP_ENTER = gtk.gdk.keyval_from_name("KP_Enter")
_RETURN = gtk.gdk.keyval_from_name("Return")
#-------------------------------------------------------------------------
#
# Classes
@@ -79,6 +82,7 @@ class ButtonTab(GrampsTab):
@param name: Notebook label name
@type name: str/unicode
"""
self.dirty_selection = False
GrampsTab.__init__(self,dbstate, uistate, track, name)
self.tooltips = gtk.Tooltips()
self.create_buttons(share_button)
@@ -130,6 +134,18 @@ class ButtonTab(GrampsTab):
except Errors.WindowActiveError:
pass
def key_pressed(self, obj, event):
"""
Handles the return key being pressed on list. If the key is pressed,
the Edit button handler is called
"""
if event.type == gtk.gdk.KEY_PRESS and \
event.keyval in (_RETURN, _KP_ENTER):
try:
self.edit_button_clicked(obj)
except Errors.WindowActiveError:
pass
def add_button_clicked(self, obj):
"""
Function called with the Add button is clicked. This function
@@ -167,6 +183,10 @@ class ButtonTab(GrampsTab):
"""
# Comparing to None is important, as empty strings
# and 0 can be returned
# This method is called as callback on change, and can be called
# explicitly, dirty_selection must make sure they do not interact
if self.dirty_selection:
return
if self.get_selected() != None:
self.edit_btn.set_sensitive(True)
if not self.dbstate.db.readonly:
+6 -1
View File
@@ -199,7 +199,7 @@ class EmbeddedList(ButtonTab):
# if the is same object, we have a move, otherwise,
# it is a standard drag-n-drop
if id(self) == selfid:
if id(self) == selfid and self.get_selected() is not None:
self._move(row_from, row, obj)
else:
self._handle_drag(row, obj)
@@ -263,6 +263,7 @@ class EmbeddedList(ButtonTab):
self.tree.set_reorderable(True)
self.tree.set_rules_hint(True)
self.tree.connect('button_press_event', self.double_click)
self.tree.connect('key_press_event', self.key_pressed)
# create the scrolled window, and attach the treeview
scroll = gtk.ScrolledWindow()
@@ -353,6 +354,8 @@ class EmbeddedList(ButtonTab):
Rebuilds the data in the database by creating a new model,
using the build_model function passed at creation time.
"""
#during rebuild, don't do _selection_changed
self.dirty_selection = True
try:
self.model = self.build_model(self.get_data(), self.dbstate.db)
except AttributeError, msg:
@@ -362,4 +365,6 @@ class EmbeddedList(ButtonTab):
self.tree.set_model(self.model)
self._set_label()
#model and tree are reset, allow _selection_changed again, and force it
self.dirty_selection = False
self._selection_changed()
+31 -16
View File
@@ -78,9 +78,12 @@ class GalleryTab(ButtonTab):
self.rebuild()
self.show_all()
#connect external remove of object to rebuild
self.dbstate.db.connect('media-delete',self.media_delete)
def connect_db_signals(self):
#connect external remove/change of object to rebuild of grampstab
self._add_db_signal('media-delete', self.media_delete)
self._add_db_signal('media-rebuild', self.rebuild)
self._add_db_signal('media-update', self.media_update)
def double_click(self, obj, event):
"""
@@ -291,14 +294,10 @@ class GalleryTab(ButtonTab):
from Editors import EditMediaRef
EditMediaRef(self.dbstate, self.uistate, self.track,
obj, ref, self.edit_callback)
obj, ref, None)
except Errors.WindowActiveError:
pass
def edit_callback(self, media_ref, ref):
self.changed = True
self.rebuild()
def media_delete(self, del_media_handle_list):
"""
Outside of this tab media objects have been deleted. Check if tab
@@ -306,18 +305,34 @@ class GalleryTab(ButtonTab):
Note: delete of object will cause reference on database to be removed,
so this method need not do this
"""
rebuild = False
ref_handles = [x.ref for x in self.media_list]
for handle in del_media_handle_list :
pos = None
try :
pos = ref_handles.index(handle)
except ValueError :
continue
while 1:
pos = None
try :
pos = ref_handles.index(handle)
except ValueError :
break
if pos is not None:
#oeps, we need to remove this reference, and rebuild tab
self.media_list.remove(self.media_list[pos])
if pos is not None:
#oeps, we need to remove this reference, and rebuild tab
del self.media_list[pos]
del ref_handles[pos]
rebuild = True
if rebuild:
self.rebuild()
def media_update(self, upd_media_handle_list):
"""
Outside of this tab media objects have been changed. Check if tab
and object must be changed.
"""
ref_handles = [x.ref for x in self.media_list]
for handle in upd_media_handle_list :
if handle in ref_handles:
self.rebuild()
break
def _set_dnd(self):
"""
+23
View File
@@ -66,6 +66,8 @@ class GrampsTab(gtk.HBox):
self.track = track
self.changed = False
self._add_db_signal = None
# save name used for notebook label, and build the widget used
# for the label
@@ -135,6 +137,27 @@ class GrampsTab(gtk.HBox):
"""
return self.label_container
def add_db_signal_callback(self, add_db_signal):
"""
The grampstab must be able to react to database signals, however
on destroy of the editor to which the tab is attached, these signals
must be disconnected.
This method sets the method with which to add database signals on tabs,
typically EditPrimary and EditSecondary add tabs, and have methods to
connect signals and register them so they are correctly disconnected
on close
"""
self._add_db_signal = add_db_signal
self.connect_db_signals()
def connect_db_signals(self):
"""
Function to connect db signals to GrampsTab methods. This function
should be overridden in the derived class.
It is called when the add_db_signal method is added.
"""
pass
def _set_label(self):
"""
Updates the label based of if the tab contains information. Tabs
+9
View File
@@ -898,6 +898,15 @@ class EditFamily(EditPrimary):
else:
self.db.commit_family(self.obj, trans)
self.db.transaction_commit(trans, _("Edit Family"))
else:
# Signal an update to allow other windows that use family data to
# refresh. The family-update signal is normally only emitted when
# the family record itself changes, however the Relationship view
# needs to know to refresh when related data such as the marriage
# event may have been altered.
# Bug #1416
self.db.emit('family-update', ([],))
self.close()
+1 -1
View File
@@ -59,7 +59,7 @@ class EditLocation(EditSecondary):
_('Location Editor'))
def _setup_fields(self):
self.city = MonitoredEntry(
self.street = MonitoredEntry(
self.top.get_widget("street"),
self.obj.set_street,
self.obj.get_street,
+27 -12
View File
@@ -165,20 +165,36 @@ class EditPerson(EditPrimary):
self._add_db_signal('family-update', self.family_change)
self._add_db_signal('family-add', self.family_change)
def family_change(self, handle_list):
flist = self.obj.get_family_handle_list() + self.obj.get_parent_family_handle_list()
for handle in handle_list:
if handle in flist:
self._update_families()
return
def family_change(self, handle_list=[]):
"""Callback for family change signals. This should rebuild the
backreferences to family in person when:
1)a family the person is parent of changes. Person could have
been removed
2)a family the person is child in changes. Child could have been
removed
3)a family is changed. The person could be added as child or
parent
"""
#As this would be an extensive check, we choose the easy path and
# rebuild family backreferences on all family changes
##flist = self.obj.get_family_handle_list() + \
## self.obj.get_parent_family_handle_list()
##for handle in handle_list:
## if handle in flist:
## self._update_families()
## return
self._update_families()
def _update_families(self):
phandle = self.obj.get_handle()
person = self.dbstate.db.get_person_from_handle(phandle)
self.obj.set_family_handle_list(person.get_family_handle_list())
self.obj.set_parent_family_handle_list(person.get_parent_family_handle_list())
self.person_ref_list.data = self.obj.get_person_ref_list()
self.person_ref_list.rebuild()
if phandle:
person = self.dbstate.db.get_person_from_handle(phandle)
self.obj.set_family_handle_list(person.get_family_handle_list())
self.obj.set_parent_family_handle_list(person.get_parent_family_handle_list())
#self.person_ref_list.data = self.obj.get_person_ref_list()
#self.person_ref_list.rebuild()
def _setup_fields(self):
"""
@@ -385,7 +401,6 @@ class EditPerson(EditPrimary):
the updating image on the main form which has just been modified.
"""
self.load_photo(obj.get_path())
self.gallery_tab.edit_callback(ref, obj)
def _image_button_press(self, obj, event):
"""
+1 -1
View File
@@ -93,7 +93,7 @@ class EditPlace(EditPrimary):
self.obj.set_title, self.obj.get_title,
self.db.readonly)
self.city = MonitoredEntry(
self.street = MonitoredEntry(
self.top.get_widget("street"),
mloc.set_street, mloc.get_street, self.db.readonly)
+1
View File
@@ -99,6 +99,7 @@ class EditPrimary(ManagedWindow.ManagedWindow):
def _add_tab(self,notebook,page):
notebook.insert_page(page, page.get_tab_widget())
page.add_db_signal_callback(self._add_db_signal)
return page
def _cleanup_on_exit(self):
+1
View File
@@ -100,6 +100,7 @@ class EditReference(ManagedWindow.ManagedWindow):
def _add_tab(self,notebook,page):
notebook.insert_page(page, page.get_tab_widget())
page.add_db_signal_callback(self._add_db_signal)
return page
def _add_db_signal(self, name, callback):
+1
View File
@@ -96,6 +96,7 @@ class EditSecondary(ManagedWindow.ManagedWindow):
def _add_tab(self,notebook,page):
notebook.insert_page(page, page.get_tab_widget())
page.add_db_signal_callback(self._add_db_signal)
return page
def _cleanup_on_exit(self):
+1 -1
View File
@@ -79,7 +79,7 @@ class PlaceSidebarFilter(SidebarFilter):
self.on_filters_changed('Place')
self.add_text_entry(_('ID'), self.filter_id)
self.add_text_entry(_('Name'), self.filter_title)
self.add_text_entry(_('Place Name'), self.filter_title)
self.add_text_entry(_('Church parish'), self.filter_parish)
self.add_text_entry(_('Zip/Postal code'), self.filter_zip)
self.add_text_entry(_('City'), self.filter_city)
+8 -2
View File
@@ -242,7 +242,7 @@ def db_copy(from_db,to_db,callback):
}
# Start batch transaction to use async TXN and other tricks
trans = to_db.transaction_begin("",batch=True)
trans = to_db.transaction_begin("", batch=True)
for table_name in tables.keys():
cursor_func = tables[table_name]['cursor_func']
@@ -259,8 +259,14 @@ def db_copy(from_db,to_db,callback):
uc.update()
cursor.close()
# Copy name grouping
group_map = from_db.get_name_group_keys()
for key in group_map:
value = from_db.get_name_group_mapping(key)
to_db.set_name_group_mapping(key, value)
# Commit batch transaction: does nothing, except undoing the tricks
to_db.transaction_commit(trans,"")
to_db.transaction_commit(trans, "")
# Copy bookmarks over:
# we already know that there's no overlap in handles anywhere
+41 -9
View File
@@ -337,7 +337,8 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback):
# These env settings are only needed for Txn environment
self.env.set_lk_max_locks(25000)
self.env.set_lk_max_objects(25000)
self.env.set_flags(db.DB_LOG_AUTOREMOVE,1) # clean up unused logs
self.set_auto_remove()
# The DB_PRIVATE flag must go if we ever move to multi-user setup
env_flags = db.DB_CREATE|db.DB_PRIVATE|\
@@ -399,8 +400,16 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback):
dbtype=db.DB_BTREE)
callback(37)
self._load_metadata()
self.name_group = db.DB(self.env)
self.name_group.set_flags(db.DB_DUP)
if self.readonly:
self.name_group.open(self.full_name, "name_group",
db.DB_HASH, flags=db.DB_RDONLY)
else:
self.name_group.open(self.full_name, "name_group",
db.DB_HASH, flags=self.open_flags())
self._load_metadata()
gstats = self.metadata.get('gender_stats',default=None)
if not self.readonly:
@@ -529,11 +538,6 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback):
self.surnames.open(self.full_name, "surnames", db.DB_BTREE,
flags=table_flags)
self.name_group = db.DB(self.env)
self.name_group.set_flags(db.DB_DUP)
self.name_group.open(self.full_name, "name_group",
db.DB_HASH, flags=table_flags)
self.id_trans = db.DB(self.env)
self.id_trans.set_flags(db.DB_DUP)
self.id_trans.open(self.full_name, "idtrans",
@@ -1117,6 +1121,7 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback):
self.media_map = None
self.event_map = None
self.surnames = None
self.name_group = None
self.env = None
self.metadata = None
self.db_is_open = False
@@ -1382,7 +1387,8 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback):
if transaction.batch:
if self.UseTXN:
self.env.txn_checkpoint()
self.env.set_flags(db.DB_TXN_NOSYNC,1) # async txn
if db.version() < (4, 7):
self.env.set_flags(db.DB_TXN_NOSYNC, 1) # async txn
if self.secondary_connected and not transaction.no_magic:
# Disconnect unneeded secondary indices
@@ -1422,7 +1428,8 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback):
if transaction.batch:
if self.UseTXN:
self.env.txn_checkpoint()
self.env.set_flags(db.DB_TXN_NOSYNC,0) # sync txn
if db.version() < (4, 7):
self.env.set_flags(db.DB_TXN_NOSYNC, 0) # sync txn
if not transaction.no_magic:
# create new secondary indices to replace the ones removed
@@ -1494,6 +1501,31 @@ class GrampsBSDDB(GrampsDbBase,UpdateCallback):
db_map.put(handle,data,txn=self.txn)
self.emit(signal,([handle],))
def set_auto_remove(self):
"""
BSDDB change log settings using new method with renamed attributes
"""
if db.version() < (4, 7):
# by the book: old method with old attribute
self.env.set_flags(db.DB_LOG_AUTOREMOVE, 1)
else: # look at python pybsddb interface, should also be 4.7+
# TODO test with new version of pybsddb
try:
# try numeric compare, just first 2 digits
# this won't work with something like "4.10a", but
# hopefully they won't do that
old_version = map(int, db.__version__.split(".",2)[:2]) < (4, 7)
except:
# fallback, weak string compare
old_version = db.__version__ < "4.7"
if old_version:
# undocumented: old method with new attribute
self.env.set_flags(db.DB_LOG_AUTO_REMOVE, 1)
else:
# by the book: new method with new attribute
self.env.log_set_config(db.DB_LOG_AUTO_REMOVE, 1)
def gramps_upgrade(self,callback=None):
UpdateCallback.__init__(self,callback)
+6
View File
@@ -1135,6 +1135,12 @@ class GrampsDbBase(GrampsDBCallback):
"""
return [unicode(k) for k in self.name_group.keys()]
def has_name_group_key(self, name):
"""
Return if a key exists in the name_group table
"""
return self.name_group.has_key(str(name))
def set_name_group_mapping(self, name, group):
"""
Sets the default grouping name for a surname. Needs to be overridden
+5 -1
View File
@@ -257,7 +257,11 @@ class GrampsInMemDB(GrampsDbBase):
old_id = old_data[self.ID_INDEX]
if old_id is not None and obj.gramps_id != old_id:
del trans_map[old_id]
trans_map[gid] = obj.handle
#on load of xml for backref that are encountered before object exists,
#the object is created empty with gid None. Do not add this to
#trans_map. Broken ref will then also not be exported (good!)
if gid is not None:
trans_map[gid] = obj.handle
return True
def commit_person(self,person,transaction,change_time=None):
+2 -1
View File
@@ -451,7 +451,8 @@ class Reader:
while len(self.current_list) < 5:
old_line = self.f.readline()
self.index += 1
line = old_line.strip('\r\n')
# space ensures no trailing space at end-of-line
line = old_line.strip(' \r\n')
if line == "" and line != old_line:
continue
if line == "":
+16
View File
@@ -196,6 +196,22 @@ def importData(database, filename, callback=None,cl=0,use_trans=True):
database.media_bookmarks.append_list(other_database.media_bookmarks.get())
database.repo_bookmarks.append_list(other_database.repo_bookmarks.get())
# Copy grouping table
group_map = other_database.get_name_group_keys()
name_len = len(group_map)
if name_len > 0:
for key in group_map:
value = other_database.get_name_group_mapping(key)
if database.has_name_group_key(key) :
present = database.get_name_group_mapping(key)
if not value == present:
msg = _("Your database groups name %s together"
" with %s, did not change this grouping to %s") % (
key, present, value)
print msg
else:
database.set_name_group_mapping(key, value)
# close the other database and clean things up
other_database.close()
+33 -9
View File
@@ -27,11 +27,14 @@
#-------------------------------------------------------------------------
import os
import sys
import sets
import shutil
from xml.parsers.expat import ExpatError, ParserCreate
from gettext import gettext as _
import re
try:
set()
except NameError:
from sets import Set as set
#------------------------------------------------------------------------
#
@@ -276,7 +279,7 @@ class GrampsParser(UpdateCallback):
self.childref_map = {}
self.change = change
self.dp = DateHandler.parser
self.place_names = sets.Set()
self.place_names = set()
cursor = database.get_place_cursor()
data = cursor.next()
while data:
@@ -393,8 +396,10 @@ class GrampsParser(UpdateCallback):
"gender" : (None, self.stop_gender),
"header" : (None, None),
"last" : (self.start_last, self.stop_last),
"map" : (self.start_namemap, None),
"mother" : (self.start_mother,None),
"name" : (self.start_name, self.stop_name),
"namemaps" : (None, None),
"nick" : (None, self.stop_nick),
"note" : (self.start_note, self.stop_note),
"p" : (None, self.stop_ptag),
@@ -451,6 +456,9 @@ class GrampsParser(UpdateCallback):
"rname" : (None, self.stop_rname),
}
def errmsg(self, msg):
log.warning(msg)
def find_person_by_gramps_id(self,gramps_id):
intid = self.gid2id.get(gramps_id)
if intid:
@@ -855,31 +863,31 @@ class GrampsParser(UpdateCallback):
# Make sure those are filtered out.
# Bookmarks are at end, so all handle must exist before we do bookmrks
if target == 'person':
if (self.db.find_person_from_handle(handle,self.trans) is not None
if (self.db.get_person_from_handle(handle) is not None
and handle not in self.db.bookmarks.get() ):
self.db.bookmarks.append(handle)
elif target == 'family':
if (self.db.find_family_from_handle(handle,self.trans) is not None
if (self.db.get_family_from_handle(handle) is not None
and handle not in self.db.family_bookmarks.get() ):
self.db.family_bookmarks.append(handle)
elif target == 'event':
if (self.db.find_event_from_handle(handle,self.trans) is not None
if (self.db.get_event_from_handle(handle) is not None
and handle not in self.db.event_bookmarks.get() ):
self.db.event_bookmarks.append(handle)
elif target == 'source':
if (self.db.find_source_from_handle(handle,self.trans) is not None
if (self.db.get_source_from_handle(handle) is not None
and handle not in self.db.source_bookmarks.get() ):
self.db.source_bookmarks.append(handle)
elif target == 'place':
if (self.db.find_place_from_handle(handle,self.trans) is not None
if (self.db.get_place_from_handle(handle) is not None
and handle not in self.db.place_bookmarks.get() ):
self.db.place_bookmarks.append(handle)
elif target == 'media':
if (self.db.find_object_from_handle(handle,self.trans) is not None
if (self.db.get_object_from_handle(handle) is not None
and handle not in self.db.media_bookmarks.get() ):
self.db.media_bookmarks.append(handle)
elif target == 'repository':
if (self.db.find_repository_from_handle(handle,self.trans)
if (self.db.get_repository_from_handle(handle)
is not None and handle not in self.db.repo_bookmarks.get()):
self.db.repo_bookmarks.append(handle)
@@ -1112,6 +1120,22 @@ class GrampsParser(UpdateCallback):
except KeyError:
pass
def start_namemap(self, attrs):
type = attrs.get('type')
key = attrs['key']
value = attrs['value']
if type == 'group_as':
if self.db.has_name_group_key(key) :
present = self.db.get_name_group_mapping(key)
if not value == present:
msg = _("Your database groups name %s together"
" with %s, did not change this grouping to %s") % (
key, present, value)
self.errmsg(msg)
else:
self.db.set_name_group_mapping(key, value)
def start_last(self,attrs):
self.name.prefix = attrs.get('prefix','')
self.name.group_as = attrs.get('group','')
+3 -3
View File
@@ -124,7 +124,7 @@ lds_ord_name = {
RelLib.LdsOrd.BAPTISM : 'BAPL',
RelLib.LdsOrd.ENDOWMENT : 'ENDL',
RelLib.LdsOrd.SEAL_TO_PARENTS : 'SLGC',
RelLib.LdsOrd.SEAL_TO_SPOUSE : 'SGLS',
RelLib.LdsOrd.SEAL_TO_SPOUSE : 'SLGS',
RelLib.LdsOrd.CONFIRMATION : 'CONL',
}
@@ -883,7 +883,7 @@ class GedcomWriter(UpdateCallback):
nickname = ""
if restricted and self.living:
primaryname = RelLib.Name (primaryname)
primaryname.set_first_name ("Living")
primaryname.set_first_name (_("Living"))
#nickname = ""
else:
primaryname = person.get_primary_name ()
@@ -1449,7 +1449,7 @@ class GedcomWriter(UpdateCallback):
return
basename = os.path.basename(path)
dest = os.path.join (imgdir, basename)
if dest != path:
if not os.path.samefile(dest,path):
try:
shutil.copyfile(path, dest)
shutil.copystat(path, dest)
+24 -2
View File
@@ -321,9 +321,22 @@ class XmlWriter(UpdateCallback):
# Data is written, now write bookmarks.
self.write_bookmarks()
self.write_namemaps()
self.g.write("</database>\n")
def write_namemaps(self):
group_map = self.db.get_name_group_keys()
name_len = len(group_map)
if name_len > 0:
self.g.write(" <namemaps>\n")
for key in group_map:
value = self.db.get_name_group_mapping(key)
self.g.write(' <map type="group_as" key="%s" value="%s"/>\n'
% (key, value) )
self.g.write(" </namemaps>\n")
def write_bookmarks(self):
bm_person_len = len(self.db.bookmarks.get())
bm_family_len = len(self.db.family_bookmarks.get())
@@ -713,6 +726,15 @@ class XmlWriter(UpdateCallback):
self.g.write('%s<%s>%s</%s>\n' %
(' '*indent,tagname,self.fix(value),tagname))
def write_line_nofix(self,tagname,value,indent=1):
'''Writes a line, but does not escape characters.
Use this instead of write_line is the value is already fixed,
this avoids &amp; becoming &amp;amp;
'''
if value:
self.g.write('%s<%s>%s</%s>\n' %
(' '*indent, tagname, value, tagname))
def get_iso_date(self,date):
if date[2] == 0:
y = "????"
@@ -1011,8 +1033,8 @@ class XmlWriter(UpdateCallback):
note = place.get_note()
if title == "":
title = self.fix(self.build_place_title(place.get_main_location()))
self.write_line("ptitle",title,index+1)
title = self.build_place_title(place.get_main_location())
self.write_line_nofix("ptitle",title,index+1)
if longitude or lat:
self.g.write('%s<coord long="%s" lat="%s"/>\n'
+1 -1
View File
@@ -370,7 +370,7 @@ class MonitoredEntry:
self.obj.grab_focus()
def update(self):
if self.get_val():
if self.get_val() is not None:
self.obj.set_text(self.get_val())
class MonitoredText:
+1 -1
View File
@@ -218,7 +218,7 @@ class Event(SourceBase, NoteBase, MediaBase, AttributeBase,
@return: Returns the list of objects refereincing primary objects.
@rtype: list
"""
return self.media_list + self.source_list
return self.get_sourcref_child_list() + self.source_list
def is_empty(self):
"""
+52 -2
View File
@@ -105,7 +105,7 @@ class EventRef(SecondaryObject, PrivacyBase, NoteBase, AttributeBase, RefBase):
@return: Returns the list of child objects that may carry textual data.
@rtype: list
"""
check_list = self.attribute_list[:]
check_list = self.attribute_list
if self.note:
check_list.append(self.note)
return check_list
@@ -117,7 +117,7 @@ class EventRef(SecondaryObject, PrivacyBase, NoteBase, AttributeBase, RefBase):
@return: Returns the list of child secondary child objects that may refer sources.
@rtype: list
"""
return self.attribute_list[:]
return self.attribute_list
def get_referenced_handles(self):
"""
@@ -132,6 +132,56 @@ class EventRef(SecondaryObject, PrivacyBase, NoteBase, AttributeBase, RefBase):
else:
return []
def get_handle_referents(self):
"""
Returns the list of child objects which may, directly or through
their children, reference primary objects..
@return: Returns the list of objects refereincing primary objects.
@rtype: list
"""
return self.get_sourcref_child_list()
def has_source_reference(self, src_handle) :
"""
Returns True if any of the child objects has reference
to this source handle.
@param src_handle: The source handle to be checked.
@type src_handle: str
@return: Returns whether any of it's child objects has reference to this source handle.
@rtype: bool
"""
for item in self.get_sourcref_child_list():
if item.has_source_reference(src_handle):
return True
return False
def remove_source_references(self, src_handle_list):
"""
Removes references to all source handles in the list
in all child objects.
@param src_handle_list: The list of source handles to be removed.
@type src_handle_list: list
"""
for item in self.get_sourcref_child_list():
item.remove_source_references(src_handle_list)
def replace_source_references(self, old_handle, new_handle):
"""
Replaces references to source handles in the list
in this object and all child objects.
@param old_handle: The source handle to be replaced.
@type old_handle: str
@param new_handle: The source handle to replace the old one with.
@type new_handle: str
"""
for item in self.get_sourcref_child_list():
item.replace_source_references(old_handle, new_handle)
def get_role(self):
"""
Returns the tuple corresponding to the preset role.
+14 -5
View File
@@ -223,6 +223,10 @@ class Person(SourceBase, NoteBase, AttributeBase, MediaBase,
def _remove_handle_references(self, classname, handle_list):
if classname == 'Event':
# Keep a copy of the birth and death references
birth_ref = self.get_birth_ref()
death_ref = self.get_death_ref()
new_list = [ref for ref in self.event_ref_list
if ref.ref not in handle_list]
# If deleting removing the reference to the event
@@ -236,6 +240,12 @@ class Person(SourceBase, NoteBase, AttributeBase, MediaBase,
in handle_list):
self.death_ref_index = -1
self.event_ref_list = new_list
# Reset the indexes after deleting the event from even_ref_list
if (self.birth_ref_index != -1):
self.set_birth_ref(birth_ref)
if (self.death_ref_index != -1):
self.set_death_ref(death_ref)
elif classname == 'Person':
new_list = [ref for ref in self.person_ref_list
if ref.ref not in handle_list]
@@ -314,7 +324,7 @@ class Person(SourceBase, NoteBase, AttributeBase, MediaBase,
return [self.primary_name] + self.media_list + \
self.alternate_names + self.address_list + \
self.attribute_list + self.lds_ord_list + \
self.person_ref_list
self.person_ref_list + self.event_ref_list
def get_referenced_handles(self):
"""
@@ -335,8 +345,7 @@ class Person(SourceBase, NoteBase, AttributeBase, MediaBase,
@return: Returns the list of objects refereincing primary objects.
@rtype: list
"""
return self.get_sourcref_child_list() + self.source_list \
+ self.event_ref_list
return self.get_sourcref_child_list() + self.source_list
def set_primary_name(self, name):
"""
@@ -428,7 +437,7 @@ class Person(SourceBase, NoteBase, AttributeBase, MediaBase,
"""
if event_ref and not isinstance(event_ref, EventRef):
raise ValueError("Expecting EventRef instance")
if event_ref == None:
if event_ref is None:
self.birth_ref_index = -1
return
# check whether we already have this ref in the list
@@ -451,7 +460,7 @@ class Person(SourceBase, NoteBase, AttributeBase, MediaBase,
"""
if event_ref and not isinstance(event_ref, EventRef):
raise ValueError("Expecting EventRef instance")
if event_ref == None:
if event_ref is None:
self.death_ref_index = -1
return
# check whether we already have this ref in the list
+27 -2
View File
@@ -100,6 +100,25 @@ class Repository(NoteBase, AddressBase, UrlBase, PrimaryObject):
check_list.append(self.note)
return check_list
def get_sourcref_child_list(self):
"""
Returns the list of child secondary objects that may refer sources.
@return: Returns the list of child secondary child objects that may refer sources.
@rtype: list
"""
return self.address_list
def get_handle_referents(self):
"""
Returns the list of child objects which may, directly or through
their children, reference primary objects.
@return: Returns the list of objects refereincing primary objects.
@rtype: list
"""
return self.address_list
def has_source_reference(self, src_handle) :
"""
Returns True if any of the child objects has reference
@@ -110,6 +129,10 @@ class Repository(NoteBase, AddressBase, UrlBase, PrimaryObject):
@return: Returns whether any of it's child objects has reference to this source handle.
@rtype: bool
"""
for item in self.get_sourcref_child_list():
if item.has_source_reference(src_handle):
return True
return False
def remove_source_references(self, src_handle_list):
@@ -120,7 +143,8 @@ class Repository(NoteBase, AddressBase, UrlBase, PrimaryObject):
@param src_handle_list: The list of source handles to be removed.
@type src_handle_list: list
"""
pass
for item in self.get_sourcref_child_list():
item.remove_source_references(src_handle_list)
def replace_source_references(self, old_handle, new_handle):
"""
@@ -132,7 +156,8 @@ class Repository(NoteBase, AddressBase, UrlBase, PrimaryObject):
@param new_handle: The source handle to replace the old one with.
@type new_handle: str
"""
pass
for item in self.get_sourcref_child_list():
item.replace_source_references(old_handle, new_handle)
def set_type(self, the_type):
"""
+1 -1
View File
@@ -83,7 +83,7 @@ class StyleComboBox(gtk.ComboBox):
active = self.get_active()
if active < 0:
return None
key = self.store[active][0]
key = unicode(self.store[active][0])
if key == _('default'):
key = "default"
return (key,self.style_map[key])
+2 -2
View File
@@ -149,7 +149,7 @@ class StyleListDisplay:
if not node:
return
name = self.list.model.get_value(node,0)
name = unicode(self.list.model.get_value(node,0))
style = self.sheetlist.get_style_sheet(name)
StyleEditor(name,style,self)
@@ -158,7 +158,7 @@ class StyleListDisplay:
store,node = self.list.selection.get_selected()
if not node:
return
name = self.list.model.get_value(node,0)
name = unicode(self.list.model.get_value(node,0))
self.sheetlist.delete_style_sheet(name)
self.redraw()
+1
View File
@@ -719,6 +719,7 @@ class ScratchSourceLink(ScratchPadWrapper):
"\t<b>%s:</b>\t%s\n"\
"\t<b>%s:</b>\t%s\n"\
"\t<b>%s:</b>\t%s\n"\
"\t<b>%s:</b>\t%s\n"\
"\t<b>%s:</b>\t%s" % (
_("Source Link"),
_("Title"),escape(base.get_title()),
+4 -5
View File
@@ -675,7 +675,6 @@ class ViewManager:
about.set_documenters(const.documenters)
about.set_logo(gtk.gdk.pixbuf_new_from_file(const.splash))
about.set_modal(True)
about.show()
about.run()
about.destroy()
@@ -878,9 +877,9 @@ class ViewManager:
self.page_is_changing = False
def import_pkg(self, filename):
import ReadPkg
ReadPkg.impData(self.state.db, filename, self.uistate.pulse_progressbar)
self.post_load()
import ReadPkg
ReadPkg.impData(self.state.db, filename, self.uistate.pulse_progressbar)
self.post_load()
def import_data(self, obj):
if self.state.db.db_is_open:
@@ -970,7 +969,7 @@ class ViewManager:
self.change_page(None, None)
self.actiongroup.set_visible(True)
self.readonlygroup.set_visible(True)
self.readonlygroup.set_visible(True)
self.file_loaded = True
+349 -294
View File
@@ -20,321 +20,376 @@
# $Id$
# ANSEL references:
# http://lcweb2.loc.gov/diglib/codetables/45.html
# http://www.gymel.com/charsets/ANSEL.html
# Note that cStringIO stores 8-bit strings (bytes not unicode)
# utf8 will do, since that looks just like bytes
import cStringIO
# list of ANSEL codes that replicate ASCII
# note that DEL (127=0x7F) is a control char
# Note: spec allows control-chars that Gramps probably doesn't use
# but 10=0x0A _is_ needed (!)
# ---
# Also: there are two additional control chars 0x98,0x9c (unicode same)
# which we also ignore for now (start/emd of string (or sort sequence)
# ---
# TODO: should we allow TAB, as a Gramps extension?
_printable_ascii = map(chr, range(32,127)) # note: up thru 126
_use_ASCII = map(chr, [10, 27, 29 ,30, 31]) + _printable_ascii
# mappings of single byte ANSEL codes to unicode
_onebyte = {
'\x8D' : u'\x20\x0D', '\x8E' : u'\x20\x0C', '\xA1' : u'\x01\x41',
'\xA2' : u'\xD8', '\xA3' : u'\xD0', '\xA4' : u'\xDE',
'\xA5' : u'\xC6', '\xA6' : u'\x01\x52', '\xA7' : u'\x02\xB9',
'\xA8' : u'\xB7', '\xA9' : u'\x26\x6D', '\xAA' : u'\xAE',
'\xAB' : u'\xB1', '\xAC' : u'\x01\xA0', '\xAD' : u'\x01\xAF',
'\xAE' : u'\x02\xBE', '\xB0' : u'\x02\xBF', '\xB1' : u'\x01\x42',
'\xB2' : u'\xF8', '\xB3' : u'\x01\x11', '\xB4' : u'\xFE',
'\xB5' : u'\xE6', '\xB6' : u'\x01\x53', '\xB7' : u'\x02\xBA',
'\xB8' : u'\x01\x31', '\xB9' : u'\xA3', '\xBA' : u'\xF0',
'\xBC' : u'\x01\xA1', '\xBD' : u'\x01\xB0', '\xC0' : u'\xB0',
'\xC1' : u'\x21\x13', '\xC2' : u'\x21\x17', '\xC3' : u'\xA9',
'\xC4' : u'\x26\x6F', '\xC5' : u'\xBF', '\xC6' : u'\xA1',
'\xCF' : u'\xDF', '\xE0' : u'\x03\x09', '\xE1' : u'\x03',
'\xE2' : u'\x03\x01', '\xE3' : u'\x03\x02', '\xE4' : u'\x03\x03',
'\xE5' : u'\x03\x04', '\xE6' : u'\x03\x06', '\xE7' : u'\x03\x07',
'\xE9' : u'\x03\x0C', '\xEA' : u'\x03\x0A', '\xEB' : u'\xFE\x20',
'\xEC' : u'\xFE\x21', '\xED' : u'\x03\x15', '\xEE' : u'\x03\x0B',
'\xEF' : u'\x03\x10', '\xF0' : u'\x03\x27', '\xF1' : u'\x03\x28',
'\xF2' : u'\x03\x23', '\xF3' : u'\x03\x24', '\xF4' : u'\x03\x25',
'\xF5' : u'\x03\x33', '\xF6' : u'\x03\x32', '\xF7' : u'\x03\x26',
'\xF8' : u'\x03\x1C', '\xF9' : u'\x03\x2E', '\xFA' : u'\xFE\x22',
'\xFB' : u'\xFE\x23', '\xFE' : u'\x03\x13',
'\xA1' : u'\u0141', '\xA2' : u'\u00d8', '\xA3' : u'\u0110',
'\xA4' : u'\u00de', '\xA5' : u'\u00c6', '\xA6' : u'\u0152',
'\xA7' : u'\u02b9', '\xA8' : u'\u00b7', '\xA9' : u'\u266d',
'\xAA' : u'\u00ae', '\xAB' : u'\u00b1', '\xAC' : u'\u01a0',
'\xAD' : u'\u01af', '\xAE' : u'\u02bc', '\xB0' : u'\u02bb',
'\xB1' : u'\u0142', '\xB2' : u'\u00f8', '\xB3' : u'\u0111',
'\xB4' : u'\u00fe', '\xB5' : u'\u00e6', '\xB6' : u'\u0153',
'\xB7' : u'\u02ba', '\xB8' : u'\u0131', '\xB9' : u'\u00a3',
'\xBA' : u'\u00f0', '\xBC' : u'\u01a1', '\xBD' : u'\u01b0',
'\xC0' : u'\u00b0', '\xC1' : u'\u2113', '\xC2' : u'\u2117',
'\xC3' : u'\u00a9', '\xC4' : u'\u266f', '\xC5' : u'\u00bf',
'\xC6' : u'\u00a1', '\xC7' : u'\u00df', '\xC8' : u'\u20ac',
}
# combining forms (in ANSEL, they precede the modified ASCII character
# whereas the unicode combining term follows the character modified
# Note: unicode allows multiple modifiers, but ANSEL may not (TDB?),
# so we ignore multiple combining forms in this module
# 8d & 8e are zero-width joiner (ZWJ), and zero-width non-joiner ZWNJ
# (strange things) probably not commonly found in our needs, unless one
# starts writing persian (or???) poetry in ANSEL
_acombiners = {
'\x8D' : u'\u200d', '\x8E' : u'\u200c', '\xE0' : u'\u0309',
'\xE1' : u'\u0300', '\xE2' : u'\u0301', '\xE3' : u'\u0302',
'\xE4' : u'\u0303', '\xE5' : u'\u0304', '\xE6' : u'\u0306',
'\xE7' : u'\u0307', '\xE8' : u'\u0308', '\xE9' : u'\u030c',
'\xEA' : u'\u030a', '\xEB' : u'\ufe20', '\xEC' : u'\ufe21',
'\xED' : u'\u0315', '\xEE' : u'\u030b', '\xEF' : u'\u0310',
'\xF0' : u'\u0327', '\xF1' : u'\u0328', '\xF2' : u'\u0323',
'\xF3' : u'\u0324', '\xF4' : u'\u0325', '\xF5' : u'\u0333',
'\xF6' : u'\u0332', '\xF7' : u'\u0326', '\xF8' : u'\u031c',
'\xF9' : u'\u032e', '\xFA' : u'\ufe22', '\xFB' : u'\ufe23',
'\xFE' : u'\u0313',
}
# mappings of two byte (precomposed forms) ANSEL codes to unicode
_twobyte = {
'\xE0\x41' : u'\x1E\xA2', '\xE0\x45' : u'\x1E\xBA', '\xE0\x49' : u'\x1E\xC8',
'\xE0\x4F' : u'\x1E\xCE', '\xE0\x55' : u'\x1E\xE6', '\xE0\x59' : u'\x1E\xF6',
'\xE0\x61' : u'\x1E\xA3', '\xE0\x65' : u'\x1E\xBB', '\xE0\x69' : u'\x1E\xC9',
'\xE0\x6F' : u'\x1E\xCF', '\xE0\x75' : u'\x1E\xE7', '\xE0\x79' : u'\x1E\xF7',
'\xE1\x41' : u'\xC0', '\xE1\x45' : u'\xC8', '\xE1\x49' : u'\xCC',
'\xE1\x4F' : u'\xD2', '\xE1\x55' : u'\xD9', '\xE1\x57' : u'\x1E\x80',
'\xE1\x59' : u'\x1E\xF2', '\xE1\x61' : u'\xE0', '\xE1\x65' : u'\xE8',
'\xE1\x69' : u'\xEC', '\xE1\x6F' : u'\xF2', '\xE1\x75' : u'\xF9',
'\xE1\x77' : u'\x1E\x81', '\xE1\x79' : u'\x1E\xF3', '\xE2\x41' : u'\xC1',
'\xE2\x43' : u'\x01\x06', '\xE2\x45' : u'\xC9', '\xE2\x47' : u'\x01\xF4',
'\xE2\x49' : u'\xCD', '\xE2\x4B' : u'\x1E\x30', '\xE2\x4C' : u'\x01\x39',
'\xE2\x4D' : u'\x1E\x3E', '\xE2\x4E' : u'\x01\x43', '\xE2\x4F' : u'\xD3',
'\xE2\x50' : u'\x1E\x54', '\xE2\x52' : u'\x01\x54', '\xE2\x53' : u'\x01\x5A',
'\xE2\x55' : u'\xDA', '\xE2\x57' : u'\x1E\x82', '\xE2\x59' : u'\xDD',
'\xE2\x5A' : u'\x01\x79', '\xE2\x61' : u'\xE1', '\xE2\x63' : u'\x01\x07',
'\xE2\x65' : u'\xE9', '\xE2\x67' : u'\x01\xF5', '\xE2\x69' : u'\xED',
'\xE2\x6B' : u'\x1E\x31', '\xE2\x6C' : u'\x01\x3A', '\xE2\x6D' : u'\x1E\x3F',
'\xE2\x6E' : u'\x01\x44', '\xE2\x6F' : u'\xF3', '\xE2\x70' : u'\x1E\x55',
'\xE2\x72' : u'\x01\x55', '\xE2\x73' : u'\x01\x5B', '\xE2\x75' : u'\xFA',
'\xE2\x77' : u'\x1E\x83', '\xE2\x79' : u'\xFD', '\xE2\x7A' : u'\x01\x7A',
'\xE2\xA5' : u'\x01\xFC', '\xE2\xB5' : u'\x01\xFD', '\xE3\x41' : u'\xC2',
'\xE3\x43' : u'\x01\x08', '\xE3\x45' : u'\xCA', '\xE3\x47' : u'\x01\x1C',
'\xE3\x48' : u'\x01\x24', '\xE3\x49' : u'\xCE', '\xE3\x4A' : u'\x01\x34',
'\xE3\x4F' : u'\xD4', '\xE3\x53' : u'\x01\x5C', '\xE3\x55' : u'\xDB',
'\xE3\x57' : u'\x01\x74', '\xE3\x59' : u'\x01\x76', '\xE3\x5A' : u'\x1E\x90',
'\xE3\x61' : u'\xE2', '\xE3\x63' : u'\x01\x09', '\xE3\x65' : u'\xEA',
'\xE3\x67' : u'\x01\x1D', '\xE3\x68' : u'\x01\x25', '\xE3\x69' : u'\xEE',
'\xE3\x6A' : u'\x01\x35', '\xE3\x6F' : u'\xF4', '\xE3\x73' : u'\x01\x5D',
'\xE3\x75' : u'\xFB', '\xE3\x77' : u'\x01\x75', '\xE3\x79' : u'\x01\x77',
'\xE3\x7A' : u'\x1E\x91', '\xE4\x41' : u'\xC3', '\xE4\x45' : u'\x1E\xBC',
'\xE4\x49' : u'\x01\x28', '\xE4\x4E' : u'\xD1', '\xE4\x4F' : u'\xD5',
'\xE4\x55' : u'\x01\x68', '\xE4\x56' : u'\x1E\x7C', '\xE4\x59' : u'\x1E\xF8',
'\xE4\x61' : u'\xE3', '\xE4\x65' : u'\x1E\xBD', '\xE4\x69' : u'\x01\x29',
'\xE4\x6E' : u'\xF1', '\xE4\x6F' : u'\xF5', '\xE4\x75' : u'\x01\x69',
'\xE4\x76' : u'\x1E\x7D', '\xE4\x79' : u'\x1E\xF9', '\xE5\x41' : u'\x01',
'\xE5\x45' : u'\x01\x12', '\xE5\x47' : u'\x1E\x20', '\xE5\x49' : u'\x01\x2A',
'\xE5\x4F' : u'\x01\x4C', '\xE5\x55' : u'\x01\x6A', '\xE5\x61' : u'\x01\x01',
'\xE5\x65' : u'\x01\x13', '\xE5\x67' : u'\x1E\x21', '\xE5\x69' : u'\x01\x2B',
'\xE5\x6F' : u'\x01\x4D', '\xE5\x75' : u'\x01\x6B', '\xE5\xA5' : u'\x01\xE2',
'\xE5\xB5' : u'\x01\xE3', '\xE6\x41' : u'\x01\x02', '\xE6\x45' : u'\x01\x14',
'\xE6\x47' : u'\x01\x1E', '\xE6\x49' : u'\x01\x2C', '\xE6\x4F' : u'\x01\x4E',
'\xE6\x55' : u'\x01\x6C', '\xE6\x61' : u'\x01\x03', '\xE6\x65' : u'\x01\x15',
'\xE6\x67' : u'\x01\x1F', '\xE6\x69' : u'\x01\x2D', '\xE6\x6F' : u'\x01\x4F',
'\xE6\x75' : u'\x01\x6D', '\xE7\x42' : u'\x1E\x02', '\xE7\x43' : u'\x01\x0A',
'\xE7\x44' : u'\x1E\x0A', '\xE7\x45' : u'\x01\x16', '\xE7\x46' : u'\x1E\x1E',
'\xE7\x47' : u'\x01\x20', '\xE7\x48' : u'\x1E\x22', '\xE7\x49' : u'\x01\x30',
'\xE7\x4D' : u'\x1E\x40', '\xE7\x4E' : u'\x1E\x44', '\xE7\x50' : u'\x1E\x56',
'\xE7\x52' : u'\x1E\x58', '\xE7\x53' : u'\x1E\x60', '\xE7\x54' : u'\x1E\x6A',
'\xE7\x57' : u'\x1E\x86', '\xE7\x58' : u'\x1E\x8A', '\xE7\x59' : u'\x1E\x8E',
'\xE7\x5A' : u'\x01\x7B', '\xE7\x62' : u'\x1E\x03', '\xE7\x63' : u'\x01\x0B',
'\xE7\x64' : u'\x1E\x0B', '\xE7\x65' : u'\x01\x17', '\xE7\x66' : u'\x1E\x1F',
'\xE7\x67' : u'\x01\x21', '\xE7\x68' : u'\x1E\x23', '\xE7\x6D' : u'\x1E\x41',
'\xE7\x6E' : u'\x1E\x45', '\xE7\x70' : u'\x1E\x57', '\xE7\x72' : u'\x1E\x59',
'\xE7\x73' : u'\x1E\x61', '\xE7\x74' : u'\x1E\x6B', '\xE7\x77' : u'\x1E\x87',
'\xE7\x78' : u'\x1E\x8B', '\xE7\x79' : u'\x1E\x8F', '\xE7\x7A' : u'\x01\x7C',
'\xE8\x41' : u'\xC4', '\xE8\x45' : u'\xCB', '\xE8\x48' : u'\x1E\x26',
'\xE8\x49' : u'\xCF', '\xE8\x4F' : u'\xD6', '\xE8\x55' : u'\xDC',
'\xE8\x57' : u'\x1E\x84', '\xE8\x58' : u'\x1E\x8C', '\xE8\x59' : u'\x01\x78',
'\xE8\x61' : u'\xE4', '\xE8\x65' : u'\xEB', '\xE8\x68' : u'\x1E\x27',
'\xE8\x69' : u'\xEF', '\xE8\x6F' : u'\xF6', '\xE8\x74' : u'\x1E\x97',
'\xE8\x75' : u'\xFC', '\xE8\x77' : u'\x1E\x85', '\xE8\x78' : u'\x1E\x8D',
'\xE8\x79' : u'\xFF', '\xE9\x41' : u'\x01\xCD', '\xE9\x43' : u'\x01\x0C',
'\xE9\x44' : u'\x01\x0E', '\xE9\x45' : u'\x01\x1A', '\xE9\x47' : u'\x01\xE6',
'\xE9\x49' : u'\x01\xCF', '\xE9\x4B' : u'\x01\xE8', '\xE9\x4C' : u'\x01\x3D',
'\xE9\x4E' : u'\x01\x47', '\xE9\x4F' : u'\x01\xD1', '\xE9\x52' : u'\x01\x58',
'\xE9\x53' : u'\x01\x60', '\xE9\x54' : u'\x01\x64', '\xE9\x55' : u'\x01\xD3',
'\xE9\x5A' : u'\x01\x7D', '\xE9\x61' : u'\x01\xCE', '\xE9\x63' : u'\x01\x0D',
'\xE9\x64' : u'\x01\x0F', '\xE9\x65' : u'\x01\x1B', '\xE9\x67' : u'\x01\xE7',
'\xE9\x69' : u'\x01\xD0', '\xE9\x6A' : u'\x01\xF0', '\xE9\x6B' : u'\x01\xE9',
'\xE9\x6C' : u'\x01\x3E', '\xE9\x6E' : u'\x01\x48', '\xE9\x6F' : u'\x01\xD2',
'\xE9\x72' : u'\x01\x59', '\xE9\x73' : u'\x01\x61', '\xE9\x74' : u'\x01\x65',
'\xE9\x75' : u'\x01\xD4', '\xE9\x7A' : u'\x01\x7E', '\xEA\x41' : u'\xC5',
'\xEA\x61' : u'\xE5', '\xEA\x75' : u'\x01\x6F', '\xEA\x77' : u'\x1E\x98',
'\xEA\x79' : u'\x1E\x99', '\xEA\xAD' : u'\x01\x6E', '\xEE\x4F' : u'\x01\x50',
'\xEE\x55' : u'\x01\x70', '\xEE\x6F' : u'\x01\x51', '\xEE\x75' : u'\x01\x71',
'\xF0\x20' : u'\xB8', '\xF0\x43' : u'\xC7', '\xF0\x44' : u'\x1E\x10',
'\xF0\x47' : u'\x01\x22', '\xF0\x48' : u'\x1E\x28', '\xF0\x4B' : u'\x01\x36',
'\xF0\x4C' : u'\x01\x3B', '\xF0\x4E' : u'\x01\x45', '\xF0\x52' : u'\x01\x56',
'\xF0\x53' : u'\x01\x5E', '\xF0\x54' : u'\x01\x62', '\xF0\x63' : u'\xE7',
'\xF0\x64' : u'\x1E\x11', '\xF0\x67' : u'\x01\x23', '\xF0\x68' : u'\x1E\x29',
'\xF0\x6B' : u'\x01\x37', '\xF0\x6C' : u'\x01\x3C', '\xF0\x6E' : u'\x01\x46',
'\xF0\x72' : u'\x01\x57', '\xF0\x73' : u'\x01\x5F', '\xF0\x74' : u'\x01\x63',
'\xF1\x41' : u'\x01\x04', '\xF1\x45' : u'\x01\x18', '\xF1\x49' : u'\x01\x2E',
'\xF1\x4F' : u'\x01\xEA', '\xF1\x55' : u'\x01\x72', '\xF1\x61' : u'\x01\x05',
'\xF1\x65' : u'\x01\x19', '\xF1\x69' : u'\x01\x2F', '\xF1\x6F' : u'\x01\xEB',
'\xF1\x75' : u'\x01\x73', '\xF2\x41' : u'\x1E\xA0', '\xF2\x42' : u'\x1E\x04',
'\xF2\x44' : u'\x1E\x0C', '\xF2\x45' : u'\x1E\xB8', '\xF2\x48' : u'\x1E\x24',
'\xF2\x49' : u'\x1E\xCA', '\xF2\x4B' : u'\x1E\x32', '\xF2\x4C' : u'\x1E\x36',
'\xF2\x4D' : u'\x1E\x42', '\xF2\x4E' : u'\x1E\x46', '\xF2\x4F' : u'\x1E\xCC',
'\xF2\x52' : u'\x1E\x5A', '\xF2\x53' : u'\x1E\x62', '\xF2\x54' : u'\x1E\x6C',
'\xF2\x55' : u'\x1E\xE4', '\xF2\x56' : u'\x1E\x7E', '\xF2\x57' : u'\x1E\x88',
'\xF2\x59' : u'\x1E\xF4', '\xF2\x5A' : u'\x1E\x92', '\xF2\x61' : u'\x1E\xA1',
'\xF2\x62' : u'\x1E\x05', '\xF2\x64' : u'\x1E\x0D', '\xF2\x65' : u'\x1E\xB9',
'\xF2\x68' : u'\x1E\x25', '\xF2\x69' : u'\x1E\xCB', '\xF2\x6B' : u'\x1E\x33',
'\xF2\x6C' : u'\x1E\x37', '\xF2\x6D' : u'\x1E\x43', '\xF2\x6E' : u'\x1E\x47',
'\xF2\x6F' : u'\x1E\xCD', '\xF2\x72' : u'\x1E\x5B', '\xF2\x73' : u'\x1E\x63',
'\xF2\x74' : u'\x1E\x6D', '\xF2\x75' : u'\x1E\xE5', '\xF2\x76' : u'\x1E\x7F',
'\xF2\x77' : u'\x1E\x89', '\xF2\x79' : u'\x1E\xF5', '\xF2\x7A' : u'\x1E\x93',
'\xF3\x55' : u'\x1E\x72', '\xF3\x75' : u'\x1E\x73', '\xF4\x41' : u'\x1E',
'\xF4\x61' : u'\x1E\x01', '\xF9\x48' : u'\x1E\x2A', '\xF9\x68' : u'\x1E\x2B',
}
'\xE0\x41' : u'\u1ea2', '\xE0\x45' : u'\u1eba', '\xE0\x49' : u'\u1ec8',
'\xE0\x4F' : u'\u1ece', '\xE0\x55' : u'\u1ee6', '\xE0\x59' : u'\u1ef6',
'\xE0\x61' : u'\u1ea3', '\xE0\x65' : u'\u1ebb', '\xE0\x69' : u'\u1ec9',
'\xE0\x6F' : u'\u1ecf', '\xE0\x75' : u'\u1ee7', '\xE0\x79' : u'\u1ef7',
'\xE1\x41' : u'\u00c0', '\xE1\x45' : u'\u00c8', '\xE1\x49' : u'\u00cc',
'\xE1\x4F' : u'\u00d2', '\xE1\x55' : u'\u00d9', '\xE1\x57' : u'\u1e80',
'\xE1\x59' : u'\u1ef2', '\xE1\x61' : u'\u00e0', '\xE1\x65' : u'\u00e8',
'\xE1\x69' : u'\u00ec', '\xE1\x6F' : u'\u00f2', '\xE1\x75' : u'\u00f9',
'\xE1\x77' : u'\u1e81', '\xE1\x79' : u'\u1ef3', '\xE2\x41' : u'\u00c1',
'\xE2\x43' : u'\u0106', '\xE2\x45' : u'\u00c9', '\xE2\x47' : u'\u01f4',
'\xE2\x49' : u'\u00cd', '\xE2\x4B' : u'\u1e30', '\xE2\x4C' : u'\u0139',
'\xE2\x4D' : u'\u1e3e', '\xE2\x4E' : u'\u0143', '\xE2\x4F' : u'\u00d3',
'\xE2\x50' : u'\u1e54', '\xE2\x52' : u'\u0154', '\xE2\x53' : u'\u015a',
'\xE2\x55' : u'\u00da', '\xE2\x57' : u'\u1e82', '\xE2\x59' : u'\u00dd',
'\xE2\x5A' : u'\u0179', '\xE2\x61' : u'\u00e1', '\xE2\x63' : u'\u0107',
'\xE2\x65' : u'\u00e9', '\xE2\x67' : u'\u01f5', '\xE2\x69' : u'\u00ed',
'\xE2\x6B' : u'\u1e31', '\xE2\x6C' : u'\u013a', '\xE2\x6D' : u'\u1e3f',
'\xE2\x6E' : u'\u0144', '\xE2\x6F' : u'\u00f3', '\xE2\x70' : u'\u1e55',
'\xE2\x72' : u'\u0155', '\xE2\x73' : u'\u015b', '\xE2\x75' : u'\u00fa',
'\xE2\x77' : u'\u1e83', '\xE2\x79' : u'\u00fd', '\xE2\x7A' : u'\u017a',
'\xE2\xA5' : u'\u01fc', '\xE2\xB5' : u'\u01fd', '\xE3\x41' : u'\u00c2',
'\xE3\x43' : u'\u0108', '\xE3\x45' : u'\u00ca', '\xE3\x47' : u'\u011c',
'\xE3\x48' : u'\u0124', '\xE3\x49' : u'\u00ce', '\xE3\x4A' : u'\u0134',
'\xE3\x4F' : u'\u00d4', '\xE3\x53' : u'\u015c', '\xE3\x55' : u'\u00db',
'\xE3\x57' : u'\u0174', '\xE3\x59' : u'\u0176', '\xE3\x5A' : u'\u1e90',
'\xE3\x61' : u'\u00e2', '\xE3\x63' : u'\u0109', '\xE3\x65' : u'\u00ea',
'\xE3\x67' : u'\u011d', '\xE3\x68' : u'\u0125', '\xE3\x69' : u'\u00ee',
'\xE3\x6A' : u'\u0135', '\xE3\x6F' : u'\u00f4', '\xE3\x73' : u'\u015d',
'\xE3\x75' : u'\u00fb', '\xE3\x77' : u'\u0175', '\xE3\x79' : u'\u0177',
'\xE3\x7A' : u'\u1e91', '\xE4\x41' : u'\u00c3', '\xE4\x45' : u'\u1ebc',
'\xE4\x49' : u'\u0128', '\xE4\x4E' : u'\u00d1', '\xE4\x4F' : u'\u00d5',
'\xE4\x55' : u'\u0168', '\xE4\x56' : u'\u1e7c', '\xE4\x59' : u'\u1ef8',
'\xE4\x61' : u'\u00e3', '\xE4\x65' : u'\u1ebd', '\xE4\x69' : u'\u0129',
'\xE4\x6E' : u'\u00f1', '\xE4\x6F' : u'\u00f5', '\xE4\x75' : u'\u0169',
'\xE4\x76' : u'\u1e7d', '\xE4\x79' : u'\u1ef9', '\xE5\x41' : u'\u0100',
'\xE5\x45' : u'\u0112', '\xE5\x47' : u'\u1e20', '\xE5\x49' : u'\u012a',
'\xE5\x4F' : u'\u014c', '\xE5\x55' : u'\u016a', '\xE5\x61' : u'\u0101',
'\xE5\x65' : u'\u0113', '\xE5\x67' : u'\u1e21', '\xE5\x69' : u'\u012b',
'\xE5\x6F' : u'\u014d', '\xE5\x75' : u'\u016b', '\xE5\xA5' : u'\u01e2',
'\xE5\xB5' : u'\u01e3', '\xE6\x41' : u'\u0102', '\xE6\x45' : u'\u0114',
'\xE6\x47' : u'\u011e', '\xE6\x49' : u'\u012c', '\xE6\x4F' : u'\u014e',
'\xE6\x55' : u'\u016c', '\xE6\x61' : u'\u0103', '\xE6\x65' : u'\u0115',
'\xE6\x67' : u'\u011f', '\xE6\x69' : u'\u012d', '\xE6\x6F' : u'\u014f',
'\xE6\x75' : u'\u016d', '\xE7\x42' : u'\u1e02', '\xE7\x43' : u'\u010a',
'\xE7\x44' : u'\u1e0a', '\xE7\x45' : u'\u0116', '\xE7\x46' : u'\u1e1e',
'\xE7\x47' : u'\u0120', '\xE7\x48' : u'\u1e22', '\xE7\x49' : u'\u0130',
'\xE7\x4D' : u'\u1e40', '\xE7\x4E' : u'\u1e44', '\xE7\x50' : u'\u1e56',
'\xE7\x52' : u'\u1e58', '\xE7\x53' : u'\u1e60', '\xE7\x54' : u'\u1e6a',
'\xE7\x57' : u'\u1e86', '\xE7\x58' : u'\u1e8a', '\xE7\x59' : u'\u1e8e',
'\xE7\x5A' : u'\u017b', '\xE7\x62' : u'\u1e03', '\xE7\x63' : u'\u010b',
'\xE7\x64' : u'\u1e0b', '\xE7\x65' : u'\u0117', '\xE7\x66' : u'\u1e1f',
'\xE7\x67' : u'\u0121', '\xE7\x68' : u'\u1e23', '\xE7\x6D' : u'\u1e41',
'\xE7\x6E' : u'\u1e45', '\xE7\x70' : u'\u1e57', '\xE7\x72' : u'\u1e59',
'\xE7\x73' : u'\u1e61', '\xE7\x74' : u'\u1e6b', '\xE7\x77' : u'\u1e87',
'\xE7\x78' : u'\u1e8b', '\xE7\x79' : u'\u1e8f', '\xE7\x7A' : u'\u017c',
'\xE8\x41' : u'\u00c4', '\xE8\x45' : u'\u00cb', '\xE8\x48' : u'\u1e26',
'\xE8\x49' : u'\u00cf', '\xE8\x4F' : u'\u00d6', '\xE8\x55' : u'\u00dc',
'\xE8\x57' : u'\u1e84', '\xE8\x58' : u'\u1e8c', '\xE8\x59' : u'\u0178',
'\xE8\x61' : u'\u00e4', '\xE8\x65' : u'\u00eb', '\xE8\x68' : u'\u1e27',
'\xE8\x69' : u'\u00ef', '\xE8\x6F' : u'\u00f6', '\xE8\x74' : u'\u1e97',
'\xE8\x75' : u'\u00fc', '\xE8\x77' : u'\u1e85', '\xE8\x78' : u'\u1e8d',
'\xE8\x79' : u'\u00ff', '\xE9\x41' : u'\u01cd', '\xE9\x43' : u'\u010c',
'\xE9\x44' : u'\u010e', '\xE9\x45' : u'\u011a', '\xE9\x47' : u'\u01e6',
'\xE9\x49' : u'\u01cf', '\xE9\x4B' : u'\u01e8', '\xE9\x4C' : u'\u013d',
'\xE9\x4E' : u'\u0147', '\xE9\x4F' : u'\u01d1', '\xE9\x52' : u'\u0158',
'\xE9\x53' : u'\u0160', '\xE9\x54' : u'\u0164', '\xE9\x55' : u'\u01d3',
'\xE9\x5A' : u'\u017d', '\xE9\x61' : u'\u01ce', '\xE9\x63' : u'\u010d',
'\xE9\x64' : u'\u010f', '\xE9\x65' : u'\u011b', '\xE9\x67' : u'\u01e7',
'\xE9\x69' : u'\u01d0', '\xE9\x6A' : u'\u01f0', '\xE9\x6B' : u'\u01e9',
'\xE9\x6C' : u'\u013e', '\xE9\x6E' : u'\u0148', '\xE9\x6F' : u'\u01d2',
'\xE9\x72' : u'\u0159', '\xE9\x73' : u'\u0161', '\xE9\x74' : u'\u0165',
'\xE9\x75' : u'\u01d4', '\xE9\x7A' : u'\u017e', '\xEA\x41' : u'\u00c5',
'\xEA\x61' : u'\u00e5', '\xEA\x75' : u'\u016f', '\xEA\x77' : u'\u1e98',
'\xEA\x79' : u'\u1e99', '\xEA\xAD' : u'\u016e', '\xEE\x4F' : u'\u0150',
'\xEE\x55' : u'\u0170', '\xEE\x6F' : u'\u0151', '\xEE\x75' : u'\u0171',
'\xF0\x20' : u'\u00b8', '\xF0\x43' : u'\u00c7', '\xF0\x44' : u'\u1e10',
'\xF0\x47' : u'\u0122', '\xF0\x48' : u'\u1e28', '\xF0\x4B' : u'\u0136',
'\xF0\x4C' : u'\u013b', '\xF0\x4E' : u'\u0145', '\xF0\x52' : u'\u0156',
'\xF0\x53' : u'\u015e', '\xF0\x54' : u'\u0162', '\xF0\x63' : u'\u00e7',
'\xF0\x64' : u'\u1e11', '\xF0\x67' : u'\u0123', '\xF0\x68' : u'\u1e29',
'\xF0\x6B' : u'\u0137', '\xF0\x6C' : u'\u013c', '\xF0\x6E' : u'\u0146',
'\xF0\x72' : u'\u0157', '\xF0\x73' : u'\u015f', '\xF0\x74' : u'\u0163',
'\xF1\x41' : u'\u0104', '\xF1\x45' : u'\u0118', '\xF1\x49' : u'\u012e',
'\xF1\x4F' : u'\u01ea', '\xF1\x55' : u'\u0172', '\xF1\x61' : u'\u0105',
'\xF1\x65' : u'\u0119', '\xF1\x69' : u'\u012f', '\xF1\x6F' : u'\u01eb',
'\xF1\x75' : u'\u0173', '\xF2\x41' : u'\u1ea0', '\xF2\x42' : u'\u1e04',
'\xF2\x44' : u'\u1e0c', '\xF2\x45' : u'\u1eb8', '\xF2\x48' : u'\u1e24',
'\xF2\x49' : u'\u1eca', '\xF2\x4B' : u'\u1e32', '\xF2\x4C' : u'\u1e36',
'\xF2\x4D' : u'\u1e42', '\xF2\x4E' : u'\u1e46', '\xF2\x4F' : u'\u1ecc',
'\xF2\x52' : u'\u1e5a', '\xF2\x53' : u'\u1e62', '\xF2\x54' : u'\u1e6c',
'\xF2\x55' : u'\u1ee4', '\xF2\x56' : u'\u1e7e', '\xF2\x57' : u'\u1e88',
'\xF2\x59' : u'\u1ef4', '\xF2\x5A' : u'\u1e92', '\xF2\x61' : u'\u1ea1',
'\xF2\x62' : u'\u1e05', '\xF2\x64' : u'\u1e0d', '\xF2\x65' : u'\u1eb9',
'\xF2\x68' : u'\u1e25', '\xF2\x69' : u'\u1ecb', '\xF2\x6B' : u'\u1e33',
'\xF2\x6C' : u'\u1e37', '\xF2\x6D' : u'\u1e43', '\xF2\x6E' : u'\u1e47',
'\xF2\x6F' : u'\u1ecd', '\xF2\x72' : u'\u1e5b', '\xF2\x73' : u'\u1e63',
'\xF2\x74' : u'\u1e6d', '\xF2\x75' : u'\u1ee5', '\xF2\x76' : u'\u1e7f',
'\xF2\x77' : u'\u1e89', '\xF2\x79' : u'\u1ef5', '\xF2\x7A' : u'\u1e93',
'\xF3\x55' : u'\u1e72', '\xF3\x75' : u'\u1e73', '\xF4\x41' : u'\u1e00',
'\xF4\x61' : u'\u1e01', '\xF9\x48' : u'\u1e2a', '\xF9\x68' : u'\u1e2b',
}
# mappings of unicode to ANSEL codes
# note: a char u'\u00A1' is internally remembered & represented as u'\xA1'
# so do NOT blindly use 4-hexdigit keys for those cases
# or the conversion function will fail
_utoa = {
u'\xa1' : '\xC6', u'\xa3' : '\xB9', u'\xa9' : '\xC3',
u'\xae' : '\xAA', u'\xb0' : '\xC0', u'\xb1' : '\xAB',
u'\xb7' : '\xA8', u'\xb8' : '\xF0\x20', u'\xbf' : '\xC5',
u'\xc0' : '\xE1\x41', u'\xc1' : '\xE2\x41', u'\xc2' : '\xE3\x41',
u'\xc3' : '\xE4\x41', u'\xc4' : '\xE8\x41', u'\xc5' : '\xEA\x41',
u'\xc6' : '\xA5', u'\xc7' : '\xF0\x43', u'\xc8' : '\xE1\x45',
u'\xc9' : '\xE2\x45', u'\xca' : '\xE3\x45', u'\xcb' : '\xE8\x45',
u'\xcc' : '\xE1\x49', u'\xcd' : '\xE2\x49', u'\xce' : '\xE3\x49',
u'\xcf' : '\xE8\x49', u'\xd1' : '\xE4\x4E', u'\xd2' : '\xE1\x4F',
u'\xd3' : '\xE2\x4F', u'\xd4' : '\xE3\x4F', u'\xd5' : '\xE4\x4F',
u'\xd6' : '\xE8\x4F', u'\xd8' : '\xA2', u'\xd9' : '\xE1\x55',
u'\xda' : '\xE2\x55', u'\xdb' : '\xE3\x55', u'\xdc' : '\xE8\x55',
u'\xdd' : '\xE2\x59', u'\xde' : '\xA4', u'\xdf' : '\xC7',
u'\xe0' : '\xE1\x61', u'\xe1' : '\xE2\x61', u'\xe2' : '\xE3\x61',
u'\xe3' : '\xE4\x61', u'\xe4' : '\xE8\x61', u'\xe5' : '\xEA\x61',
u'\xe6' : '\xB5', u'\xe7' : '\xF0\x63', u'\xe8' : '\xE1\x65',
u'\xe9' : '\xE2\x65', u'\xea' : '\xE3\x65', u'\xeb' : '\xE8\x65',
u'\xec' : '\xE1\x69', u'\xed' : '\xE2\x69', u'\xee' : '\xE3\x69',
u'\xef' : '\xE8\x69', u'\xf0' : '\xBA', u'\xf1' : '\xE4\x6E',
u'\xf2' : '\xE1\x6F', u'\xf3' : '\xE2\x6F', u'\xf4' : '\xE3\x6F',
u'\xf5' : '\xE4\x6F', u'\xf6' : '\xE8\x6F', u'\xf8' : '\xB2',
u'\xf9' : '\xE1\x75', u'\xfa' : '\xE2\x75', u'\xfb' : '\xE3\x75',
u'\xfc' : '\xE8\x75', u'\xfd' : '\xE2\x79', u'\xfe' : '\xB4',
u'\xff' : '\xE8\x79', u'\u0100' : '\xE5\x41', u'\u0101' : '\xE5\x61',
u'\u0102' : '\xE6\x41', u'\u0103' : '\xE6\x61', u'\u0104' : '\xF1\x41',
u'\u0105' : '\xF1\x61', u'\u0106' : '\xE2\x43', u'\u0107' : '\xE2\x63',
u'\u0108' : '\xE3\x43', u'\u0109' : '\xE3\x63', u'\u010a' : '\xE7\x43',
u'\u010b' : '\xE7\x63', u'\u010c' : '\xE9\x43', u'\u010d' : '\xE9\x63',
u'\u010e' : '\xE9\x44', u'\u010f' : '\xE9\x64', u'\u0110' : '\xA3',
u'\u0111' : '\xB3', u'\u0112' : '\xE5\x45', u'\u0113' : '\xE5\x65',
u'\u0114' : '\xE6\x45', u'\u0115' : '\xE6\x65', u'\u0116' : '\xE7\x45',
u'\u0117' : '\xE7\x65', u'\u0118' : '\xF1\x45', u'\u0119' : '\xF1\x65',
u'\u011a' : '\xE9\x45', u'\u011b' : '\xE9\x65', u'\u011c' : '\xE3\x47',
u'\u011d' : '\xE3\x67', u'\u011e' : '\xE6\x47', u'\u011f' : '\xE6\x67',
u'\u0120' : '\xE7\x47', u'\u0121' : '\xE7\x67', u'\u0122' : '\xF0\x47',
u'\u0123' : '\xF0\x67', u'\u0124' : '\xE3\x48', u'\u0125' : '\xE3\x68',
u'\u0128' : '\xE4\x49', u'\u0129' : '\xE4\x69', u'\u012a' : '\xE5\x49',
u'\u012b' : '\xE5\x69', u'\u012c' : '\xE6\x49', u'\u012d' : '\xE6\x69',
u'\u012e' : '\xF1\x49', u'\u012f' : '\xF1\x69', u'\u0130' : '\xE7\x49',
u'\u0131' : '\xB8', u'\u0134' : '\xE3\x4A', u'\u0135' : '\xE3\x6A',
u'\u0136' : '\xF0\x4B', u'\u0137' : '\xF0\x6B', u'\u0139' : '\xE2\x4C',
u'\u013a' : '\xE2\x6C', u'\u013b' : '\xF0\x4C', u'\u013c' : '\xF0\x6C',
u'\u013d' : '\xE9\x4C', u'\u013e' : '\xE9\x6C', u'\u0141' : '\xA1',
u'\u0142' : '\xB1', u'\u0143' : '\xE2\x4E', u'\u0144' : '\xE2\x6E',
u'\u0145' : '\xF0\x4E', u'\u0146' : '\xF0\x6E', u'\u0147' : '\xE9\x4E',
u'\u0148' : '\xE9\x6E', u'\u014c' : '\xE5\x4F', u'\u014d' : '\xE5\x6F',
u'\u014e' : '\xE6\x4F', u'\u014f' : '\xE6\x6F', u'\u0150' : '\xEE\x4F',
u'\u0151' : '\xEE\x6F', u'\u0152' : '\xA6', u'\u0153' : '\xB6',
u'\u0154' : '\xE2\x52', u'\u0155' : '\xE2\x72', u'\u0156' : '\xF0\x52',
u'\u0157' : '\xF0\x72', u'\u0158' : '\xE9\x52', u'\u0159' : '\xE9\x72',
u'\u015a' : '\xE2\x53', u'\u015b' : '\xE2\x73', u'\u015c' : '\xE3\x53',
u'\u015d' : '\xE3\x73', u'\u015e' : '\xF0\x53', u'\u015f' : '\xF0\x73',
u'\u0160' : '\xE9\x53', u'\u0161' : '\xE9\x73', u'\u0162' : '\xF0\x54',
u'\u0163' : '\xF0\x74', u'\u0164' : '\xE9\x54', u'\u0165' : '\xE9\x74',
u'\u0168' : '\xE4\x55', u'\u0169' : '\xE4\x75', u'\u016a' : '\xE5\x55',
u'\u016b' : '\xE5\x75', u'\u016c' : '\xE6\x55', u'\u016d' : '\xE6\x75',
u'\u016e' : '\xEA\xAD', u'\u016f' : '\xEA\x75', u'\u0170' : '\xEE\x55',
u'\u0171' : '\xEE\x75', u'\u0172' : '\xF1\x55', u'\u0173' : '\xF1\x75',
u'\u0174' : '\xE3\x57', u'\u0175' : '\xE3\x77', u'\u0176' : '\xE3\x59',
u'\u0177' : '\xE3\x79', u'\u0178' : '\xE8\x59', u'\u0179' : '\xE2\x5A',
u'\u017a' : '\xE2\x7A', u'\u017b' : '\xE7\x5A', u'\u017c' : '\xE7\x7A',
u'\u017d' : '\xE9\x5A', u'\u017e' : '\xE9\x7A', u'\u01a0' : '\xAC',
u'\u01a1' : '\xBC', u'\u01af' : '\xAD', u'\u01b0' : '\xBD',
u'\u01cd' : '\xE9\x41', u'\u01ce' : '\xE9\x61', u'\u01cf' : '\xE9\x49',
u'\u01d0' : '\xE9\x69', u'\u01d1' : '\xE9\x4F', u'\u01d2' : '\xE9\x6F',
u'\u01d3' : '\xE9\x55', u'\u01d4' : '\xE9\x75', u'\u01e2' : '\xE5\xA5',
u'\u01e3' : '\xE5\xB5', u'\u01e6' : '\xE9\x47', u'\u01e7' : '\xE9\x67',
u'\u01e8' : '\xE9\x4B', u'\u01e9' : '\xE9\x6B', u'\u01ea' : '\xF1\x4F',
u'\u01eb' : '\xF1\x6F', u'\u01f0' : '\xE9\x6A', u'\u01f4' : '\xE2\x47',
u'\u01f5' : '\xE2\x67', u'\u01fc' : '\xE2\xA5', u'\u01fd' : '\xE2\xB5',
u'\u02b9' : '\xA7', u'\u02ba' : '\xB7', u'\u02bb' : '\xB0',
u'\u02bc' : '\xAE', u'\u1e00' : '\xF4\x41', u'\u1e01' : '\xF4\x61',
u'\u1e02' : '\xE7\x42', u'\u1e03' : '\xE7\x62', u'\u1e04' : '\xF2\x42',
u'\u1e05' : '\xF2\x62', u'\u1e0a' : '\xE7\x44', u'\u1e0b' : '\xE7\x64',
u'\u1e0c' : '\xF2\x44', u'\u1e0d' : '\xF2\x64', u'\u1e10' : '\xF0\x44',
u'\u1e11' : '\xF0\x64', u'\u1e1e' : '\xE7\x46', u'\u1e1f' : '\xE7\x66',
u'\u1e20' : '\xE5\x47', u'\u1e21' : '\xE5\x67', u'\u1e22' : '\xE7\x48',
u'\u1e23' : '\xE7\x68', u'\u1e24' : '\xF2\x48', u'\u1e25' : '\xF2\x68',
u'\u1e26' : '\xE8\x48', u'\u1e27' : '\xE8\x68', u'\u1e28' : '\xF0\x48',
u'\u1e29' : '\xF0\x68', u'\u1e2a' : '\xF9\x48', u'\u1e2b' : '\xF9\x68',
u'\u1e30' : '\xE2\x4B', u'\u1e31' : '\xE2\x6B', u'\u1e32' : '\xF2\x4B',
u'\u1e33' : '\xF2\x6B', u'\u1e36' : '\xF2\x4C', u'\u1e37' : '\xF2\x6C',
u'\u1e3e' : '\xE2\x4D', u'\u1e3f' : '\xE2\x6D', u'\u1e40' : '\xE7\x4D',
u'\u1e41' : '\xE7\x6D', u'\u1e42' : '\xF2\x4D', u'\u1e43' : '\xF2\x6D',
u'\u1e44' : '\xE7\x4E', u'\u1e45' : '\xE7\x6E', u'\u1e46' : '\xF2\x4E',
u'\u1e47' : '\xF2\x6E', u'\u1e54' : '\xE2\x50', u'\u1e55' : '\xE2\x70',
u'\u1e56' : '\xE7\x50', u'\u1e57' : '\xE7\x70', u'\u1e58' : '\xE7\x52',
u'\u1e59' : '\xE7\x72', u'\u1e5a' : '\xF2\x52', u'\u1e5b' : '\xF2\x72',
u'\u1e60' : '\xE7\x53', u'\u1e61' : '\xE7\x73', u'\u1e62' : '\xF2\x53',
u'\u1e63' : '\xF2\x73', u'\u1e6a' : '\xE7\x54', u'\u1e6b' : '\xE7\x74',
u'\u1e6c' : '\xF2\x54', u'\u1e6d' : '\xF2\x74', u'\u1e72' : '\xF3\x55',
u'\u1e73' : '\xF3\x75', u'\u1e7c' : '\xE4\x56', u'\u1e7d' : '\xE4\x76',
u'\u1e7e' : '\xF2\x56', u'\u1e7f' : '\xF2\x76', u'\u1e80' : '\xE1\x57',
u'\u1e81' : '\xE1\x77', u'\u1e82' : '\xE2\x57', u'\u1e83' : '\xE2\x77',
u'\u1e84' : '\xE8\x57', u'\u1e85' : '\xE8\x77', u'\u1e86' : '\xE7\x57',
u'\u1e87' : '\xE7\x77', u'\u1e88' : '\xF2\x57', u'\u1e89' : '\xF2\x77',
u'\u1e8a' : '\xE7\x58', u'\u1e8b' : '\xE7\x78', u'\u1e8c' : '\xE8\x58',
u'\u1e8d' : '\xE8\x78', u'\u1e8e' : '\xE7\x59', u'\u1e8f' : '\xE7\x79',
u'\u1e90' : '\xE3\x5A', u'\u1e91' : '\xE3\x7A', u'\u1e92' : '\xF2\x5A',
u'\u1e93' : '\xF2\x7A', u'\u1e97' : '\xE8\x74', u'\u1e98' : '\xEA\x77',
u'\u1e99' : '\xEA\x79', u'\u1ea0' : '\xF2\x41', u'\u1ea1' : '\xF2\x61',
u'\u1ea2' : '\xE0\x41', u'\u1ea3' : '\xE0\x61', u'\u1eb8' : '\xF2\x45',
u'\u1eb9' : '\xF2\x65', u'\u1eba' : '\xE0\x45', u'\u1ebb' : '\xE0\x65',
u'\u1ebc' : '\xE4\x45', u'\u1ebd' : '\xE4\x65', u'\u1ec8' : '\xE0\x49',
u'\u1ec9' : '\xE0\x69', u'\u1eca' : '\xF2\x49', u'\u1ecb' : '\xF2\x69',
u'\u1ecc' : '\xF2\x4F', u'\u1ecd' : '\xF2\x6F', u'\u1ece' : '\xE0\x4F',
u'\u1ecf' : '\xE0\x6F', u'\u1ee4' : '\xF2\x55', u'\u1ee5' : '\xF2\x75',
u'\u1ee6' : '\xE0\x55', u'\u1ee7' : '\xE0\x75', u'\u1ef2' : '\xE1\x59',
u'\u1ef3' : '\xE1\x79', u'\u1ef4' : '\xF2\x59', u'\u1ef5' : '\xF2\x79',
u'\u1ef6' : '\xE0\x59', u'\u1ef7' : '\xE0\x79', u'\u1ef8' : '\xE4\x59',
u'\u1ef9' : '\xE4\x79', u'\u20ac' : '\xC8', u'\u2113' : '\xC1',
u'\u2117' : '\xC2', u'\u266d' : '\xA9', u'\u266f' : '\xC4',
}
_utoa = {
u'\xA1' : '\xC6', u'\xA3' : '\xB9', u'\xA9' : '\xC3',
u'\xAE' : '\xAA', u'\xB0' : '\xC0', u'\xB1' : '\xAB',
u'\xB7' : '\xA8', u'\xB8' : '\xF0\x20', u'\xBF' : '\xC5',
u'\xC0' : '\xE1\x41', u'\xC1' : '\xE2\x41', u'\xC2' : '\xE3\x41',
u'\xC3' : '\xE4\x41', u'\xC4' : '\xE8\x41', u'\xC5' : '\xEA\x41',
u'\xC6' : '\xA5', u'\xC7' : '\xF0\x43', u'\xC8' : '\xE1\x45',
u'\xC9' : '\xE2\x45', u'\xCA' : '\xE3\x45', u'\xCB' : '\xE8\x45',
u'\xCC' : '\xE1\x49', u'\xCD' : '\xE2\x49', u'\xCE' : '\xE3\x49',
u'\xCF' : '\xE8\x49', u'\xD0' : '\xA3', u'\xD1' : '\xE4\x4E',
u'\xD2' : '\xE1\x4F', u'\xD3' : '\xE2\x4F', u'\xD4' : '\xE3\x4F',
u'\xD5' : '\xE4\x4F', u'\xD6' : '\xE8\x4F', u'\xD8' : '\xA2',
u'\xD9' : '\xE1\x55', u'\xDA' : '\xE2\x55', u'\xDB' : '\xE3\x55',
u'\xDC' : '\xE8\x55', u'\xDD' : '\xE2\x59', u'\xDE' : '\xA4',
u'\xDF' : '\xCF', u'\xE0' : '\xE1\x61', u'\xE1' : '\xE2\x61',
u'\xE2' : '\xE3\x61', u'\xE3' : '\xE4\x61', u'\xE4' : '\xE8\x61',
u'\xE5' : '\xEA\x61', u'\xE6' : '\xB5', u'\xE7' : '\xF0\x63',
u'\xE8' : '\xE1\x65', u'\xE9' : '\xE2\x65', u'\xEA' : '\xE3\x65',
u'\xEB' : '\xE8\x65', u'\xEC' : '\xE1\x69', u'\xED' : '\xE2\x69',
u'\xEE' : '\xE3\x69', u'\xEF' : '\xE8\x69', u'\xF0' : '\xBA',
u'\xF1' : '\xE4\x6E', u'\xF2' : '\xE1\x6F', u'\xF3' : '\xE2\x6F',
u'\xF4' : '\xE3\x6F', u'\xF5' : '\xE4\x6F', u'\xF6' : '\xE8\x6F',
u'\xF8' : '\xB2', u'\xF9' : '\xE1\x75', u'\xFA' : '\xE2\x75',
u'\xFB' : '\xE3\x75', u'\xFC' : '\xE8\x75', u'\xFD' : '\xE2\x79',
u'\xFE' : '\xB4', u'\xFF' : '\xE8\x79', u'\x01' : '\xE5\x41',
u'\x01\x01' : '\xE5\x61', u'\x01\x02' : '\xE6\x41', u'\x01\x03' : '\xE6\x61',
u'\x01\x04' : '\xF1\x41', u'\x01\x05' : '\xF1\x61', u'\x01\x06' : '\xE2\x43',
u'\x01\x07' : '\xE2\x63', u'\x01\x08' : '\xE3\x43', u'\x01\x09' : '\xE3\x63',
u'\x01\x0A' : '\xE7\x43', u'\x01\x0B' : '\xE7\x63', u'\x01\x0C' : '\xE9\x43',
u'\x01\x0D' : '\xE9\x63', u'\x01\x0E' : '\xE9\x44', u'\x01\x0F' : '\xE9\x64',
u'\x01\x10' : '\xA3', u'\x01\x11' : '\xB3', u'\x01\x12' : '\xE5\x45',
u'\x01\x13' : '\xE5\x65', u'\x01\x14' : '\xE6\x45', u'\x01\x15' : '\xE6\x65',
u'\x01\x16' : '\xE7\x45', u'\x01\x17' : '\xE7\x65', u'\x01\x18' : '\xF1\x45',
u'\x01\x19' : '\xF1\x65', u'\x01\x1A' : '\xE9\x45', u'\x01\x1B' : '\xE9\x65',
u'\x01\x1C' : '\xE3\x47', u'\x01\x1D' : '\xE3\x67', u'\x01\x1E' : '\xE6\x47',
u'\x01\x1F' : '\xE6\x67', u'\x01\x20' : '\xE7\x47', u'\x01\x21' : '\xE7\x67',
u'\x01\x22' : '\xF0\x47', u'\x01\x23' : '\xF0\x67', u'\x01\x24' : '\xE3\x48',
u'\x01\x25' : '\xE3\x68', u'\x01\x28' : '\xE4\x49', u'\x01\x29' : '\xE4\x69',
u'\x01\x2A' : '\xE5\x49', u'\x01\x2B' : '\xE5\x69', u'\x01\x2C' : '\xE6\x49',
u'\x01\x2D' : '\xE6\x69', u'\x01\x2E' : '\xF1\x49', u'\x01\x2F' : '\xF1\x69',
u'\x01\x30' : '\xE7\x49', u'\x01\x31' : '\xB8', u'\x01\x34' : '\xE3\x4A',
u'\x01\x35' : '\xE3\x6A', u'\x01\x36' : '\xF0\x4B', u'\x01\x37' : '\xF0\x6B',
u'\x01\x39' : '\xE2\x4C', u'\x01\x3A' : '\xE2\x6C', u'\x01\x3B' : '\xF0\x4C',
u'\x01\x3C' : '\xF0\x6C', u'\x01\x3D' : '\xE9\x4C', u'\x01\x3E' : '\xE9\x6C',
u'\x01\x41' : '\xA1', u'\x01\x42' : '\xB1', u'\x01\x43' : '\xE2\x4E',
u'\x01\x44' : '\xE2\x6E', u'\x01\x45' : '\xF0\x4E', u'\x01\x46' : '\xF0\x6E',
u'\x01\x47' : '\xE9\x4E', u'\x01\x48' : '\xE9\x6E', u'\x01\x4C' : '\xE5\x4F',
u'\x01\x4D' : '\xE5\x6F', u'\x01\x4E' : '\xE6\x4F', u'\x01\x4F' : '\xE6\x6F',
u'\x01\x50' : '\xEE\x4F', u'\x01\x51' : '\xEE\x6F', u'\x01\x52' : '\xA6',
u'\x01\x53' : '\xB6', u'\x01\x54' : '\xE2\x52', u'\x01\x55' : '\xE2\x72',
u'\x01\x56' : '\xF0\x52', u'\x01\x57' : '\xF0\x72', u'\x01\x58' : '\xE9\x52',
u'\x01\x59' : '\xE9\x72', u'\x01\x5A' : '\xE2\x53', u'\x01\x5B' : '\xE2\x73',
u'\x01\x5C' : '\xE3\x53', u'\x01\x5D' : '\xE3\x73', u'\x01\x5E' : '\xF0\x53',
u'\x01\x5F' : '\xF0\x73', u'\x01\x60' : '\xE9\x53', u'\x01\x61' : '\xE9\x73',
u'\x01\x62' : '\xF0\x54', u'\x01\x63' : '\xF0\x74', u'\x01\x64' : '\xE9\x54',
u'\x01\x65' : '\xE9\x74', u'\x01\x68' : '\xE4\x55', u'\x01\x69' : '\xE4\x75',
u'\x01\x6A' : '\xE5\x55', u'\x01\x6B' : '\xE5\x75', u'\x01\x6C' : '\xE6\x55',
u'\x01\x6D' : '\xE6\x75', u'\x01\x6E' : '\xEA\xAD', u'\x01\x6F' : '\xEA\x75',
u'\x01\x70' : '\xEE\x55', u'\x01\x71' : '\xEE\x75', u'\x01\x72' : '\xF1\x55',
u'\x01\x73' : '\xF1\x75', u'\x01\x74' : '\xE3\x57', u'\x01\x75' : '\xE3\x77',
u'\x01\x76' : '\xE3\x59', u'\x01\x77' : '\xE3\x79', u'\x01\x78' : '\xE8\x59',
u'\x01\x79' : '\xE2\x5A', u'\x01\x7A' : '\xE2\x7A', u'\x01\x7B' : '\xE7\x5A',
u'\x01\x7C' : '\xE7\x7A', u'\x01\x7D' : '\xE9\x5A', u'\x01\x7E' : '\xE9\x7A',
u'\x01\xA0' : '\xAC', u'\x01\xA1' : '\xBC', u'\x01\xAF' : '\xAD',
u'\x01\xB0' : '\xBD', u'\x01\xCD' : '\xE9\x41', u'\x01\xCE' : '\xE9\x61',
u'\x01\xCF' : '\xE9\x49', u'\x01\xD0' : '\xE9\x69', u'\x01\xD1' : '\xE9\x4F',
u'\x01\xD2' : '\xE9\x6F', u'\x01\xD3' : '\xE9\x55', u'\x01\xD4' : '\xE9\x75',
u'\x01\xE2' : '\xE5\xA5', u'\x01\xE3' : '\xE5\xB5', u'\x01\xE6' : '\xE9\x47',
u'\x01\xE7' : '\xE9\x67', u'\x01\xE8' : '\xE9\x4B', u'\x01\xE9' : '\xE9\x6B',
u'\x01\xEA' : '\xF1\x4F', u'\x01\xEB' : '\xF1\x6F', u'\x01\xF0' : '\xE9\x6A',
u'\x01\xF4' : '\xE2\x47', u'\x01\xF5' : '\xE2\x67', u'\x01\xFC' : '\xE2\xA5',
u'\x01\xFD' : '\xE2\xB5', u'\x02\xB9' : '\xA7', u'\x02\xBA' : '\xB7',
u'\x02\xBE' : '\xAE', u'\x02\xBF' : '\xB0', u'\x03' : '\xE1',
u'\x03\x01' : '\xE2', u'\x03\x02' : '\xE3', u'\x03\x03' : '\xE4',
u'\x03\x04' : '\xE5', u'\x03\x06' : '\xE6', u'\x03\x07' : '\xE7',
u'\x03\x09' : '\xE0', u'\x03\x0A' : '\xEA', u'\x03\x0B' : '\xEE',
u'\x03\x0C' : '\xE9', u'\x03\x10' : '\xEF', u'\x03\x13' : '\xFE',
u'\x03\x15' : '\xED', u'\x03\x1C' : '\xF8', u'\x03\x23' : '\xF2',
u'\x03\x24' : '\xF3', u'\x03\x25' : '\xF4', u'\x03\x26' : '\xF7',
u'\x03\x27' : '\xF0', u'\x03\x28' : '\xF1', u'\x03\x2E' : '\xF9',
u'\x03\x32' : '\xF6', u'\x03\x33' : '\xF5', u'\x1E' : '\xF4\x41',
u'\x1E\x01' : '\xF4\x61', u'\x1E\x02' : '\xE7\x42', u'\x1E\x03' : '\xE7\x62',
u'\x1E\x04' : '\xF2\x42', u'\x1E\x05' : '\xF2\x62', u'\x1E\x0A' : '\xE7\x44',
u'\x1E\x0B' : '\xE7\x64', u'\x1E\x0C' : '\xF2\x44', u'\x1E\x0D' : '\xF2\x64',
u'\x1E\x10' : '\xF0\x44', u'\x1E\x11' : '\xF0\x64', u'\x1E\x1E' : '\xE7\x46',
u'\x1E\x1F' : '\xE7\x66', u'\x1E\x20' : '\xE5\x47', u'\x1E\x21' : '\xE5\x67',
u'\x1E\x22' : '\xE7\x48', u'\x1E\x23' : '\xE7\x68', u'\x1E\x24' : '\xF2\x48',
u'\x1E\x25' : '\xF2\x68', u'\x1E\x26' : '\xE8\x48', u'\x1E\x27' : '\xE8\x68',
u'\x1E\x28' : '\xF0\x48', u'\x1E\x29' : '\xF0\x68', u'\x1E\x2A' : '\xF9\x48',
u'\x1E\x2B' : '\xF9\x68', u'\x1E\x30' : '\xE2\x4B', u'\x1E\x31' : '\xE2\x6B',
u'\x1E\x32' : '\xF2\x4B', u'\x1E\x33' : '\xF2\x6B', u'\x1E\x36' : '\xF2\x4C',
u'\x1E\x37' : '\xF2\x6C', u'\x1E\x3E' : '\xE2\x4D', u'\x1E\x3F' : '\xE2\x6D',
u'\x1E\x40' : '\xE7\x4D', u'\x1E\x41' : '\xE7\x6D', u'\x1E\x42' : '\xF2\x4D',
u'\x1E\x43' : '\xF2\x6D', u'\x1E\x44' : '\xE7\x4E', u'\x1E\x45' : '\xE7\x6E',
u'\x1E\x46' : '\xF2\x4E', u'\x1E\x47' : '\xF2\x6E', u'\x1E\x54' : '\xE2\x50',
u'\x1E\x55' : '\xE2\x70', u'\x1E\x56' : '\xE7\x50', u'\x1E\x57' : '\xE7\x70',
u'\x1E\x58' : '\xE7\x52', u'\x1E\x59' : '\xE7\x72', u'\x1E\x5A' : '\xF2\x52',
u'\x1E\x5B' : '\xF2\x72', u'\x1E\x60' : '\xE7\x53', u'\x1E\x61' : '\xE7\x73',
u'\x1E\x62' : '\xF2\x53', u'\x1E\x63' : '\xF2\x73', u'\x1E\x6A' : '\xE7\x54',
u'\x1E\x6B' : '\xE7\x74', u'\x1E\x6C' : '\xF2\x54', u'\x1E\x6D' : '\xF2\x74',
u'\x1E\x72' : '\xF3\x55', u'\x1E\x73' : '\xF3\x75', u'\x1E\x7C' : '\xE4\x56',
u'\x1E\x7D' : '\xE4\x76', u'\x1E\x7E' : '\xF2\x56', u'\x1E\x7F' : '\xF2\x76',
u'\x1E\x80' : '\xE1\x57', u'\x1E\x81' : '\xE1\x77', u'\x1E\x82' : '\xE2\x57',
u'\x1E\x83' : '\xE2\x77', u'\x1E\x84' : '\xE8\x57', u'\x1E\x85' : '\xE8\x77',
u'\x1E\x86' : '\xE7\x57', u'\x1E\x87' : '\xE7\x77', u'\x1E\x88' : '\xF2\x57',
u'\x1E\x89' : '\xF2\x77', u'\x1E\x8A' : '\xE7\x58', u'\x1E\x8B' : '\xE7\x78',
u'\x1E\x8C' : '\xE8\x58', u'\x1E\x8D' : '\xE8\x78', u'\x1E\x8E' : '\xE7\x59',
u'\x1E\x8F' : '\xE7\x79', u'\x1E\x90' : '\xE3\x5A', u'\x1E\x91' : '\xE3\x7A',
u'\x1E\x92' : '\xF2\x5A', u'\x1E\x93' : '\xF2\x7A', u'\x1E\x97' : '\xE8\x74',
u'\x1E\x98' : '\xEA\x77', u'\x1E\x99' : '\xEA\x79', u'\x1E\xA0' : '\xF2\x41',
u'\x1E\xA1' : '\xF2\x61', u'\x1E\xA2' : '\xE0\x41', u'\x1E\xA3' : '\xE0\x61',
u'\x1E\xB8' : '\xF2\x45', u'\x1E\xB9' : '\xF2\x65', u'\x1E\xBA' : '\xE0\x45',
u'\x1E\xBB' : '\xE0\x65', u'\x1E\xBC' : '\xE4\x45', u'\x1E\xBD' : '\xE4\x65',
u'\x1E\xC8' : '\xE0\x49', u'\x1E\xC9' : '\xE0\x69', u'\x1E\xCA' : '\xF2\x49',
u'\x1E\xCB' : '\xF2\x69', u'\x1E\xCC' : '\xF2\x4F', u'\x1E\xCD' : '\xF2\x6F',
u'\x1E\xCE' : '\xE0\x4F', u'\x1E\xCF' : '\xE0\x6F', u'\x1E\xE4' : '\xF2\x55',
u'\x1E\xE5' : '\xF2\x75', u'\x1E\xE6' : '\xE0\x55', u'\x1E\xE7' : '\xE0\x75',
u'\x1E\xF2' : '\xE1\x59', u'\x1E\xF3' : '\xE1\x79', u'\x1E\xF4' : '\xF2\x59',
u'\x1E\xF5' : '\xF2\x79', u'\x1E\xF6' : '\xE0\x59', u'\x1E\xF7' : '\xE0\x79',
u'\x1E\xF8' : '\xE4\x59', u'\x1E\xF9' : '\xE4\x79',
# u'\x20\x0C' : '\x8E', u'\x20\x0D' : '\x8D', u'\x21\x13' : '\xC1',
# u'\x21\x17' : '\xC2', u'\x26\x6D' : '\xA9', u'\x26\x6F' : '\xC4',
u'\xFE\x20' : '\xEB',
u'\xFE\x21' : '\xEC', u'\xFE\x22' : '\xFA', u'\xFE\x23' : '\xFB',
}
# unicode combining forms mapped to ANSEL
_ucombiners = {
u'\u0300' : '\xE1', u'\u0301' : '\xE2', u'\u0302' : '\xE3',
u'\u0303' : '\xE4', u'\u0304' : '\xE5', u'\u0306' : '\xE6',
u'\u0307' : '\xE7', u'\u0308' : '\xE8', u'\u0309' : '\xE0',
u'\u030a' : '\xEA', u'\u030b' : '\xEE', u'\u030c' : '\xE9',
u'\u0310' : '\xEF', u'\u0313' : '\xFE', u'\u0315' : '\xED',
u'\u031c' : '\xF8', u'\u0323' : '\xF2', u'\u0324' : '\xF3',
u'\u0325' : '\xF4', u'\u0326' : '\xF7', u'\u0327' : '\xF0',
u'\u0328' : '\xF1', u'\u032e' : '\xF9', u'\u0332' : '\xF6',
u'\u0333' : '\xF5', u'\u200c' : '\x8E', u'\u200d' : '\x8D',
u'\ufe20' : '\xEB', u'\ufe21' : '\xEC', u'\ufe22' : '\xFA',
u'\ufe23' : '\xFB',
}
# TODO: change name to ansel_to_unicode (it does NOT return utf-8)
# ALSO: I think I'd prefer full pass-through of ANSEL's ASCII subset,
# with substitutions and deletions handled at a higher level
def ansel_to_utf8(s):
"""Converts an ANSEL encoded string to UTF8"""
""" Convert an ANSEL encoded string to unicode """
buff = cStringIO.StringIO()
while s:
c0 = ord(s[0])
if c0 <= 31:
head = u' '
s = s[1:]
elif c0 > 127:
l2 = s[0:2]
l1 = s[0]
if _twobyte.has_key(l2):
head = _twobyte[l2]
s = s[2:]
elif _onebyte.has_key(l1):
head = _onebyte[l1]
s = s[1:]
if ord(s[0]) < 128:
if s[0] in _use_ASCII:
head = s[0]
else:
head = u'\xff\xfd'
s = s[1:]
else:
head = s[0]
# substitute space for disallowed (control) chars
head = ' '
s = s[1:]
buff.write(head)
ans = unicode(buff.getvalue())
else:
if _twobyte.has_key(s[0:2]):
head = _twobyte[s[0:2]]
s = s[2:]
elif _onebyte.has_key(s[0]):
head = _onebyte[s[0]]
s = s[1:]
elif s[0] in _acombiners.keys():
c = _acombiners[s[0]]
# always consume the combiner
s = s[1:]
next = s[0]
if next in _printable_ascii:
# consume next as well
s = s[1:]
# unicode: combiner follows base-char
head = next + c
else:
# just drop the unexpected combiner
continue
else:
head = u'\ufffd' # "Replacement Char"
s = s[1:]
# note: cStringIO handles 8-bit strings, only (no unicode)
buff.write(head.encode("utf-8"))
ans = unicode(buff.getvalue(), "utf-8")
buff.close()
return ans
# TODO: change name to unicode_to_ansel (it does NOT process utf-8 input)
def utf8_to_ansel(s):
"""Converts an UTF8 encoded string to ANSEL"""
if type(s) != unicode:
s = unicode(s)
""" Convert a unicode string to ANSEL """
buff = cStringIO.StringIO()
while s:
c0 = ord(s[0])
if c0 <= 3 or c0 == 0x1e or c0 >= 0xf3:
try:
head = _utoa[s[0:2]]
s = s[2:]
except:
try:
head = _utoa[s[0:1]]
s = s[1:]
except:
head = '?'
s = s[1:]
elif c0 > 127:
try:
head = _utoa[s[0:1]]
s = s[1:]
except:
head = '?'
s = s[1:]
if ord(s[0]) < 128:
head = s[0].encode('ascii')
if not head in _use_ASCII:
head = ' '
else:
head = s[0]
s = s[1:]
if s[0] in _utoa.keys():
head = _utoa[s[0]]
elif s[0] in _ucombiners.keys():
c = _ucombiners[s[0]]
# head happens to have last conversion to ansel
if len(head) == 1 and head[-1] in _printable_ascii:
last = head[-1]
head = head[:-1] + c + last
buff.seek(-1,2)
buff.truncate()
else:
# ignore mpultiple combiners
# but always consume the combiner
s = s[1:]
continue
else:
head = '?'
s = s[1:]
buff.write(head)
ans = buff.getvalue()
buff.close()
+2 -2
View File
@@ -1,7 +1,7 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2000-2007 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -365,7 +365,7 @@ class PdfDoc(BaseDoc.BaseDoc):
global _pil_warn
if _pil_warn:
ErrorDialog(
_("You do not have the Python Imaging Library installed "
_("You do not have the Python Imaging Library installed. "
"Images will not be added to this report"))
_pil_warn = False
return
+1 -1
View File
@@ -222,7 +222,7 @@ class SvgDrawDoc(BaseDoc.BaseDoc):
else:
self.t.write(' font-family:serif;')
self.t.write('">')
self.f.write(lines[i])
self.t.write(lines[i])
self.t.write('</text>\n')
def draw_text(self,style,text,x,y):
+3 -1
View File
@@ -1634,7 +1634,7 @@
<child>
<widget class="GtkEntry" id="longitude">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">East/West position, eg -2.88589, 2°53'9.23&quot; W or -2:53:9.23</property>
<property name="tooltip" translatable="yes">East/West position, eg -2.88589, 2°53'9.23&quot;W or -2:53:9.23</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
@@ -10308,6 +10308,7 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">3</property>
<property name="mnemonic_widget">eer_role_combo</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
@@ -10513,6 +10514,7 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">eer_date_stat</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
+8 -3
View File
@@ -170,9 +170,14 @@ def run():
try:
gramps_main.Gramps(args)
except SystemExit, msg:
log.error("Gramps terminated with the following message:\n %s."
% msg, exc_info=True)
except SystemExit, err:
# err.message may be numeric=0 or string="" or None or False
# or (), or [], .. , all of which are non-error conditions
# which need no error logging/dialog here (lower-level, maybe)
if err and err.message:
log.error("Gramps terminated with the following message:\n %r."
% err.message, exc_info=True)
gtk.main_quit()
except:
log.error("Gramps failed to start.", exc_info=True)
+23 -5
View File
@@ -83,7 +83,8 @@ def low_level(db):
('Event',db.event_map),
('Place',db.place_map),
('Source',db.source_map),
('Media',db.media_map)]:
('Media',db.media_map),
('Repository', db.repository_map)]:
print "Low-level repair: table: %s" % the_map[0]
if _table_low_level(db,the_map[1]):
@@ -798,7 +799,7 @@ class CheckIntegrity:
if not event:
# The event referenced by the family
# does not exist in the database
family.get_event_list().remove(event_ref)
family.get_event_ref_list().remove(event_ref)
self.db.commit_family(family,self.trans)
self.invalid_events.append(key)
elif type(family.get_event_ref_list()) != list:
@@ -887,7 +888,8 @@ class CheckIntegrity:
total = self.db.get_number_of_people() + self.db.get_number_of_families() + \
self.db.get_number_of_events() + self.db.get_number_of_places() + \
self.db.get_number_of_media_objects() + \
self.db.get_number_of_sources()
self.db.get_number_of_sources() + \
self.db.get_number_of_repositories()
self.progress.set_pass(_('Looking for source reference problems'),
total)
@@ -968,7 +970,7 @@ class CheckIntegrity:
item[1] not in known_handles ]
if bad_handles:
obj.remove_source_references(bad_handles)
self.db.commit_object(obj,self.trans)
self.db.commit_media_object(obj,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
@@ -988,7 +990,23 @@ 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
for handle in self.db.repository_map.keys():
self.progress.step()
info = self.db.repository_map[handle]
repo = RelLib.Repository()
repo.unserialize(info)
handle_list = repo.get_referenced_handles_recursively()
bad_handles = [ item[1] for item in handle_list
if item[0] == 'Source' and
item[1] not in known_handles ]
if bad_handles:
repo.remove_source_references(bad_handles)
self.db.commit_repository(repo,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
def check_media_references(self):
known_handles = self.db.get_media_object_handles(False)
+14
View File
@@ -369,6 +369,20 @@ class DetAncestorReport(Report):
self.doc.write_text(event.get_description())
self.doc.write_text(".")
self.doc.end_paragraph()
if self.includeNotes:
# if the event or event reference has a note attached to it,
# get the text and format it correctly
note = event.get_note()
if note != "":
self.doc.start_paragraph('DAR-MoreDetails')
self.doc.write_text(note)
self.doc.end_paragraph()
note = event_ref.get_note()
if note != "":
self.doc.start_paragraph('DAR-MoreDetails')
self.doc.write_text(note)
self.doc.end_paragraph()
def write_parents(self, person, firstName):
family_handle = person.get_main_parents_family_handle()
+14
View File
@@ -398,6 +398,20 @@ class DetDescendantReport(Report):
self.doc.write_text(".")
self.doc.end_paragraph()
if self.includeNotes:
# if the event or event reference has a note attached to it,
# get the text and format it correctly
note = event.get_note()
if note != "":
self.doc.start_paragraph('DDR-MoreDetails')
self.doc.write_text(note)
self.doc.end_paragraph()
note = event_ref.get_note()
if note != "":
self.doc.start_paragraph('DDR-MoreDetails')
self.doc.write_text(note)
self.doc.end_paragraph()
def write_parents(self, person, firstName):
family_handle = person.get_main_parents_family_handle()
if family_handle:
+10 -1
View File
@@ -355,6 +355,9 @@ GRAMPS - Relationship graph
Generated on %s.
More info:
http://www.gramps-project.org/wiki/index.php?title=Howto:_Make_a_relationship_chart
Report content options:
include URLs : %s
IDs : %s
@@ -1014,6 +1017,12 @@ class GraphVizDialog(ReportDialog):
def make_report(self):
"""Create the object that will produce the GraphViz file."""
GraphViz(self.database,self.person,self.options_class)
if self.print_report.get_active ():
try:
app = Mime.get_application("text/plain")[0]
Utils.launch(app,self.options_class.get_output())
except:
pass
#------------------------------------------------------------------------
#
@@ -1052,7 +1061,7 @@ class FormatComboBox(gtk.ComboBox):
return '.dot'
def get_printable(self):
_apptype = _options.formats[self.get_active()][3]
_apptype = "text/plain"
print_label = None
try:
mprog = Mime.get_application(_apptype)
+13 -8
View File
@@ -114,11 +114,17 @@ class IndivCompleteReport(Report):
cell.set_longlist(1)
self.doc.add_cell_style("IDS-ListCell",cell)
def write_fact(self,event):
def write_fact(self,event_ref):
event = self.database.get_event_from_handle(event_ref.ref)
if event == None:
return
text = ""
name = str(event.get_type())
if event_ref.get_role() == RelLib.EventRoleType.PRIMARY or \
event_ref.get_role() == RelLib.EventRoleType.FAMILY:
name = str(event.get_type())
else:
name = '%(event)s (%(role)s)' % {'event' : str(event.get_type()),
'role' : event_ref.get_role()}
date = DateHandler.get_date(event)
place_handle = event.get_place_handle()
@@ -167,7 +173,8 @@ class IndivCompleteReport(Report):
if parent:
self.normal_cell('%(parent)s, relationship: %(relation)s' %
{ 'parent' : parent, 'relation' : rel },mark)
{ 'parent' : parent, 'relation' : rel },
mark=mark)
else:
self.normal_cell('')
self.doc.end_row()
@@ -345,8 +352,7 @@ class IndivCompleteReport(Report):
for event_ref in family.get_event_ref_list():
if event_ref:
event = self.database.get_event_from_handle(event_ref.ref)
self.write_fact(event)
self.write_fact(event_ref)
child_ref_list = family.get_child_ref_list()
if len(child_ref_list):
@@ -407,11 +413,10 @@ class IndivCompleteReport(Report):
self.doc.end_cell()
self.doc.end_row()
event_ref_list = self.start_person.get_primary_event_ref_list()
event_ref_list = self.start_person.get_event_ref_list()
for event_ref in event_ref_list:
if event_ref:
event = self.database.get_event_from_handle(event_ref.ref)
self.write_fact(event)
self.write_fact(event_ref)
self.doc.end_table()
self.doc.start_paragraph("IDS-Normal")
self.doc.end_paragraph()
+1
View File
@@ -55,6 +55,7 @@ pkgdata_PYTHON = \
rel_fi.py\
rel_fr.py\
rel_no.py\
rel_nl.py\
rel_pt.py\
rel_sv.py\
rel_sk.py\
+419 -75
View File
@@ -74,6 +74,8 @@ import Errors
import Utils
import ImgManip
import GrampsLocale
import DateHandler
import Mime
from QuestionDialog import ErrorDialog, WarningDialog
from NameDisplay import displayer as _nd
from DateHandler import displayer as _dd
@@ -86,6 +88,8 @@ from DateHandler import displayer as _dd
_NARRATIVE = "narrative.css"
_NAME_COL = 3
MAX_IMG_WIDTH=800 # resize images that are wider than this
MAX_IMG_HEIGHT=600 # resize images that are taller than this
WIDTH=160
HEIGHT=50
VGAP=10
@@ -147,6 +151,12 @@ class BasePage:
self.encoding = options.handler.options_dict['NWEBencoding']
self.css = options.handler.options_dict['NWEBcss']
self.noid = options.handler.options_dict['NWEBnoid']
self.linkhome = options.handler.options_dict['NWEBlinkhome']
self.showbirth = options.handler.options_dict['NWEBshowbirth']
self.showdeath = options.handler.options_dict['NWEBshowdeath']
self.showspouse = options.handler.options_dict['NWEBshowspouse']
self.showparents = options.handler.options_dict['NWEBshowparents']
self.showhalfsiblings = options.handler.options_dict['NWEBshowhalfsiblings']
self.use_intro = options.handler.options_dict['NWEBintronote'] != u""
self.use_contact = options.handler.options_dict['NWEBcontact'] != u""
self.use_gallery = options.handler.options_dict['NWEBgallery']
@@ -158,7 +168,7 @@ class BasePage:
self.graphgens = options.handler.options_dict['NWEBgraphgens']
self.use_home = self.options.handler.options_dict['NWEBhomenote'] != ""
self.page_title = ""
self.warn_dir = True
self.warn_dir = True
def store_file(self,archive,html_dir,from_path,to_path):
if archive:
@@ -316,12 +326,22 @@ class BasePage:
of.write(' </div>\n')
of.write('<div id="navheader">\n')
value = unicode(time.strftime('%x',time.localtime(time.time())),
GrampsLocale.codeset)
value = DateHandler.parser.parse(time.strftime('%b %d %Y'))
value = _dd.display(value)
msg = _('Generated by <a href="http://gramps-project.org">'
'GRAMPS</a> on %(date)s') % { 'date' : value }
if self.linkhome:
home_person_handle = db.get_default_handle()
if home_person_handle:
home_person = db.get_default_person()
home_person_url = self.build_name(
self.build_path(home_person_handle, "ppl", up),
home_person.handle)
home_person_name = home_person.get_primary_name().get_regular_name()
msg += _('<br>for <a href="%s">%s</a>') % (home_person_url, home_person_name)
of.write('<div class="navbyline">%s</div>\n' % msg)
of.write('<h1 class="navtitle">%s</h1>\n' % self.title_str)
of.write('<div class="nav">\n')
@@ -345,6 +365,8 @@ class BasePage:
self.show_link(of,intro_page,_('Introduction'),path)
self.show_link(of,surname_page,_('Surnames'),path)
self.show_link(of,'individuals',_('Individuals'),path)
# some people want count to be displayed -- make it easy for them to uncomment
# self.show_link(of,'surnames_count',_('Count'),path)
self.show_link(of,'sources',_('Sources'),path)
self.show_link(of,'places',_('Places'),path)
if self.use_gallery:
@@ -444,7 +466,7 @@ class BasePage:
if format:
text = u"<pre>%s</pre>" % text
else:
text = u"</p><p>".join(text.split("\n"))
text = u"<br>".join(text.split("\n"))
of.write('<p>%s</p>\n' % text)
of.write('</div>\n')
@@ -475,6 +497,46 @@ class BasePage:
of.write('</table>\n')
of.write('</div>\n')
def display_source_refs(self,of,db,sreflist):
if not sreflist:
return
of.write('<div id="sourcerefs">\n')
of.write('<h4>%s</h4>\n' % _('Source References'))
of.write('<table class="infolist">\n')
index = 1
for sref in sreflist:
lnk = (self.cur_name, self.page_title, self.gid)
shandle = sref.get_reference_handle()
if not shandle:
continue
if self.src_list.has_key(shandle):
if lnk not in self.src_list[shandle]:
self.src_list[shandle].append(lnk)
else:
self.src_list[shandle] = [lnk]
source = self.db.get_source_from_handle(shandle)
title = source.get_title()
of.write('<tr><td class="field">')
of.write('<a name="sref%d"></a>%d.</td>' % (index,index))
of.write('<td class="field">')
self.source_link(of,source.handle,title,source.gramps_id,True)
tmp = []
confidence = Utils.confidence.get(sref.confidence, _('Unknown'))
for (label,data) in [(_('Date'),_dd.display(sref.date)),
(_('Page'),sref.page),
(_('Confidence'),confidence),
(_('Text'),sref.text)]:
if data:
tmp.append("%s: %s" % (label,data))
if len(tmp) > 0:
of.write('<br />' + '<br />'.join(tmp))
of.write('</td></tr>\n')
index += 1
of.write('</table>\n')
of.write('</div>\n')
def display_references(self,of,db,handlelist):
if not handlelist:
return
@@ -602,37 +664,123 @@ class IndividualListPage(BasePage):
of.write('<table class="infolist">\n<thead><tr>\n')
of.write('<th>%s</th>\n' % _('Surname'))
of.write('<th>%s</th>\n' % _('Name'))
of.write('<th>%s</th>\n' % _('Birth date'))
column_count = 2
if self.showbirth:
of.write('<th>%s</th>\n' % _('Birth'))
column_count += 1
if self.showdeath:
of.write('<th>%s</th>\n' % _('Death'))
column_count += 1
if self.showspouse:
of.write('<th>%s</th>\n' % _('Partner'))
column_count += 1
if self.showparents:
of.write('<th>%s</th>\n' % _('Parents'))
column_count += 1
of.write('</tr></thead>\n<tbody>\n')
person_handle_list = sort_people(db,person_handle_list)
for (surname,handle_list) in person_handle_list:
first = True
of.write('<tr><td colspan="2">&nbsp;</td></tr>\n')
of.write('<tr><td colspan="%d">&nbsp;</td></tr>\n' % column_count)
for person_handle in handle_list:
person = db.get_person_from_handle(person_handle)
if self.exclude_private:
person = ReportUtils.sanitize_person(db,person)
# surname column
of.write('<tr><td class="category">')
if first:
of.write('<a name="%s">%s</a>' % (self.lnkfmt(surname),surname))
else:
of.write('&nbsp;')
of.write('</td><td class="data">')
of.write('</td>')
# firstname column
of.write('<td class="data">')
path = self.build_path(person.handle,"ppl",False)
self.person_link(of, self.build_name(path,person.handle),
_nd.display_given(person), person.gramps_id,False)
of.write('</td><td class="field">')
of.write('</td>')
if person.handle in restrict_list:
of.write(_('restricted'))
else:
birth_ref = person.get_birth_ref()
if birth_ref:
birth = db.get_event_from_handle(birth_ref.ref)
of.write(_dd.display(birth.get_date_object()))
of.write('</td></tr>\n')
# birth column
if self.showbirth:
of.write('<td class="field">')
if person.handle in restrict_list:
of.write(_('restricted'))
else:
birth_ref = person.get_birth_ref()
if birth_ref:
birth = db.get_event_from_handle(birth_ref.ref)
of.write(_dd.display(birth.get_date_object()))
of.write('</td>')
# death column
if self.showdeath:
of.write('<td class="field">')
if person.handle in restrict_list:
of.write(_('restricted'))
else:
death_ref = person.get_death_ref()
if death_ref:
death = db.get_event_from_handle(death_ref.ref)
of.write(_dd.display(death.get_date_object()))
of.write('</td>')
# spouse (partner) column
if self.showspouse:
of.write('<td class="field">')
if person.handle in restrict_list:
of.write(_('restricted'))
else:
family_list = person.get_family_handle_list()
first_family = True
spouse_name = None
if family_list:
for family_handle in family_list:
family = db.get_family_from_handle(family_handle)
spouse_id = ReportUtils.find_spouse(person, family)
if spouse_id:
spouse = db.get_person_from_handle(spouse_id)
if self.exclude_private:
spouse = ReportUtils.sanitize_person(db, spouse)
spouse_name = spouse.get_primary_name().get_regular_name()
if not first_family:
of.write(', ')
of.write('%s' % spouse_name)
first_family = False
of.write('</td>')
# parents column
if self.showparents:
of.write('<td class="field">')
parent_handle_list = person.get_parent_family_handle_list()
if parent_handle_list:
parent_handle = parent_handle_list[0]
family = db.get_family_from_handle(parent_handle)
father_name = ''
mother_name = ''
father_id = family.get_father_handle()
mother_id = family.get_mother_handle()
father = db.get_person_from_handle(father_id)
mother = db.get_person_from_handle(mother_id)
if father and self.exclude_private:
father = ReportUtils.sanitize_person(db, father)
father_name = father.get_primary_name().get_regular_name()
if mother and self.exclude_private:
mother = ReportUtils.sanitize_person(db, mother)
mother_name = mother.get_primary_name().get_regular_name()
if mother and father:
of.write('%s, %s' % (father_name, mother_name))
elif mother:
of.write('%s' % mother_name)
elif father:
of.write('%s' % father_name)
of.write('</td>')
# finished writing all columns
of.write('</tr>\n')
first = False
of.write('</tbody>\n</table>\n')
@@ -662,10 +810,19 @@ class SurnamePage(BasePage):
of.write('<p>%s</p>\n' % msg)
of.write('<table class="infolist">\n<thead><tr>\n')
of.write('<th>%s</th>\n' % _('Name'))
of.write('<th>%s</th>\n' % _('Birth date'))
if self.showbirth:
of.write('<th>%s</th>\n' % _('Birth'))
if self.showdeath:
of.write('<th>%s</th>\n' % _('Death'))
if self.showspouse:
of.write('<th>%s</th>\n' % _('Partner'))
if self.showparents:
of.write('<th>%s</th>\n' % _('Parents'))
of.write('</tr></thead>\n<tbody>\n')
for person_handle in person_handle_list:
# firstname column
person = db.get_person_from_handle(person_handle)
if self.exclude_private:
person = ReportUtils.sanitize_person(db,person)
@@ -674,16 +831,85 @@ class SurnamePage(BasePage):
self.person_link(of, self.build_name(path,person.handle),
person.get_primary_name().get_first_name(),
person.gramps_id,False)
of.write('</td><td class="field">')
if person.handle in restrict_list:
of.write(_('restricted'))
else:
birth_ref = person.get_birth_ref()
if birth_ref:
birth = db.get_event_from_handle(birth_ref.ref)
birth_date = _dd.display(birth.get_date_object())
of.write(birth_date)
of.write('</td></tr>\n')
of.write('</td>')
# birth column
if self.showbirth:
of.write('<td class="field">')
if person.handle in restrict_list:
of.write(_('restricted'))
else:
birth_ref = person.get_birth_ref()
if birth_ref:
birth = db.get_event_from_handle(birth_ref.ref)
of.write(_dd.display(birth.get_date_object()))
of.write('</td>')
# death column
if self.showdeath:
of.write('<td class="field">')
if person.handle in restrict_list:
of.write(_('restricted'))
else:
death_ref = person.get_death_ref()
if death_ref:
death = db.get_event_from_handle(death_ref.ref)
of.write(_dd.display(death.get_date_object()))
of.write('</td>')
# spouse (partner) column
if self.showspouse:
of.write('<td class="field">')
if person.handle in restrict_list:
of.write(_('restricted'))
else:
family_list = person.get_family_handle_list()
first_family = True
spouse_name = None
if family_list:
for family_handle in family_list:
family = db.get_family_from_handle(family_handle)
spouse_id = ReportUtils.find_spouse(person, family)
if spouse_id:
spouse = db.get_person_from_handle(spouse_id)
if self.exclude_private:
spouse = ReportUtils.sanitize_person(db, spouse)
spouse_name = spouse.get_primary_name().get_regular_name()
if not first_family:
of.write(', ')
of.write('%s' % spouse_name)
first_family = False
of.write('</td>')
# parents column
if self.showparents:
of.write('<td class="field">')
parent_handle_list = person.get_parent_family_handle_list()
if parent_handle_list:
parent_handle = parent_handle_list[0]
family = db.get_family_from_handle(parent_handle)
father_name = ''
mother_name = ''
father_id = family.get_father_handle()
mother_id = family.get_mother_handle()
father = db.get_person_from_handle(father_id)
mother = db.get_person_from_handle(mother_id)
if father and self.exclude_private:
father = ReportUtils.sanitize_person(db, father)
father_name = father.get_primary_name().get_regular_name()
if mother and self.exclude_private:
mother = ReportUtils.sanitize_person(db, mother)
mother_name = mother.get_primary_name().get_regular_name()
if mother and father:
of.write('%s, %s' % (father_name, mother_name))
elif mother:
of.write('%s' % mother_name)
elif father:
of.write('%s' % father_name)
of.write('</td>')
# finished writing all columns
of.write('</tr>\n')
of.write('<tbody>\n</table>\n')
self.display_footer(of,db)
self.close_file(of)
@@ -825,9 +1051,12 @@ class MediaPage(BasePage):
BasePage.__init__(self, title, options, archive, media_list,
photo.gramps_id)
of = self.create_link_file(handle,"img")
self.db = db
self.src_list = src_list
mime_type = photo.get_mime_type()
if mime_type:
note_only = False
newpath = self.copy_source_file(handle, photo)
@@ -861,8 +1090,27 @@ class MediaPage(BasePage):
if mime_type.startswith("image/"):
of.write('<div class="centered">\n')
if target_exists:
of.write('<img ')
# if the image is spectacularly large, then force the client
# to resize it, and include a "<a href=" link to the actual
# image; most web browsers will dynamically resize an image
# and provide zoom-in/zoom-out functionality when the image
# is displayed directly
im = ImgManip.ImgManip(photo.get_path())
(width, height) = im.size()
scale = 1.0
if width > MAX_IMG_WIDTH or height > MAX_IMG_HEIGHT:
# image is too large -- scale it down and link to the full image
scale = min(float(MAX_IMG_WIDTH)/float(width), float(MAX_IMG_HEIGHT)/float(height))
width = int(width * scale)
height = int(height * scale)
of.write('<a href="../../../%s">\n' % newpath)
of.write('<img width="%d" height="%d"' % (width, height))
of.write('src="../../../%s" alt="%s" />\n' % (newpath, self.page_title))
if scale <> 1.0:
of.write('</a>\n');
else:
of.write('<br /><span>(%s)</span>' % _("The file has been moved or deleted"))
of.write('</div>\n')
@@ -906,10 +1154,10 @@ class MediaPage(BasePage):
of.write('<td class="field">%s</td>\n' % _('GRAMPS ID'))
of.write('<td class="data">%s</td>\n' % photo.gramps_id)
of.write('</tr>\n')
if not note_only:
if not note_only and not mime_type.startswith("image/"):
of.write('<tr>\n')
of.write('<td class="field">%s</td>\n' % _('File type'))
of.write('<td class="data">%s</td>\n' % photo.mime)
of.write('<td class="data">%s</td>\n' % Mime.get_description(mime_type))
of.write('</tr>\n')
date = _dd.display(photo.get_date_object())
if date != "":
@@ -922,10 +1170,27 @@ class MediaPage(BasePage):
self.display_note_object(of, photo.get_note_object())
self.display_attr_list(of, ReportUtils.sanitize_list( photo.get_attribute_list(), self.exclude_private))
self.display_media_sources(of,db,photo)
self.display_references(of,db,media_list)
self.display_footer(of,db)
self.close_file(of)
def display_media_sources(self,of,db,photo):
sreflist = photo.get_source_references()
# add the media source refs to the global list of source refs
for sref in sreflist:
msh = sref.get_reference_handle()
lnk = (self.cur_name, self.page_title, self.gid)
if self.src_list.has_key(msh):
if photo.handle not in self.src_list[msh]:
self.src_list[msh].append(lnk)
else:
self.src_list[msh] = [lnk]
# print the media source reference
self.display_source_refs(of,db,sreflist)
def display_attr_list(self,of,attrlist=None):
if not attrlist:
return
@@ -1105,7 +1370,7 @@ class IntroductionPage(BasePage):
of.write('<pre>\n%s\n</pre>\n' % text)
else:
of.write('<p>')
of.write('</p><p>'.join(text.split('\n')))
of.write('<br>'.join(text.split('\n')))
of.write('</p>')
self.display_footer(of,db)
@@ -1152,7 +1417,7 @@ class HomePage(BasePage):
of.write('<pre>\n%s\n</pre>\n' % text)
else:
of.write('<p>')
of.write('</p><p>'.join(text.split('\n')))
of.write('<br>'.join(text.split('\n')))
of.write('</p>')
self.display_footer(of,db)
@@ -1391,11 +1656,11 @@ class ContactPage(BasePage):
if nobj:
format = nobj.get_format()
text = nobj.get()
if format:
text = u"<pre>%s</pre>" % text
else:
text = u"</p><p>".join(text.split("\n"))
text = u"<br>".join(text.split("\n"))
of.write('<p>%s</p>\n' % text)
of.write('</div>\n')
@@ -1598,42 +1863,7 @@ class IndividualPage(BasePage):
sreflist = self.src_refs + self.person.get_source_references()
if not sreflist or self.restrict:
return
of.write('<div id="sourcerefs">\n')
of.write('<h4>%s</h4>\n' % _('Source References'))
of.write('<table class="infolist">\n')
index = 1
for sref in sreflist:
lnk = (self.cur_name, self.page_title, self.gid)
shandle = sref.get_reference_handle()
if not shandle:
continue
if self.src_list.has_key(shandle):
if lnk not in self.src_list[shandle]:
self.src_list[shandle].append(lnk)
else:
self.src_list[shandle] = [lnk]
source = self.db.get_source_from_handle(shandle)
title = source.get_title()
of.write('<tr><td class="field">')
of.write('<a name="sref%d"></a>%d.</td>' % (index,index))
of.write('<td class="field">')
self.source_link(of,source.handle,title,source.gramps_id,True)
tmp = []
confidence = Utils.confidence.get(sref.confidence, _('Unknown'))
for (label,data) in [(_('Date'),_dd.display(sref.date)),
(_('Page'),sref.page),
(_('Confidence'),confidence),
(_('Text'),sref.text)]:
if data:
tmp.append("%s: %s" % (label,data))
if len(tmp) > 0:
of.write('<br />' + '<br />'.join(tmp))
of.write('</td></tr>\n')
index += 1
of.write('</table>\n')
of.write('</div>\n')
self.display_source_refs(of,self.db,sreflist)
def display_ind_pedigree(self,of):
@@ -1844,6 +2074,7 @@ class IndividualPage(BasePage):
# Get the mother and father relationships
frel = ""
mrel = ""
sibling = set()
child_handle = self.person.get_handle()
child_ref_list = ReportUtils.sanitize_list( family.get_child_ref_list(),
self.exclude_private )
@@ -1867,6 +2098,7 @@ class IndividualPage(BasePage):
of.write('<tr>\n')
self.display_parent(of,mother_handle,_('Mother'),mrel)
of.write('</tr>\n')
first = False
if len(child_ref_list) > 1:
of.write('<tr>\n')
@@ -1874,9 +2106,53 @@ class IndividualPage(BasePage):
of.write('<td class="data">\n')
for child_ref in child_ref_list:
child_handle = child_ref.ref
sibling.add(child_handle) # remember that we've already "seen" this child
if child_handle != self.person.handle:
self.display_child_link(of,child_handle)
of.write('</td>\n</tr>\n')
# Also try to identify half-siblings
other_siblings = set()
# if we have a known father...
if father_handle and self.showhalfsiblings:
# 1) get all of the families in which this father is involved
# 2) get all of the children from those families
# 3) if the children are not already listed as siblings...
# 4) then remember those children since we're going to list them
father = self.db.get_person_from_handle(father_handle)
for family_handle in father.get_family_handle_list():
family = self.db.get_family_from_handle(family_handle)
step_child_ref_list = ReportUtils.sanitize_list(family.get_child_ref_list(), self.exclude_private)
for step_child_ref in step_child_ref_list:
step_child_handle = step_child_ref.ref
if step_child_handle not in sibling:
if step_child_handle != self.person.handle:
# we have a new step/half sibling
other_siblings.add(step_child_ref.ref)
# do the same thing with the mother (see "father" just above):
if mother_handle and self.showhalfsiblings:
mother = self.db.get_person_from_handle(mother_handle)
for family_handle in mother.get_family_handle_list():
family = self.db.get_family_from_handle(family_handle)
step_child_ref_list = ReportUtils.sanitize_list(family.get_child_ref_list(), self.exclude_private)
for step_child_ref in step_child_ref_list:
step_child_handle = step_child_ref.ref
if step_child_handle not in sibling:
if step_child_handle != self.person.handle:
# we have a new step/half sibling
other_siblings.add(step_child_ref.ref)
# now that we have all of the step-siblings/half-siblings, print them out
if len(other_siblings) > 0:
of.write('<tr>\n')
of.write('<td class="field">%s</td>\n' % _("Other Siblings"))
of.write('<td class="data">\n')
for child_handle in other_siblings:
self.display_child_link(of, child_handle)
of.write('</td>\n</tr>\n')
of.write('<tr><td colspan="3">&nbsp;</td></tr>\n')
of.write('</table>\n')
of.write('</div>\n')
@@ -1979,7 +2255,7 @@ class IndividualPage(BasePage):
if format:
of.write( u"<pre>%s</pre>" % text )
else:
of.write( u"</p><p>".join(text.split("\n")))
of.write( u"<br>".join(text.split("\n")))
of.write('</td>\n</tr>\n')
def pedigree_person(self,of,person,is_spouse=False):
@@ -2054,6 +2330,21 @@ class IndividualPage(BasePage):
else:
text = '\n'
text += self.get_citation_links( event.get_source_references() )
# if the event has a note attached to it, get the text and format it correctly
note_obj = event.get_note_object()
if note_obj:
note_text = note_obj.get()
if note_text != '':
if note_obj.get_format():
text += '<pre>\n'
text += note_text
text += '</pre>\n'
else:
text += '<p>'
text += u"<br>".join(note_text.split("\n"))
text += '</p>'
return text
def get_citation_links(self, source_ref_list):
@@ -2118,6 +2409,12 @@ class WebReport(Report):
NWEBintronote
NWEBhomenote
NWEBnoid
NWEBlinkhome
NWEBshowbirth
NWEBshowdeath
NWEBshowspouse
NWEBshowparents
NWEBshowhalfsiblings
"""
self.database = database
@@ -2137,6 +2434,12 @@ class WebReport(Report):
self.restrict_years = options.handler.options_dict['NWEBrestrictyears']
self.exclude_private = not options.handler.options_dict['NWEBincpriv']
self.noid = options.handler.options_dict['NWEBnoid']
self.linkhome = options.handler.options_dict['NWEBlinkhome']
self.showbirth = options.handler.options_dict['NWEBshowbirth']
self.showdeath = options.handler.options_dict['NWEBshowdeath']
self.showspouse = options.handler.options_dict['NWEBshowspouse']
self.showparents = options.handler.options_dict['NWEBshowparents']
self.showhalfsiblings = options.handler.options_dict['NWEBshowhalfsiblings']
self.title = options.handler.options_dict['NWEBtitle']
self.sort = Sort.Sort(self.database)
self.inc_gallery = options.handler.options_dict['NWEBgallery']
@@ -2228,9 +2531,9 @@ class WebReport(Report):
self.person_pages(ind_list, restrict_list, place_list, source_list, archive)
self.surname_pages(ind_list, restrict_list, archive)
self.place_pages(place_list, source_list, archive)
self.source_pages(source_list, self.photo_list, archive)
if self.inc_gallery:
self.gallery_pages(self.photo_list, source_list, archive)
self.source_pages(source_list, self.photo_list, archive)
if archive:
archive.close()
@@ -2293,7 +2596,10 @@ class WebReport(Report):
def person_pages(self, ind_list, restrict_list, place_list, source_list, archive):
self.progress.set_pass(_('Creating individual pages'),len(ind_list))
self.progress.set_pass(_('Creating individual pages'),len(ind_list) + 1)
self.progress.step() # otherwise the progress indicator sits at 100%
# for a short while from the last step we did,
# which was to apply the privacy filter
IndividualListPage(
self.database, self.title, ind_list, restrict_list,
@@ -2453,6 +2759,12 @@ class WebReportOptions(ReportOptions):
'NWEBincpriv' : 0,
'NWEBnonames' : 0,
'NWEBnoid' : 0,
'NWEBlinkhome' : 0,
'NWEBshowbirth' : 1,
'NWEBshowdeath' : 0,
'NWEBshowspouse' : 0,
'NWEBshowparents' : 0,
'NWEBshowhalfsiblings' : 0,
'NWEBcontact' : '',
'NWEBgallery' : 1,
'NWEBheader' : '',
@@ -2560,6 +2872,24 @@ class WebReportOptions(ReportOptions):
self.inc_download = gtk.CheckButton(download_msg)
self.inc_download.set_active(self.options_dict['NWEBdownload'])
self.linkhome = gtk.CheckButton(_('Include link to home person on every page'))
self.linkhome.set_active(self.options_dict['NWEBlinkhome'])
self.showbirth = gtk.CheckButton(_('Include a column for birth dates on the index pages'))
self.showbirth.set_active(self.options_dict['NWEBshowbirth'])
self.showdeath = gtk.CheckButton(_('Include a column for death dates on the index pages'))
self.showdeath.set_active(self.options_dict['NWEBshowdeath'])
self.showspouse = gtk.CheckButton(_('Include a column for partners on the index pages'))
self.showspouse.set_active(self.options_dict['NWEBshowspouse'])
self.showparents = gtk.CheckButton(_('Include a column for parents on the index pages'))
self.showparents.set_active(self.options_dict['NWEBshowparents'])
self.showhalfsiblings = gtk.CheckButton(_('Include half-brothers and half-sisters as siblings'))
self.showhalfsiblings.set_active(self.options_dict['NWEBshowhalfsiblings'])
# FIXME: document this:
# 0 -- no images of any kind
# 1 -- no living images, but some images
@@ -2667,6 +2997,14 @@ class WebReportOptions(ReportOptions):
dialog.add_frame_option(title,None,self.restrict_living)
dialog.add_frame_option(title,None,self.hbox)
title = _("Advanced Options")
dialog.add_frame_option(title,None,self.linkhome)
dialog.add_frame_option(title,None,self.showbirth)
dialog.add_frame_option(title,None,self.showdeath)
dialog.add_frame_option(title,None,self.showspouse)
dialog.add_frame_option(title,None,self.showparents)
dialog.add_frame_option(title,None,self.showhalfsiblings)
def restrict_toggled(self,obj):
self.restrict_years.set_sensitive(obj.get_active())
@@ -2678,6 +3016,12 @@ class WebReportOptions(ReportOptions):
self.options_dict['NWEBrestrictyears'] = int(self.restrict_years.get_text())
self.options_dict['NWEBincpriv'] = int(not self.no_private.get_active())
self.options_dict['NWEBnoid'] = int(self.noid.get_active())
self.options_dict['NWEBlinkhome'] = int(self.linkhome.get_active())
self.options_dict['NWEBshowbirth'] = int(self.showbirth.get_active())
self.options_dict['NWEBshowdeath'] = int(self.showdeath.get_active())
self.options_dict['NWEBshowspouse'] = int(self.showspouse.get_active())
self.options_dict['NWEBshowparents'] = int(self.showparents.get_active())
self.options_dict['NWEBshowhalfsiblings'] = int(self.showhalfsiblings.get_active())
self.options_dict['NWEBcontact'] = unicode(self.contact.get_handle())
self.options_dict['NWEBgallery'] = int(self.include_gallery.get_active())
self.options_dict['NWEBheader'] = unicode(self.header.get_handle())
+11 -7
View File
@@ -79,12 +79,6 @@ class RelCalc(Tool.Tool, ManagedWindow.ManagedWindow):
Tool.Tool.__init__(self, dbstate, options_class, name)
ManagedWindow.ManagedWindow.__init__(self, uistate, [], self.__class__)
if not self.person:
ErrorDialog(_('Active person has not been set'),
_('You must select an active person for this '
'tool to work properly.'))
return
self.RelClass = relationship_class
self.relationship = self.RelClass(self.db)
@@ -93,7 +87,9 @@ class RelCalc(Tool.Tool, ManagedWindow.ManagedWindow):
glade_file = "%s/relcalc.glade" % base
self.glade = gtk.glade.XML(glade_file,"relcalc","gramps")
name = NameDisplay.displayer.display(self.person)
name = ''
if self.person:
name = NameDisplay.displayer.display(self.person)
self.title = _('Relationship calculator: %(person_name)s'
) % {'person_name' : name}
window = self.glade.get_widget('relcalc')
@@ -132,6 +128,14 @@ class RelCalc(Tool.Tool, ManagedWindow.ManagedWindow):
"on_close_clicked" : self.close,
})
if not self.person:
self.window.hide()
ErrorDialog(_('Active person has not been set'),
_('You must select an active person for this '
'tool to work properly.'))
self.close()
return
self.show()
def build_menu_names(self,obj):
+2 -2
View File
@@ -456,7 +456,7 @@ class GeneWebWriter:
def get_ref_name(self,person):
surname = self.rem_spaces( person.get_primary_name().get_surname())
firstname = "Living"
firstname = _("Living")
if not (Utils.probably_alive(person,self.db) and self.restrict and self.living):
firstname = self.rem_spaces( person.get_primary_name().get_first_name())
if not self.person_ids.has_key(person.get_handle()):
@@ -466,7 +466,7 @@ class GeneWebWriter:
def get_child_ref_name(self,person,father_lastname):
surname = self.rem_spaces( person.get_primary_name().get_surname())
firstname = "Living"
firstname = _("Living")
if not (Utils.probably_alive(person,self.db) and self.restrict and self.living):
firstname = self.rem_spaces( person.get_primary_name().get_first_name())
if not self.person_ids.has_key(person.get_handle()):
+146 -149
View File
@@ -40,13 +40,13 @@ from PluginUtils import register_relcalc
#-------------------------------------------------------------------------
_removed_level = [ " ",
" eerste graad",
" tweede graad",
" derde graad",
" vierde graad",
" vijfde graad",
" zesde graad",
" zevende graad",
" eerste",
" tweede",
" derde",
" vierde",
" vijfde",
" zesde",
" zevende",
" achtste",
" negende",
" tiende",
@@ -81,7 +81,7 @@ _parents_level = [ "",
"oudovergrootouders",
"oudbetovergrootouders",
"stamouders",
"stamgrootouders",
"stamgrootouders", # gen 10
"stamovergrootouders",
"stambetovergrootouders",
"stamoudouders",
@@ -91,7 +91,7 @@ _parents_level = [ "",
"edelouders",
"edelgrootoders",
"edelovergrootoudouders",
"edelbetovergrootouders",
"edelbetovergrootouders", # gen 20
"edeloudouders",
"edeloudgrootouders",
"edeloudvergrootouders",
@@ -103,66 +103,66 @@ _parents_level = [ "",
"edelstamoudouders" ]
_father_level = [ "",
"vader (graad 1)",
"grootvader (graad 2)",
"overgrootvader (graad 3)",
"betovergrootvader (graad 4)",
"oudvader (graad 5)",
"oudgrootvader (graad 6)",
"oudovergrootvader(graad 7)",
"oudbetovergrootvader (graad 8)",
"stamvader graad 9)",
"stamgrootvader",
"stamovergrootvader",
"stambetovergrootvader",
"stamoudvader",
"stamoudgrootvader",
"stamoudovergrootvader",
"stamoudbetovergrootvader",
"edelvader",
"edelgrootvader",
"edelovergrootoudvader",
"edelbetovergrootvader",
"edeloudvader",
"edeloudgrootvader",
"edeloudvergrootvader",
"edeloudbetovergrootvader",
"edelstamvader",
"edelstamgrootvader",
"edelstamovergrootvader",
"edelstambetovergrootvader",
"edelstamoudvader" ]
"vader",
"grootvader",
"overgrootvader",
"betovergrootvader",
"oudvader (generatie 5)",
"oudgrootvader (generatie 6)",
"oudovergrootvader (generatie 7)",
"oudbetovergrootvader (generatie 8)",
"stamvader (generatie 9)",
"stamgrootvader (generatie 10)",
"stamovergrootvader (generatie 11)",
"stambetovergrootvader (generatie 12)",
"stamoudvader (generatie 13)",
"stamoudgrootvader (generatie 14)",
"stamoudovergrootvader (generatie 15)",
"stamoudbetovergrootvader (generatie 16)",
"edelvader (generatie 17)",
"edelgrootvader (generatie 18)",
"edelovergrootoudvader (generatie 19)",
"edelbetovergrootvader (generatie 20)",
"edeloudvader (generatie 21)",
"edeloudgrootvader (generatie 22)",
"edeloudvergrootvader (generatie 23)",
"edeloudbetovergrootvader (generatie 24)",
"edelstamvader (generatie 25)",
"edelstamgrootvader (generatie 26)",
"edelstamovergrootvader (generatie 27)",
"edelstambetovergrootvader (generatie 28)",
"edelstamoudvader (generatie 29)" ]
_mother_level = [ "",
"moeder (graad 1)",
"grootmoeder (graad 2)",
"overgrootmoeder (graad 3)",
"betovergrootmoeder (graad 4)",
"oudmoeder",
"oudgrootmoeder",
"oudovergrootmoeder",
"oudbetovergrootmoeder",
"stammoeder",
"stamgrootmoeder",
"stamovergrootmoeder",
"stambetovergrootmoeder",
"stamoudmoeder",
"stamoudgrootmoeder",
"stamoudovergrootmoeder",
"stamoudbetovergrootmoeder",
"edelmoeder",
"edelgrootmoeder",
"edelovergrootoudmoeder",
"edelbetovergrootmoeder",
"edeloudmoeder",
"edeloudgrootmoeder",
"edeloudvergrootmoeder",
"edeloudbetovergrootmoeder",
"edelstammoeder",
"edelstamgrootmoeder",
"edelstamovergrootmoeder",
"edelstambetovergrootmoeder",
"edelstamoudmoeder" ]
"moeder ",
"grootmoeder",
"overgrootmoeder",
"betovergrootmoeder",
"oudmoeder (generatie 5)",
"oudgrootmoeder (generatie 6)",
"oudovergrootmoeder (generatie 7)",
"oudbetovergrootmoeder (generatie 8)",
"stammoeder (generatie 9)",
"stamgrootmoeder (generatie 10)",
"stamovergrootmoeder (generatie 11)",
"stambetovergrootmoeder (generatie 12)",
"stamoudmoeder (generatie 13)",
"stamoudgrootmoeder (generatie 14)",
"stamoudovergrootmoeder (generatie 15)",
"stamoudbetovergrootmoeder (generatie 16)",
"edelmoeder (generatie 17)",
"edelgrootmoeder (generatie 18)",
"edelovergrootoudmoeder (generatie 19)",
"edelbetovergrootmoeder (generatie 20)",
"edeloudmoeder (generatie 21)",
"edeloudgrootmoeder (generatie 22)",
"edeloudvergrootmoeder (generatie 23)",
"edeloudbetovergrootmoeder (generatie 24)",
"edelstammoeder (generatie 25)",
"edelstamgrootmoeder (generatie 26)",
"edelstamovergrootmoeder (generatie 27)",
"edelstambetovergrootmoeder (generatie 28)",
"edelstamoudmoeder (generatie 29)" ]
_son_level = [ "",
"zoon",
@@ -178,22 +178,6 @@ _daughter_level = [ "",
"achterachterkleindochter",
"achterachterachterkleindochter"]
##_sister_level = [ "",
## "zuster",
## "tante",
## "groottante",
## "overgroottante" ,
## "betovergroottante",
## "oudtante"]
##_brother_level = [ "",
## "broer",
## "oom",
## "grootoom",
## "overgrootoom",
## "betovergrootoom",
## "oudoom" ]
_nephew_level = [ "",
"neef",
"achterneef",
@@ -202,19 +186,20 @@ _nephew_level = [ "",
_niece_level = [ "",
"nicht",
"achternicht",
"achterachtenicht"]
"achterachternicht"]
_aunt_level = [ "",
"tante",
"groottante",
"overgroottante",
"betovergroottante",
"oudtante"]
"oudtante (generatie 5)"]
_uncle_level = [ "",
"oom",
"grootoom",
"overgrootoom",
"betovergrootoom"]
"betovergrootoom",
"oudoom (generatie 5)"]
#-------------------------------------------------------------------------
#
#
@@ -226,72 +211,103 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
Relationship.RelationshipCalculator.__init__(self,db)
def get_parents(self, level):
if level>len(_parents_level)-1:
return "verre voorouders"
if level > len(_parents_level)-1:
return "verre voorouders (%d generaties)" % level
else:
return _parents_level[level]
def get_father(self, level):
if level>len(_father_level)-1:
return "verre voorouder"
if level > len(_father_level)-1:
return "verre voorvader (%d generaties)" % level
else:
return _father_level[level]
def get_son(self, level):
if level>len(_son_level)-1:
return "verre afstammeling"
if level < len(_son_level):
return _son_level[level]
else:
return _son_level[level]
return "verre achterkleinzoon (%d generaties)" % level
def get_mother(self,level):
if level>len(_mother_level)-1:
return "verre voorouder"
if level > len(_mother_level)-1:
return "verre voormoeder (%d generaties)" % level
else:
return _mother_level[level]
def get_daughter(self, level):
if level>len(_daughter_level)-1:
return "verre afstammelinge"
if level > len(_daughter_level)-1:
return "verre achterkleindochter (%d generaties)" % level
else:
return _daughter_level[level]
def get_aunt(self, level, removed):
if level>len(_aunt_level)-1 or removed > len(_removed_level) -1:
return "verre voorouder"
if removed == 1 and level < len(_aunt_level):
return _aunt_level[level]
elif level > len(_aunt_level)-1 or removed > len(_removed_level) -1:
return "verre tante (%d generaties, %d graden)" % (level, removed)
elif level > len(_aunt_level)-1:
return "verre tante van de%s graad (%d generaties)" \
% (_removed_level[removed], level)
else:
return _aunt_level[level] + _removed_level[removed]
return _aunt_level[level] + _removed_level[removed] + " graad"
def get_uncle(self, level, removed):
if level>len(_uncle_level)-1 or removed > len(_removed_level) -1:
return "verre voorouder"
if removed == 1 and level < len(_uncle_level):
return _uncle_level[level]
elif level > len(_uncle_level)-1 or removed > len(_removed_level) -1:
return "verre oom (%d generaties, %d graden)" % (level, removed)
elif level > len(_uncle_level)-1:
return "verre oom van de%s graad (%d generaties)" \
% (_removed_level[removed], level)
else:
return _uncle_level[level] + _removed_level[removed]
return _uncle_level[level] + _removed_level[removed] + " graad"
def get_nephew(self,level, removed):
if level>len(_nephew_level)-1 or removed > len(_removed_level) -1:
return "verre voorouder"
def get_nephew(self, level, removed=1):
if removed == 1 and level < len(_nephew_level):
return _nephew_level[level]
elif level > len(_nephew_level)-1 or removed > len(_removed_level) -1:
return "verre neef (%d generaties, %d graden)" % (level, removed)
elif level > len(_nephew_level)-1:
return "verre neef van de%s graad (%d generaties)" \
% (_removed_level[removed], level)
else:
return _nephew_level[level] + _removed_level[removed]
return _nephew_level[level] + _removed_level[removed] + " graad"
def get_niece(self,level, removed):
if level>len(_niece_level)-1 or removed > len(_removed_level) -1:
return "verre afstammelinge"
def get_niece(self, level, removed=1):
if removed == 1 and level < len(_niece_level):
return _niece_level[level]
if level > len(_niece_level)-1 or removed > len(_removed_level) -1:
return "verre nicht (%d generaties, %d graden)" % (level, removed)
elif level > len(_niece_level)-1:
return "verre nicht van de%s graad (%d generaties)" \
% (_removed_level[removed], level)
else:
return _niece_level[level] + _removed_level[removed]
return _niece_level[level] + _removed_level[removed] + " graad"
def get_male_cousin(self,removed):
if removed>len(_removed_level)-1:
return "verre afstammeling"
"""Specific Dutch thing, the nieces/nephews on same level are called
going sideways in a branch as the nieces/newphews going downward
from your brother/sisters. This used to be called "kozijn"
"""
removed = removed - 1
if removed > len(_removed_level)-1:
return "verre neef (kozijn, %d graden)" % removed
elif removed == 0:
return "broer"
else:
return "neef "+_removed_level[removed]
return "neef (kozijn)"+_removed_level[removed] + " graad"
def get_female_cousin(self,removed):
if removed>len(_removed_level)-1:
return "verre afstammelinge"
elif removed == 0:
return " zus"
"""Specific Dutch thing, the nieces/nephews on same level are called
going sideways in a branch as the nieces/newphews going downward
from your brother/sisters. This used to be called "kozijn"
"""
removed = removed - 1
if removed > len(_removed_level)-1:
return "verre nicht (kozijn, %d graden)" % removed
elif removed == 0:
return "zus"
else:
return "nicht "+ _removed_level[removed]
return "nicht (kozijn)"+ _removed_level[removed] + " graad"
def get_relationship(self,orig_person,other_person):
"""
@@ -323,6 +339,7 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
secondRel = len(secondRel)
if firstRel == 0:
#other person is ancestor
if secondRel == 0:
return ('',common)
elif other_person.get_gender() == RelLib.Person.MALE:
@@ -330,51 +347,31 @@ class RelationshipCalculator(Relationship.RelationshipCalculator):
else:
return (self.get_mother(secondRel), common)
elif secondRel == 0:
#other person is descendant
if other_person.get_gender() == RelLib.Person.MALE:
return (self.get_son(firstRel), common)
else:
return (self.get_daughter(firstRel), common)
elif secondRel > firstRel:
#other person is higher in the branch, in english uncle/aunt or
#cousin up, in dutch always 'oom/tante'
if other_person.get_gender() == RelLib.Person.MALE:
return (self.get_uncle(secondRel - firstRel,firstRel), common)
else:
return (self.get_aunt(secondRel - firstRel, firstRel), common)
elif secondRel < firstRel:
#other person is lower in the branch, in english niece/nephew or
#cousin down, in dutch always 'neef/nicht'
if other_person.get_gender() == RelLib.Person.MALE:
return (self.get_nephew(firstRel - secondRel, secondRel), common)
else:
return (self.get_niece(firstRel - secondRel, secondRel), common)
else:
if other_person.get_gender() == RelLib.Person.MALE:
return (self.get_male_cousin(firstRel -1), common)
else:
return (self.get_female_cousin(firstRel -1), common)
## elif firstRel == 2 and secondRel == 2:
## if other_person.get_gender() == RelLib.Person.MALE:
## return ('de neef',common)
## else:
## return ('de nicht',common)
## elif firstRel == 3 and secondRel == 2:
## if other_person.get_gender() == RelLib.Person.MALE:
## return ('neef',common)
## else:
## return ('nicht',common)
## elif firstRel == 2 and secondRel == 3:
## if other_person.get_gender() == RelLib.Person.MALE:
## return ('de oom',common)
## else:
## return ('de tante',common)
## else:
## if other_person.get_gender() == RelLib.Person.MALE:
## if firstRel+secondRel>len(_level_name)-1:
## return (self.get_male_cousin(firstRel+secondRel),common)
## else:
## return ('verre neef',common)
## else:
## if firstRel+secondRel>len(_level_name)-1:
## return (self.get_female_cousin(firstRel+secondRel),common)
## else:
## return ('verre nicht',common)
# people on the same level secondRel == firstRel
if other_person.get_gender() == RelLib.Person.MALE:
return (self.get_male_cousin(firstRel), common)
else:
return (self.get_female_cousin(firstRel), common)
#-------------------------------------------------------------------------
#