* various: merge changes made in gramps20 up until R2_0_10_real tag.
* configure.in: Bump up release number. * Release: Version 2.0.10 "Holy Hand Grenade of Antioch" released. svn: r6011
This commit is contained in:
parent
c4010b28a4
commit
2b96e371e1
@ -1,3 +1,6 @@
|
||||
2006-02-28 Alex Roitman <shura@gramps-project.org>
|
||||
* various: merge changes made in gramps20 up until R2_0_10_real tag.
|
||||
|
||||
2006-02-25 Don Allingham <don@gramps-project.org>
|
||||
* src/DisplayTabs.py: repository reference editor
|
||||
* src/EditRepository.py: repository reference editor
|
||||
@ -1316,6 +1319,10 @@
|
||||
2005-12-12 Alex Roitman <shura@gramps-project.org>
|
||||
* configure.in: bump up the version number.
|
||||
|
||||
2006-02-27 Alex Roitman <shura@gramps-project.org>
|
||||
* configure.in: Bump up release number.
|
||||
* Release: Version 2.0.10 "Holy Hand Grenade of Antioch" released.
|
||||
|
||||
2005-12-11 Don Allingham <don@gramps-project.org>
|
||||
* Release: Version 2.0.9 "Nobody expects the Spanish inquisition!"
|
||||
released.
|
||||
|
12
NEWS
12
NEWS
@ -1,3 +1,15 @@
|
||||
Version 2.0.10 -- the "Holy Hand Grenade of Antioch" release
|
||||
* Date handler for Lithuanian language (Arturas Sleinius).
|
||||
* New Calendar graphical report (Doug Blank).
|
||||
* Multiple tool fixes.
|
||||
* GEDCOM import and export improvements.
|
||||
* Proper rebuilding of secondary indices.
|
||||
* Open Document Format support in reports (Serge Noiraud, Brian Matherly).
|
||||
* Multiple report fixes.
|
||||
* Fix for low-level duplicate records.
|
||||
* User Manual updates.
|
||||
* An insane number of bug fixes.
|
||||
|
||||
Version 2.0.9 -- the "Nobody expects the Spanish inquisition!" release
|
||||
* Incremental interface improvements.
|
||||
* Automated testing added, based on the CLI functionality.
|
||||
|
@ -239,6 +239,8 @@ src/data/Makefile
|
||||
src/data/templates/Makefile
|
||||
src/po/Makefile
|
||||
doc/Makefile
|
||||
doc/man/Makefile
|
||||
doc/man/fr/Makefile
|
||||
doc/gramps-manual/Makefile
|
||||
doc/gramps-manual/C/Makefile
|
||||
doc/gramps-manual/fr/Makefile
|
||||
|
@ -1,13 +1,4 @@
|
||||
# Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = gramps-manual
|
||||
|
||||
man_IN_FILES = gramps.1.in
|
||||
man_MANS = $(man_IN_FILES:.1.in=.1)
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(man_IN_FILES) xmldocs.make omf.make
|
||||
|
||||
gramps.1: $(top_builddir)/config.status gramps.1.in
|
||||
cd $(top_builddir) && CONFIG_FILES=doc/$@ $(SHELL) ./config.status
|
||||
|
||||
CLEANFILES=$(man_MANS)
|
||||
SUBDIRS = gramps-manual man
|
||||
EXTRA_DIST = xmldocs.make omf.make
|
||||
|
@ -47,7 +47,7 @@
|
||||
of Linux to another. On the default GNOME desktop, you'll
|
||||
find &app; in the
|
||||
<menuchoice><guimenu>Applications</guimenu><guisubmenu>Other</guisubmenu></menuchoice>
|
||||
menu. </para>
|
||||
menu.</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -116,8 +116,7 @@
|
||||
<screenshot>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="figures/researcher.png" format="PNG"
|
||||
width="510" depth="369" scale="75"/>
|
||||
<imagedata fileref="figures/researcher.png" format="PNG"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>Shows Researcher Information Window. </phrase>
|
||||
@ -166,8 +165,7 @@
|
||||
|
||||
<para>To open a database that you have recently opened, choose the
|
||||
top selection, select your database from the menu and
|
||||
click <guibutton>OK</guibutton>. &app; will then ask you to specify
|
||||
the name of the database you wish to open. </para>
|
||||
click <guibutton>OK</guibutton>.</para>
|
||||
|
||||
<para>To open an existing database you have not recently opened,
|
||||
choose the middle selection and click
|
||||
|
File diff suppressed because it is too large
Load Diff
8115
doc/gramps-manual/C/manual.xml
Normal file
8115
doc/gramps-manual/C/manual.xml
Normal file
File diff suppressed because it is too large
Load Diff
@ -101,7 +101,7 @@
|
||||
immediately applied; this means that clicking
|
||||
<guibutton>OK</guibutton> in the Person, Family, Source,
|
||||
Place, Media object, or Event editor immediately records
|
||||
changes in the database. </para>
|
||||
changes to the database. </para>
|
||||
|
||||
<para>In previous versions, you could "quit without
|
||||
saving." This option no longer exists per se; however,
|
||||
@ -177,7 +177,7 @@
|
||||
<para>Removal of the Save function and addition of Undo.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Proper window management and removal of most modal windows.</para>
|
||||
<para>Proper window management.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Support for Tip of the Day.</para>
|
||||
@ -229,7 +229,7 @@
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>It is possible to generate reports from the command
|
||||
line, without launching the interactive GRAMPS
|
||||
line, without launching an interactive GRAMPS
|
||||
session.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1485,7 +1485,7 @@
|
||||
</variablelist>
|
||||
</sect3>
|
||||
<sect3 id="cmdplug-id29">
|
||||
<title>Mémoriser le genre de statistiques ???</title>
|
||||
<title>Tableau statistique croisé du prénom et du sexe</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><command>name</command>:</term>
|
||||
|
@ -2285,7 +2285,119 @@ directement vers n'importe quelle personne sélectionnée récemment.
|
||||
</para>
|
||||
|
||||
|
||||
<!-- =============== Usage Sub-subsection ================ -->
|
||||
<!-- =============== Usage Sub-subsection ================ -->
|
||||
|
||||
<sect2 id="subst-values">
|
||||
<title>Valeurs de substitution</title>
|
||||
<para>
|
||||
La plupart des rapports graphiques vous permettent de personnaliser les informations affichées. Les variables de substitution sont représentées par des symboles particuliers. Il existe 2 styles de variables
|
||||
Leurs différences se trouvent dans la gestion des données vides.
|
||||
</para>
|
||||
<para>
|
||||
Le premier style est une variable précédée par '$'. Si cette variable se rapporte à une chaîne vide alors elle sera remplacée par une chaîne vide. Le second style est une variable précédée par '%'. Si cette variable se rapporte à une chaîne vide alors la ligne contenant la variable sera retirée lors de la sortie.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>$n/%n</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le nom de l'individu : Prénom Nom
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$N/%N</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le nom de l'individu : Nom Prénom
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$i/%i</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche l'ID GRAMPS associé à l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$b/%b</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche la date de naissance de l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$B/%B</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le lieu de naissance de l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$d/%d</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche la date de décès de l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$D/%D</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le lieu de décès de l'individu.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$s/%s</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le nom du conjoint préféré : Prénom Nom
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$S/%S</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le nom du conjoint préféré : Nom Prénom
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$m/%m</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche la date de marriage de l'individu et de son conjoint préféré.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>$M/%M</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Affiche le lieu du marriage de l'individu et de son conjoint préféré.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="rep-books">
|
||||
<title>Livres</title>
|
||||
<para>Il n'y a actuellement qu'une seule édition dans cette catégorie : l'édition Livre. </para>
|
||||
|
3
doc/man/.cvsignore
Normal file
3
doc/man/.cvsignore
Normal file
@ -0,0 +1,3 @@
|
||||
gramps.1
|
||||
Makefile.in
|
||||
Makefile
|
13
doc/man/Makefile.am
Normal file
13
doc/man/Makefile.am
Normal file
@ -0,0 +1,13 @@
|
||||
# Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = fr
|
||||
|
||||
man_IN_FILES = gramps.1.in
|
||||
man_MANS = $(man_IN_FILES:.1.in=.1)
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(man_IN_FILES)
|
||||
|
||||
gramps.1: $(top_builddir)/config.status gramps.1.in
|
||||
cd $(top_builddir) && CONFIG_FILES=doc/man/$@ $(SHELL) ./config.status
|
||||
|
||||
CLEANFILES=$(man_MANS)
|
3
doc/man/fr/.cvsignore
Normal file
3
doc/man/fr/.cvsignore
Normal file
@ -0,0 +1,3 @@
|
||||
gramps.1
|
||||
Makefile.in
|
||||
Makefile
|
13
doc/man/fr/Makefile.am
Normal file
13
doc/man/fr/Makefile.am
Normal file
@ -0,0 +1,13 @@
|
||||
# Process this file with automake to produce Makefile.in
|
||||
|
||||
man_IN_FILES = gramps.1.in
|
||||
man_MANS = $(man_IN_FILES:.1.in=.1)
|
||||
|
||||
mandir = @mandir@/fr
|
||||
|
||||
EXTRA_DIST = $(man_MANS) $(man_IN_FILES)
|
||||
|
||||
gramps.1: $(top_builddir)/config.status gramps.1.in
|
||||
cd $(top_builddir) && CONFIG_FILES=doc/man/fr/$@ $(SHELL) ./config.status
|
||||
|
||||
CLEANFILES=$(man_MANS)
|
214
doc/man/fr/gramps.1.in
Normal file
214
doc/man/fr/gramps.1.in
Normal file
@ -0,0 +1,214 @@
|
||||
.TH gramps 1 "@VERSION@" "Janvier 2006" "@VERSION@"
|
||||
.SH NOM
|
||||
gramps \- GRAMPS est une application de généalogie. GRAMPS est l'acronyme de Genealogical Research and Analysis Management Programming System (Systeme de Programmation pour Recherche, Analyse et Gestion de données généalogiques)
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B gramps
|
||||
.RB [ \-?|\-\^\-help ]
|
||||
.RB [ \-\^\-usage ]
|
||||
.RB [ \-\^\-version ]
|
||||
.RB [ \-O|\-\^\-open=
|
||||
.IR FICHIER
|
||||
.RB [ \-f|\-\^\-format=
|
||||
.IR FORMAT ]]
|
||||
.RB [ \-i|\-\^\-import=
|
||||
.IR FICHIER
|
||||
.RB [ \-f|\-\^\-format=
|
||||
.IR FORMAT ]]
|
||||
.RB [ \-i|\-\^\-import=
|
||||
.IR ... ]
|
||||
.RB [ \-o|\-\^\-output=
|
||||
.IR FICHIER
|
||||
.RB [ \-f|\-\^\-format=
|
||||
.IR FORMAT ]]
|
||||
.RB [ \-a|\-\^\-action=
|
||||
.IR ACTION ]
|
||||
.RB [ \-p|\-\^\-options=
|
||||
.IR OPTIONSTRING ]]
|
||||
.RB [
|
||||
.IR FICHIER
|
||||
.RB ]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fIGramps\fP est un programme Libre/OpenSource de généalogie. Il est écrit en python,
|
||||
et utilise une interface GTK+/GNOME.
|
||||
Gramps est semblable à d'autres programmes de généalogie tel que \fIFamily Tree Maker (FTM)\fR, \fIPersonal Ancestral
|
||||
Files\fR, ou le programme GNU Geneweb.
|
||||
Il peut importer/exporter le format le plus utilisé par les autres logiciels de généalogie : GEDCOM.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI gramps " FICHIER"
|
||||
Si \fIFICHIER\fR est désigné (sans autres commandes) alors une session interactive est ouverte. Les autres options sont ignorées. Ce type de lancement permet d'utiliser gramps
|
||||
pour manipuler des données comme dans un navigateur web. Les formats natifs de gramps sont acceptés, voir ci-dessous.
|
||||
.br
|
||||
|
||||
.TP
|
||||
.BI \-f,\-\^\-format= " FORMAT"
|
||||
Le format spécifique du \fIFICHIER\fR est précédé par les options \fB\-O\fR,
|
||||
\fB\-i\fR, ou
|
||||
\fB\-o\fR. Si l'option \fB\-f\fR n'est pas donnée pour le \fIFICHIER\fR, alors le format sera celui de l'extension.
|
||||
.br
|
||||
|
||||
Les formats disponibles pour l'ouverture sont \fBgrdb\fR (choisi si \fIFICHIER\fR se termine par
|
||||
\fB.grdb\fR), \fBgramps\-xml\fR (choisi si \fIFICHIER\fR se termine par
|
||||
\fB.gramps\fR), et \fBgedcom\fR (choisi si \fIFICHIER\fR se termine par \fB.ged\fR).
|
||||
.br
|
||||
|
||||
Les formats disponibles pour l'importation sont \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR,
|
||||
\fBgramps\-pkg\fR (choisi si \fIFICHIER\fR se termine par \fB.gpkg\fR), et
|
||||
\fBgeneweb\fR (choisi si \fIFICHIER\fR se termine par \fB.gw\fR).
|
||||
.br
|
||||
|
||||
Les formats disponibles pour l'exportation sont \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR,
|
||||
\fBgramps\-pkg\fR, \fBwft\fR (choisi si \fIFICHIER\fR se termine par \fB.wft\fR),
|
||||
\fBgeneweb\fR, et \fBiso\fR (jamais deviné, toujours spécifié avec l'option
|
||||
\fB\-f\fR).
|
||||
|
||||
.TP
|
||||
.BI \-O,\-\^\-open= " FICHIER"
|
||||
Ouvrir un \fIFICHIER\fR.
|
||||
Seulement les formats \fBgrdb\fR, \fBgramps\-xml\fR, et \fBgedcom\fR peuvent être ouvert directement. Pour les autres formats, vous devez utiliser l'option d'import,
|
||||
laquelle ouvrira une base vide et importera les données.
|
||||
.br
|
||||
|
||||
Seulement un fichier peut être ouvert. Si vous utilisez plusieurs sources, vous devez utiliser l'option d'import.
|
||||
|
||||
.TP
|
||||
.BI \-i,\-\^\-import= " FICHIER"
|
||||
Importer des données depuis un \fIFICHIER\fR.
|
||||
.br
|
||||
|
||||
Quand plus d'un fichier doit être importé, chacun doit être précédé par la commande \fB\-i\fR. Ces fichiers sont importés dans le même ordre,
|
||||
i.e. \fB\-i\fR \fIFICHIER1\fR \fB\-i\fR \fIFICHIER2\fR
|
||||
et \fB\-i\fR \fIFICHIER2\fR \fB\-i\fR \fIFICHIER1\fR vont tous les deux produire différents IDs gramps.
|
||||
|
||||
.TP
|
||||
.BI \-o,\-\^\-output= " FICHIER"
|
||||
Exporter des données dans un \fIFICHIER\fR. Pour le format \fBiso\fR, le \fIFICHIER\fR est le nom du répertoire dans lequel la base de données gramps est écrite.
|
||||
Pour \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR, \fBwft\fR, \fBgramps\-pkg\fR,
|
||||
et \fBgeneweb\fR, le \fIFICHIER\fR est le nom du fichier de sortie
|
||||
.br
|
||||
|
||||
Quand plus d'un fichier doit être exporté, chacun doit être précédé par la commande \fB\-o\fR. Ces fichiers sont importés dans le même ordre.
|
||||
|
||||
.TP
|
||||
.BI \-a,\-\^\-action= " ACTION"
|
||||
Accomplir une \fIACTION\fR sur les données importées. C'est effectué à la fin de l'importation. Les actions possibles sont \fBsummary\fR
|
||||
(Comme le rapport->Affichage->Résumé?), \fBcheck\fR (comme l'outil->Réparation de la base->Vérifier et réparer), et \fBreport\fR (produit un rapport, à besoin
|
||||
de \fIOPTIONSTRING\fR précédé par la commande \fB\-p\fR.
|
||||
.br
|
||||
|
||||
Ces options de rapport doivent satisfaire ces conditions:
|
||||
.br
|
||||
Il ne doit pas y avoir d'espace.
|
||||
Si certains arguments doivent utiliser des espaces, la chaîne doit être encadrée par des guillemets.
|
||||
Les options vont par paire nom et valeur.
|
||||
Une paire est séparée par un signe égal.
|
||||
Différentes paires sont séparées par une virgule.
|
||||
.br
|
||||
|
||||
La plupart des options sont spécifiques à chaque rapport. Même s'il existe des options communes.
|
||||
|
||||
.BI "name=reportname "
|
||||
.br
|
||||
Cette option obligatoire, elle détermine quel rapport sera généré. Si le nom du rapport saisi ne correspond à aucun rapport disponible, un message d'erreur sera ajouté.
|
||||
|
||||
.BI "show=all"
|
||||
.br
|
||||
Cette option produit une liste avec les noms des options disponibles pour un rapport donné.
|
||||
|
||||
.BI "show=optionname"
|
||||
.br
|
||||
Cette option affiche une description de toutes les fonctionnalités proposées par optionname, aussi bien les types que les valeurs pour une option.
|
||||
|
||||
.br
|
||||
Utiliser les options ci-dessus pour trouver tout sur un rapport choisi.
|
||||
|
||||
.LP
|
||||
Quand plus d'une action doit être effectuée, chacune doit être précédée par la commande \fB\-a\fR. Les actions seront réalisées une à une, dans l'ordre spécifié.
|
||||
|
||||
.BI "Operation"
|
||||
.br
|
||||
Si le premier argument de la ligne de commande ne commence pas par un tiret (i.e. pas
|
||||
d'instruction), gramps va essayer d'ouvrir le fichier avec le nom donné par le premier argument et démarrer une session interactive, en ignorant le reste de la ligne de commande.
|
||||
|
||||
.LP
|
||||
Si la commande \fB\-O\fR est notée, alors gramps va essayer le fichier défini et va travailler avec ses données, comme pour les autres paramètres de la ligne de commande.
|
||||
|
||||
.LP
|
||||
Avec ou sans la commande \fB\-O\fR, il peut y avoir plusieurs imports, exports, et actions dans la ligne de commande \fB\-i\fR,
|
||||
\fB\-o\fR, et \fB\-a\fR.
|
||||
|
||||
.LP
|
||||
L'ordre des options \fB\-i\fR, \fB\-o\fR, ou \fB\-a\fR n'a pas de sens. L'ordre actuel est toujours : imports -> actions -> exports. Mais l'ouverture doit toujours être la première!
|
||||
|
||||
.LP
|
||||
Si aucune option \fB\-O\fR ou \fB\-i\fR n'est donnée, gramps lancera sa propre fenêtre et demarrera avec une base vide, puisqu'il n'y a pas données.
|
||||
|
||||
.LP
|
||||
Si aucune option \fB\-o\fR ou \fB\-a\fR n'est donnée, gramps lancera sa propre fenêtre et démarrera avec la base de données issue de tout les imports. Cette base sera \fBimport_db.grdb\fR sous le répertoire \fB~/.gramps/import\fR.
|
||||
|
||||
.LP
|
||||
Les erreurs rencontrées lors d'import, export, ou action, seront mémorisées en \fIstdout\fR (si elles sont le fait de la manipulation par gramps) ou
|
||||
en \fIstderr\fR (si elles ne sont pas le fait d'une manipulation). Utilisez les shell de redirection de
|
||||
\fIstdout\fR et \fIstderr\fR pour sauver les messages et les erreurs dans les fichiers.
|
||||
|
||||
.SH EXEMPLES
|
||||
.TP
|
||||
Lecture de quatre bases de données dont les formats peuvent être devinés d'après les noms, puis vérification des données:
|
||||
\fBgramps\fR \fB\-i\fR \fIfile1.ged\fR \fB\-i\fR \fIfile2.tgz\fR \fB\-i\fR \fI~/db3.gramps\fR \fB\-i\fR \fIfile4.wft\fR \fB\-a\fR \fIcheck\fR
|
||||
.TP
|
||||
Si vous voulez préciser les formats de fichiers dans l'exemple ci-dessus, complétez les noms de fichiers par les options \fB\-f\fR appropriées:
|
||||
\fBgramps\fR \fB\-i\fR \fIfile1.ged\fR \fB\-f\fR \fIgedcom\fR \fB\-i\fR \fIfile2.tgz\fR \fB\-f\fR \fIgramps-pkg\fR \fB\-i\fR \fI~/db3.gramps\fR \fB\-f\fR \fIgramps-xml\fR \fB\-i\fR \fIfile4.wft\fR \fB\-f\fR \fIwft\fR \fB\-a\fR \fIcheck\fR
|
||||
.TP
|
||||
Pour enregistrer le résultat des lectures, donnez l'option \fB\-o\fR (utiliser \fB\-f\fR si le nom de fichier ne permet pas à gramps de deviner le format):
|
||||
\fBgramps\fR \fB\-i\fR \fIfile1.ged\fR \fB\-i\fR \fIfile2.tgz\fR \fB\-o\fR \fI~/new-package\fR \fB\-f\fR \fIgramps-pkg\fR
|
||||
.TP
|
||||
Pour lire trois ensembles de données puis lancer une session interactive de gramps sur le tout :
|
||||
\fBgramps\fR \fB\-i\fR \fIfile1.ged\fR \fB\-i\fR \fIfile2.tgz\fR \fB\-i\fR \fI~/db3.gramps\fR
|
||||
.TP
|
||||
Enfin, pour lancer une session interactive normale, entrer : \fBgramps\fR
|
||||
|
||||
.SH CONCEPTS
|
||||
GRAMPS est un système basé sur le support de plugin-python, permettant d'importer et d'exporter, la saisie,
|
||||
générer des rapports, des outils, et afficher des filtres pouvant être ajoutés sans modifier le programme.
|
||||
.LP
|
||||
Par ailleurs, gramps permet la génération directe : impression, rapports avec sortie vers d'autres formats, comme \fIOpenOffice.org\fR, \fIAbiWord\fR, HTML,
|
||||
ou LaTeX pour permettre à l'utilisateur de choisir selon ses besoins
|
||||
|
||||
.SH BUGS CONNUS ET LIMITATIONS
|
||||
|
||||
.SH FICHIERS
|
||||
.LP
|
||||
\fI${PREFIX}/bin/gramps\fP
|
||||
.br
|
||||
\fI${PREFIX}/share/gramps\fP
|
||||
.br
|
||||
\fI${HOME}/.gramps\fP
|
||||
|
||||
.SH AUTEURS
|
||||
Donald Allingham \fI<don@gramps-project.org>\fR
|
||||
.br
|
||||
\fIhttp://gramps.sourceforge.net\fR
|
||||
.LP
|
||||
Cette page man a d'abord été écrite par:
|
||||
.br
|
||||
Brandon L. Griffith \fI<brandon@debian.org>\fR
|
||||
.br
|
||||
pour Debian GNU/Linux système.
|
||||
.LP
|
||||
Cette page man est maintenue par:
|
||||
.br
|
||||
Alex Roitman \fI<shura@gramps-project.org>\fR
|
||||
.LP
|
||||
La traduction française:
|
||||
.br
|
||||
Jérôme Rapinat \fI<romjerome@yahoo.fr>\fR
|
||||
.br
|
||||
|
||||
.SH DOCUMENTATION
|
||||
La documentation-utilisateur est disponible par le navigateur d'aide de GNOME sous la forme du manuel Gramps. Ce manuel est également disponible sous format XML comme \fBgramps-manual.xml\fR sous \fIdoc/gramps-manual/$LANG\fR dans les sources officielles.
|
||||
.LP
|
||||
La documentation pour développeur est disponible sur le site \fIhttp://developers.gramps-project.org\fR.
|
@ -44,8 +44,8 @@ wide by almost all other genealogy software.
|
||||
.BI gramps " FILE"
|
||||
When \fIFILE\fR is given (without any flags) then it is
|
||||
opened and an interactive session is started. The rest of the options
|
||||
are ignored. This way of launching is suitable for using gramps
|
||||
as a handler for genealogical data in e.g. web browsers. This invocation
|
||||
is ignored. This way of launching is suitable for using gramps
|
||||
as a handler for genealogical data in e.g. web browsers. This invokation
|
||||
can accept any data format native to gramps, see below.
|
||||
.br
|
||||
|
||||
@ -58,10 +58,9 @@ the format of that file is guessed according to its extension.
|
||||
.br
|
||||
|
||||
Formats
|
||||
available for opening are \fBgrdb\fR (guessed if \fIFILE\fR ends
|
||||
with \fB.grdb\fR), \fBgramps\-xml\fR (guessed if \fIFILE\fR ends
|
||||
with \fB.gramps\fR), and \fBgedcom\fR (guessed if \fIFILE\fR ends
|
||||
with \fB.ged\fR).
|
||||
available for opening are \fBgrdb\fR (guessed if \fIFILE\fR ends with
|
||||
\fB.grdb\fR), \fBgramps\-xml\fR (guessed if \fIFILE\fR ends with
|
||||
\fB.gramps\fR), and \fBgedcom\fR (guessed if \fIFILE\fR ends with \fB.ged\fR).
|
||||
.br
|
||||
|
||||
Formats
|
||||
@ -72,7 +71,7 @@ available for import are \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR,
|
||||
|
||||
Formats available for export are \fBgrdb\fR, \fBgramps\-xml\fR, \fBgedcom\fR,
|
||||
\fBgramps\-pkg\fR, \fBwft\fR (guessed if \fIFILE\fR ends with \fB.wft\fR),
|
||||
\fBgeneweb\fR, and \fBiso\fR (never guessed, always specified with
|
||||
\fBgeneweb\fR, and \fBiso\fR (never guessed, always specify with
|
||||
\fB\-f\fR option).
|
||||
|
||||
.TP
|
||||
@ -160,8 +159,8 @@ by \fB\-a\fR flag. The actions are performed one by one, in the specified order.
|
||||
.br
|
||||
If the first argument on the command line does not start with dash (i.e. no
|
||||
flag), gramps will attempt to open the file with the name given by the first
|
||||
argument and start an interactive session, ignoring the rest of the command
|
||||
line arguments.
|
||||
argument and start interactive session, ignoring the rest of the command line
|
||||
arguments.
|
||||
|
||||
.LP
|
||||
If the \fB\-O\fR flag is given, then gramps will try opening
|
||||
@ -180,8 +179,8 @@ actual order always is: all imports (if any) -> all actions (if any)
|
||||
|
||||
.LP
|
||||
If no \fB\-O\fR or \fB\-i\fR option is given, gramps will launch its main
|
||||
window and start the usual interactive session with the empty database
|
||||
anyway, since there is no data to process.
|
||||
window and start the usual interactive session with the empty database,
|
||||
since there is no data to process, anyway.
|
||||
|
||||
.LP
|
||||
If no \fB\-o\fR or \fB\-a\fR options are given, gramps will launch its main
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2003 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -510,7 +510,7 @@ class ArgHandler:
|
||||
filename = os.path.normpath(os.path.abspath(filename))
|
||||
if filename:
|
||||
try:
|
||||
g = GrampsDb.XmlWriter(self.parent.db,None,1,1)
|
||||
g = GrampsDb.XmlWriter(self.parent.db,None,0,1)
|
||||
ret = g.write(filename)
|
||||
except:
|
||||
print "Error exporting %s" % filename
|
||||
|
@ -2059,7 +2059,7 @@ class IsLessThanNthGenerationAncestorOfBookmarked(Rule):
|
||||
name = _('Ancestors of bookmarked people not more '
|
||||
'than <N> generations away')
|
||||
category = _('Ancestral filters')
|
||||
description = _("Matches ancestors of the people on the bookmark list"
|
||||
description = _("Matches ancestors of the people on the bookmark list "
|
||||
"not more than N generations away")
|
||||
|
||||
def prepare(self,db):
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2004 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -219,6 +219,7 @@ class MissingMediaDialog:
|
||||
self.xml = gtk.glade.XML(const.gladeFile,"missmediadialog","gramps")
|
||||
self.top = self.xml.get_widget('missmediadialog')
|
||||
self.top.set_icon(ICON)
|
||||
|
||||
self.task1 = task1
|
||||
self.task2 = task2
|
||||
self.task3 = task3
|
||||
@ -236,7 +237,15 @@ class MissingMediaDialog:
|
||||
self.top.show()
|
||||
if parent:
|
||||
self.top.set_transient_for(parent)
|
||||
response = self.top.run()
|
||||
self.top.connect('delete_event',self.warn)
|
||||
response = gtk.RESPONSE_DELETE_EVENT
|
||||
|
||||
# Need some magic here, because an attempt to close the dialog
|
||||
# with the X button not only emits the 'delete_event' signal
|
||||
# but also exits with the RESPONSE_DELETE_EVENT
|
||||
while response == gtk.RESPONSE_DELETE_EVENT:
|
||||
response = self.top.run()
|
||||
|
||||
if response == 1:
|
||||
self.task1()
|
||||
elif response == 2:
|
||||
@ -248,3 +257,11 @@ class MissingMediaDialog:
|
||||
else:
|
||||
self.default_action = 0
|
||||
self.top.destroy()
|
||||
|
||||
def warn(self,obj,obj2):
|
||||
WarningDialog(
|
||||
_("Attempt to force closing the dialog"),
|
||||
_("Please do not force closing this important dialog.\n"
|
||||
"Instead select one of the available options"),
|
||||
self.top)
|
||||
return True
|
||||
|
@ -525,7 +525,7 @@ buried_partial_date_place = {
|
||||
buried_partial_date_no_place = {
|
||||
RelLib.Person.MALE: [
|
||||
_("%(male_name)s was buried in %(month_year)s."),
|
||||
_("He was buried on %(month_year)s."),
|
||||
_("He was buried in %(month_year)s."),
|
||||
],
|
||||
RelLib.Person.FEMALE: [
|
||||
_("%(female_name)s was buried in %(month_year)s."),
|
||||
@ -1994,16 +1994,16 @@ def buried_str(database,person,person_name=None,empty_date="",empty_place=""):
|
||||
'modified_date' : bdate,
|
||||
}
|
||||
|
||||
if bdate and bdate_full:
|
||||
if bplace: #male, date, place
|
||||
text = buried_full_date_place[gender][name_index] % values
|
||||
else: #male, date, no place
|
||||
text = buried_full_date_no_place[gender][name_index] % values
|
||||
elif bdate and bdate_mod:
|
||||
if bdate and bdate_mod:
|
||||
if bplace: #male, date, place
|
||||
text = buried_modified_date_place[gender][name_index] % values
|
||||
else: #male, date, no place
|
||||
text = buried_modified_date_no_place[gender][name_index] % values
|
||||
elif bdate and bdate_full:
|
||||
if bplace: #male, date, place
|
||||
text = buried_full_date_place[gender][name_index] % values
|
||||
else: #male, date, no place
|
||||
text = buried_full_date_no_place[gender][name_index] % values
|
||||
elif bdate:
|
||||
if bplace: #male, month_year, place
|
||||
text = buried_partial_date_place[gender][name_index] % values
|
||||
@ -2123,8 +2123,11 @@ def old_calc_age(database,person):
|
||||
months: 2
|
||||
days: 3
|
||||
"""
|
||||
YEARS = 1
|
||||
MONTHS = 2
|
||||
DAYS = 3
|
||||
|
||||
# This is an old and ugly implementation.
|
||||
# FIXME: This is an old and ugly implementation.
|
||||
# It must be changed to use the new age calculator.
|
||||
age = 0
|
||||
units = 0
|
||||
@ -2142,23 +2145,50 @@ def old_calc_age(database,person):
|
||||
else:
|
||||
death_year_valid = None
|
||||
|
||||
if birth_year_valid and death_year_valid:
|
||||
age = death.get_year() - birth.get_year()
|
||||
units = 1 # year
|
||||
# wihtout at least a year for each event we're clueless
|
||||
if not (birth_year_valid and death_year_valid):
|
||||
return (age,units)
|
||||
|
||||
# FIXME: The code below uses hard-coded 31 days in a month
|
||||
# and 12 month in a year. This is incorrect for half the Gregorian
|
||||
# months and for other calendars.
|
||||
# FIXME: We need to move to estimate_age !!!
|
||||
|
||||
# If born and died in the same year, go to the months
|
||||
if death.get_year() == birth.get_year():
|
||||
if birth.get_month_valid() and death.get_month_valid():
|
||||
# if born and died in the same month, do the days
|
||||
if birth.get_month() == death.get_month() \
|
||||
and birth.get_day_valid() and death.get_day_valid():
|
||||
age = death.get_day() - birth.get_day()
|
||||
units = DAYS
|
||||
# if not the same month, just diff the months
|
||||
else:
|
||||
age = death.get_month() - birth.get_month()
|
||||
units = MONTHS
|
||||
# Born and died in different years
|
||||
else:
|
||||
age = death.get_year() - birth.get_year()
|
||||
units = YEARS
|
||||
if birth.get_month_valid() and death.get_month_valid():
|
||||
# Subtract one year if less than a last full year
|
||||
if birth.get_month() > death.get_month():
|
||||
age = age - 1
|
||||
if birth.get_day_valid() and death.get_day_valid():
|
||||
if birth.get_month() == death.get_month() and birth.get_day() > death.get_day():
|
||||
age = age - 1
|
||||
if age == 0:
|
||||
age = death.get_month() - birth.get_month() # calc age in months
|
||||
if birth.get_day() > death.get_day():
|
||||
age = age - 1
|
||||
units = 2 # month
|
||||
if age == 0:
|
||||
age = death.get_day() + 31 - birth.get_day() # calc age in days
|
||||
units = 3 # day
|
||||
|
||||
# If less than a year (but still in different years)
|
||||
# then calculate month diff modulo 12
|
||||
if age == 0:
|
||||
age = 12 + death.get_month() - birth.get_month()
|
||||
units = MONTHS
|
||||
|
||||
# This is the case of birth on Dec 30 and death on Jan 2
|
||||
# or birth on May 30 and death on June 2
|
||||
if age == 1 and units == MONTHS \
|
||||
and birth.get_day_valid() and death.get_day_valid() \
|
||||
and birth.get_day() > death.get_day():
|
||||
age = death.get_day() + 31 - birth.get_day()
|
||||
unit = DAYS
|
||||
|
||||
return (age,units)
|
||||
|
||||
|
||||
|
@ -49,6 +49,7 @@ import GrampsMime
|
||||
import NameDisplay
|
||||
import RelLib
|
||||
import Errors
|
||||
from QuestionDialog import WarningDialog
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -1144,6 +1145,7 @@ class ProgressMeter:
|
||||
Specify the title and the current pass header.
|
||||
"""
|
||||
self.ptop = gtk.Dialog()
|
||||
self.ptop.connect('delete_event',self.warn)
|
||||
self.ptop.set_has_separator(False)
|
||||
self.ptop.set_title(title)
|
||||
self.ptop.set_border_width(12)
|
||||
@ -1193,6 +1195,13 @@ class ProgressMeter:
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration()
|
||||
|
||||
def warn(self,obj,obj2):
|
||||
WarningDialog(
|
||||
_("Attempt to force closing the dialog"),
|
||||
_("Please do not force closing this important dialog."),
|
||||
self.ptop)
|
||||
return True
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close the progress meter
|
||||
|
@ -48,64 +48,97 @@ from DateDisplay import DateDisplay
|
||||
#-------------------------------------------------------------------------
|
||||
class DateParserFR(DateParser):
|
||||
|
||||
month_to_int = DateParser.month_to_int
|
||||
# Add common latin, local and historical variants (now only on east france)
|
||||
month_to_int[u"januaris"] = 1
|
||||
month_to_int[u"janer"] = 1
|
||||
month_to_int[u"jenner"] = 1
|
||||
month_to_int[u"hartmonat"] = 1
|
||||
month_to_int[u"hartung"] = 1
|
||||
month_to_int[u"eismond"] = 1
|
||||
month_to_int[u"bluviose"] = 1
|
||||
month_to_int[u"februaris"] = 2
|
||||
month_to_int[u"hornung"] = 2
|
||||
month_to_int[u"wintermonat"] = 2
|
||||
month_to_int[u"taumond"] = 2
|
||||
month_to_int[u"narrenmond"] = 2
|
||||
month_to_int[u"vendose"] = 2
|
||||
month_to_int[u"martius"] = 3
|
||||
month_to_int[u"aprilis"] = 4
|
||||
month_to_int[u"wiesenmonat"] = 5
|
||||
month_to_int[u"maius"] = 5
|
||||
month_to_int[u"junius"] = 6
|
||||
month_to_int[u"julius"] = 7
|
||||
month_to_int[u"augustus"] = 8
|
||||
month_to_int[u"september"] = 9
|
||||
month_to_int[u"7bre"] = 9
|
||||
month_to_int[u"7bris"] = 9
|
||||
month_to_int[u"october"] = 10
|
||||
month_to_int[u"8bre"] = 10
|
||||
month_to_int[u"8bris"] = 10
|
||||
month_to_int[u"nebelmonat"] = 10
|
||||
month_to_int[u"november"] = 11
|
||||
month_to_int[u"9bre"] = 11
|
||||
month_to_int[u"9bris"] = 11
|
||||
month_to_int[u"december"] = 12
|
||||
month_to_int[u"10bre"] = 12
|
||||
month_to_int[u"10bris"] = 12
|
||||
month_to_int[u"xbre"] = 12
|
||||
month_to_int[u"xbris"] = 12
|
||||
|
||||
modifier_to_int = {
|
||||
u'avant' : Date.MOD_BEFORE,
|
||||
u'av.' : Date.MOD_BEFORE,
|
||||
u'av' : Date.MOD_BEFORE,
|
||||
u'après' : Date.MOD_AFTER,
|
||||
u'avant' : Date.MOD_BEFORE,
|
||||
u'av.' : Date.MOD_BEFORE,
|
||||
u'av' : Date.MOD_BEFORE,
|
||||
u'après' : Date.MOD_AFTER,
|
||||
u'ap.' : Date.MOD_AFTER,
|
||||
u'ap' : Date.MOD_AFTER,
|
||||
u'env.' : Date.MOD_ABOUT,
|
||||
u'env' : Date.MOD_ABOUT,
|
||||
u'environ': Date.MOD_ABOUT,
|
||||
u'circa' : Date.MOD_ABOUT,
|
||||
u'c.' : Date.MOD_ABOUT,
|
||||
u'ca' : Date.MOD_ABOUT,
|
||||
u'ca.' : Date.MOD_ABOUT,
|
||||
u'vers' : Date.MOD_ABOUT,
|
||||
u'~' : Date.MOD_ABOUT,
|
||||
}
|
||||
|
||||
calendar_to_int = {
|
||||
u'grégorien' : Date.CAL_GREGORIAN,
|
||||
u'grégorien' : Date.CAL_GREGORIAN,
|
||||
u'g' : Date.CAL_GREGORIAN,
|
||||
u'julien' : Date.CAL_JULIAN,
|
||||
u'j' : Date.CAL_JULIAN,
|
||||
u'hébreu' : Date.CAL_HEBREW,
|
||||
u'hébreu' : Date.CAL_HEBREW,
|
||||
u'h' : Date.CAL_HEBREW,
|
||||
u'islamique' : Date.CAL_ISLAMIC,
|
||||
u'i' : Date.CAL_ISLAMIC,
|
||||
u'révolutionnaire': Date.CAL_FRENCH,
|
||||
u'révolutionnaire' : Date.CAL_FRENCH,
|
||||
u'r' : Date.CAL_FRENCH,
|
||||
u'perse' : Date.CAL_PERSIAN,
|
||||
u'p' : Date.CAL_PERSIAN,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
u'estimated' : Date.QUAL_ESTIMATED,
|
||||
u'estimer' : Date.QUAL_ESTIMATED,
|
||||
u'estimée' : Date.QUAL_ESTIMATED,
|
||||
u'est.' : Date.QUAL_ESTIMATED,
|
||||
u'est' : Date.QUAL_ESTIMATED,
|
||||
u'environ' : Date.QUAL_ESTIMATED,
|
||||
u'env' : Date.QUAL_ESTIMATED,
|
||||
u'env.' : Date.QUAL_ESTIMATED,
|
||||
u'calculer' : Date.QUAL_CALCULATED,
|
||||
u'calculée' : Date.QUAL_CALCULATED,
|
||||
u'calc.' : Date.QUAL_CALCULATED,
|
||||
u'calc' : Date.QUAL_CALCULATED,
|
||||
u'compter' : Date.QUAL_CALCULATED,
|
||||
u'comptée' : Date.QUAL_CALCULATED,
|
||||
u'compt' : Date.QUAL_CALCULATED,
|
||||
u'compt.' : Date.QUAL_CALCULATED,
|
||||
u'calculated' : Date.QUAL_CALCULATED,
|
||||
}
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
_span_1 = [u'de']
|
||||
_span_2 = [u'à']
|
||||
_range_1 = [u'ent.',u'ent',u'entre']
|
||||
_range_2 = [u'et']
|
||||
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_span_1),'|'.join(_span_2)),
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1),'|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
self._span = re.compile("(de)\s+(?P<start>.+)\s+(à)\s+(?P<stop>.+)",re.IGNORECASE)
|
||||
self._range = re.compile("(entre|ent|ent.)\s+(?P<start>.+)\s+(et)\s+(?P<stop>.+)",re.IGNORECASE)
|
||||
self._text2 =re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._mon_str,
|
||||
re.IGNORECASE)
|
||||
self._jtext2 =re.compile('(\d+)?.?\s+?%s\s*((\d+)(/\d+)?)?' % self._mon_str,
|
||||
re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -115,19 +148,68 @@ class DateParserFR(DateParser):
|
||||
class DateDisplayFR(DateDisplay):
|
||||
|
||||
calendar = (
|
||||
"", u" (Julien)", u" (Hébreu)",
|
||||
"", u" (Julien)", u" (Hébreu)",
|
||||
u" (Révolutionnaire)", u" (Perse)", u" (Islamique)"
|
||||
)
|
||||
|
||||
_mod_str = ("",u"avant ",u"après ",u"vers ","","","")
|
||||
|
||||
_qual_str = ("","estimated ","calculated ")
|
||||
_qual_str = ("","estimée ","calculée ","")
|
||||
|
||||
formats = (
|
||||
"AAAA-MM-DD (ISO)", "Numérique", "Mois Jour, Année",
|
||||
"MOI Jour, Année", "Jour Mois, Année", "Jour MOIS Année"
|
||||
)
|
||||
|
||||
def _display_gregorian(self,date_val):
|
||||
year = self._slash_year(date_val[2],date_val[3])
|
||||
if self.format == 0:
|
||||
value = self.display_iso(date_val)
|
||||
elif self.format == 1:
|
||||
if date_val[0] == 0 and date_val[1] == 0:
|
||||
value = str(date_val[2])
|
||||
else:
|
||||
value = self._tformat.replace('%m',str(date_val[1]))
|
||||
value = value.replace('%d',str(date_val[0]))
|
||||
value = value.replace('%Y',str(date_val[2]))
|
||||
elif self.format == 2:
|
||||
# Month Day, Year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self._months[date_val[1]],year)
|
||||
else:
|
||||
value = "%s %d, %s" % (self._months[date_val[1]],date_val[0],year)
|
||||
elif self.format == 3:
|
||||
# MON Day, Year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self._MONS[date_val[1]],year)
|
||||
else:
|
||||
value = "%s %d, %s" % (self._MONS[date_val[1]],date_val[0],year)
|
||||
elif self.format == 4:
|
||||
# Day Month Year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self._months[date_val[1]],year)
|
||||
else:
|
||||
value = "%d. %s %s" % (date_val[0],self._months[date_val[1]],year)
|
||||
else:
|
||||
# Day MON Year
|
||||
if date_val[0] == 0:
|
||||
if date_val[1] == 0:
|
||||
value = year
|
||||
else:
|
||||
value = "%s %s" % (self._MONS[date_val[1]],year)
|
||||
else:
|
||||
value = "%d. %s %s" % (date_val[0],self._MONS[date_val[1]],year)
|
||||
return value
|
||||
|
||||
def display(self,date):
|
||||
"""
|
||||
Returns a text string representing the date.
|
||||
@ -161,4 +243,4 @@ class DateDisplayFR(DateDisplay):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from DateHandler import register_datehandler
|
||||
register_datehandler(('fr_FR','fr','french'),DateParserFR, DateDisplayFR)
|
||||
register_datehandler(('fr_FR','fr','french','fr_CA','fr_BE','fr_CH'),DateParserFR,DateDisplayFR)
|
||||
|
149
src/dates/Date_lt.py
Normal file
149
src/dates/Date_lt.py
Normal file
@ -0,0 +1,149 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2004-2005 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
# $Id$
|
||||
|
||||
"""
|
||||
Lithuanian-specific classes for parsing and displaying dates.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import re
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import Date
|
||||
from DateParser import DateParser
|
||||
from DateDisplay import DateDisplay
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Lithuanian parser
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateParserLT(DateParser):
|
||||
|
||||
modifier_to_int = {
|
||||
u'prieš' : Date.MOD_BEFORE,
|
||||
u'po' : Date.MOD_AFTER,
|
||||
u'apie' : Date.MOD_ABOUT,
|
||||
}
|
||||
|
||||
calendar_to_int = {
|
||||
u'Grigaliaus' : Date.CAL_GREGORIAN,
|
||||
u'g' : Date.CAL_GREGORIAN,
|
||||
u'Julijaus' : Date.CAL_JULIAN,
|
||||
u'j' : Date.CAL_JULIAN,
|
||||
u'Hebrajų' : Date.CAL_HEBREW,
|
||||
u'h' : Date.CAL_HEBREW,
|
||||
u'Islamo' : Date.CAL_ISLAMIC,
|
||||
u'i' : Date.CAL_ISLAMIC,
|
||||
u'Prancuzų Respublikos': Date.CAL_FRENCH,
|
||||
u'r' : Date.CAL_FRENCH,
|
||||
u'Persų' : Date.CAL_PERSIAN,
|
||||
u'p' : Date.CAL_PERSIAN,
|
||||
}
|
||||
|
||||
quality_to_int = {
|
||||
u'apytikriai' : Date.QUAL_ESTIMATED,
|
||||
u'apskaičiuota' : Date.QUAL_CALCULATED,
|
||||
}
|
||||
|
||||
def init_strings(self):
|
||||
DateParser.init_strings(self)
|
||||
_span_1 = [u'nuo']
|
||||
_span_2 = [u'iki']
|
||||
_range_1 = [u'tarp']
|
||||
_range_2 = [u'ir']
|
||||
self._span = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_span_1),'|'.join(_span_2)),
|
||||
re.IGNORECASE)
|
||||
self._range = re.compile("(%s)\s+(?P<start>.+)\s+(%s)\s+(?P<stop>.+)" %
|
||||
('|'.join(_range_1),'|'.join(_range_2)),
|
||||
re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Lithuanian displayer
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class DateDisplayLT(DateDisplay):
|
||||
|
||||
calendar = (
|
||||
"", u" (Julijaus)",
|
||||
u" (Hebrajų)",
|
||||
u" (Prancuzų Respublikos)",
|
||||
u" (Persų)",
|
||||
u" (Islamo)"
|
||||
)
|
||||
|
||||
_mod_str = ("",u"iki ",
|
||||
u"po ",
|
||||
u"apie ","","","")
|
||||
|
||||
_qual_str = ("","apytikriai ","apskaičiuota ")
|
||||
|
||||
formats = (
|
||||
"YYYY-MM-DD (ISO)", "Skaitmeninis", "Mėnuo Diena, Metai",
|
||||
"Mėn DD, YYYY", "Diena Mėnuo Metai", "DD Mėn YYYY"
|
||||
)
|
||||
|
||||
def display(self,date):
|
||||
"""
|
||||
Returns a text string representing the date.
|
||||
"""
|
||||
mod = date.get_modifier()
|
||||
cal = date.get_calendar()
|
||||
qual = date.get_quality()
|
||||
start = date.get_start_date()
|
||||
|
||||
qual_str = self._qual_str[qual]
|
||||
|
||||
if mod == Date.MOD_TEXTONLY:
|
||||
return date.get_text()
|
||||
elif start == Date.EMPTY:
|
||||
return ""
|
||||
elif mod == Date.MOD_SPAN:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
return "%sс %s %s %s%s" % (qual_str,d1,u'iki',d2,self.calendar[cal])
|
||||
elif mod == Date.MOD_RANGE:
|
||||
d1 = self.display_cal[cal](start)
|
||||
d2 = self.display_cal[cal](date.get_stop_date())
|
||||
return "%s%s %s %s %s%s" % (qual_str,u'tarp',d1,u'ir',d2,self.calendar[cal])
|
||||
else:
|
||||
text = self.display_cal[date.get_calendar()](start)
|
||||
return "%s%s%s%s" % (qual_str,self._mod_str[mod],text,self.calendar[cal])
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Register classes
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from DateHandler import register_datehandler
|
||||
register_datehandler(('lt_LT','lt','lithuanian'),DateParserLT, DateDisplayLT)
|
@ -63,7 +63,7 @@ class DateParserNL(DateParser):
|
||||
month_to_int[u"januaris"] = 1
|
||||
month_to_int[u"feber"] = 2
|
||||
month_to_int[u"februaris"] = 2
|
||||
month_to_int[u"merz"] = 2
|
||||
month_to_int[u"merz"] = 3
|
||||
month_to_int[u"aprilis"] = 4
|
||||
month_to_int[u"maius"] = 5
|
||||
month_to_int[u"junius"] = 6
|
||||
|
@ -8,6 +8,7 @@ pkgdatadir = $(datadir)/@PACKAGE@/dates
|
||||
pkgdata_PYTHON = \
|
||||
Date_de.py\
|
||||
Date_ru.py\
|
||||
Date_lt.py\
|
||||
Date_fr.py\
|
||||
Date_es.py\
|
||||
Date_fi.py\
|
||||
|
@ -10,6 +10,7 @@ docgen_PYTHON = \
|
||||
HtmlDoc.py\
|
||||
KwordDoc.py\
|
||||
LaTeXDoc.py\
|
||||
ODFDoc.py\
|
||||
OpenOfficeDoc.py\
|
||||
OpenSpreadSheet.py\
|
||||
PdfDoc.py\
|
||||
|
1153
src/docgen/ODFDoc.py
Normal file
1153
src/docgen/ODFDoc.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -451,13 +451,13 @@ class OpenSpreadSheet(SpreadSheetDoc):
|
||||
self.f.write(const.progName + ' ' + const.version)
|
||||
self.f.write('</meta:generator>\n')
|
||||
self.f.write('<meta:initial-creator>')
|
||||
self.f.write(name)
|
||||
self.f.write(self.name)
|
||||
self.f.write('</meta:initial-creator>\n')
|
||||
self.f.write('<meta:creation-date>')
|
||||
self.f.write(self.time)
|
||||
self.f.write('</meta:creation-date>\n')
|
||||
self.f.write('<dc:creator>')
|
||||
self.f.write(name)
|
||||
self.f.write(self.name)
|
||||
self.f.write('</dc:creator>\n')
|
||||
self.f.write('<dc:date>')
|
||||
self.f.write(self.time)
|
||||
|
943
src/plugins/Calendar.py
Normal file
943
src/plugins/Calendar.py
Normal file
@ -0,0 +1,943 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
__author__ = "Douglas Blank <Doug.Blank@gmail.com>"
|
||||
__version__ = "$Revision$"
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
import datetime, time
|
||||
from xml.parsers import expat
|
||||
import const
|
||||
import os
|
||||
import locale
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import BaseDoc
|
||||
import Report
|
||||
import GenericFilter
|
||||
from ReportUtils import pt2cm
|
||||
import DateDisplay
|
||||
import ReportOptions
|
||||
import RelLib
|
||||
|
||||
# _days could be added to DateDisplay:
|
||||
_codeset = locale.nl_langinfo(locale.CODESET)
|
||||
# slightly different from _months; this is zero based
|
||||
_days = (
|
||||
unicode(locale.nl_langinfo(locale.DAY_1),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_2),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_3),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_4),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_5),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_6),_codeset),
|
||||
unicode(locale.nl_langinfo(locale.DAY_7),_codeset),
|
||||
)
|
||||
_language, _country = "en", "US"
|
||||
(_language_country, _encoding) = locale.getlocale()
|
||||
if _language_country != None and _language_country.count("_") == 1:
|
||||
(_language, _country) = _language_country.split("_")
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# The one and only GUI, unfortunately. This will be able to be moved to
|
||||
# Widget once it is created.
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Support functions
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def easter(year):
|
||||
"""
|
||||
Computes the year/month/day of easter. Currently hardcoded in
|
||||
holidays.xml. Based on work by J.-M. Oudin (1940) and is reprinted in
|
||||
the "Explanatory Supplement to the Astronomical Almanac", ed. P. K.
|
||||
Seidelmann (1992).
|
||||
Note: Ash Wednesday is 46 days before Easter Sunday.
|
||||
"""
|
||||
c = year / 100
|
||||
n = year - 19 * (year / 19)
|
||||
k = (c - 17) / 25
|
||||
i = c - c / 4 - (c - k) / 3 + 19 * n + 15
|
||||
i = i - 30 * (i / 30)
|
||||
i = i - (i / 28) * (1 - (i / 28) * (29 / (i + 1))
|
||||
* ((21 - n) / 11))
|
||||
j = year + year / 4 + i + 2 - c + c / 4
|
||||
j = j - 7 * (j / 7)
|
||||
l = i - j
|
||||
month = 3 + (l + 40) / 44
|
||||
day = l + 28 - 31 * ( month / 4 )
|
||||
return "%d/%d/%d" % (year, month, day)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Calendar
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class Calendar(Report.Report):
|
||||
"""
|
||||
Creates the Calendar object that produces the report.
|
||||
"""
|
||||
def __getitem__(self, item):
|
||||
""" Used to get items from various places. Could be moved up to Report. """
|
||||
if item in self.doc.style_list:
|
||||
# font is the only element people refer to in writing reports
|
||||
# from the style_list:
|
||||
return self.doc.style_list[item].get_font()
|
||||
elif item in self.options_class.options_dict:
|
||||
# otherwise it is a option:
|
||||
return self.options_class.options_dict[item]
|
||||
else:
|
||||
raise AttributeError, ("no widget named '%s'" % item)
|
||||
|
||||
def define_graphics_styles(self):
|
||||
""" Set up the report. Could be moved up to Report. """
|
||||
for widget in self.options_class.widgets:
|
||||
if widget.__class__.__name__ == "StyleWidget":
|
||||
widget.define_graphics_style(self.doc)
|
||||
|
||||
def get_short_name(self, person, maiden_name = None):
|
||||
""" Is there a better, built-in way of getting a short, personal name? """
|
||||
nickname = person.get_nick_name()
|
||||
if nickname:
|
||||
first_name = nickname
|
||||
else:
|
||||
first_name = person.get_primary_name().get_first_name()
|
||||
if first_name:
|
||||
first_name = first_name.split()[0] # not middle name
|
||||
if nickname.strip().count(" ") > 0: # HACK: first and last name assumed
|
||||
family_name = ""
|
||||
elif maiden_name != None:
|
||||
family_name = maiden_name
|
||||
else:
|
||||
family_name = person.get_primary_name().get_surname()
|
||||
return ("%s %s" % (first_name, family_name)).strip()
|
||||
|
||||
def draw_rectangle(self, style, sx, sy, ex, ey):
|
||||
""" This should be in BaseDoc """
|
||||
self.doc.draw_line(style, sx, sy, sx, ey)
|
||||
self.doc.draw_line(style, sx, sy, ex, sy)
|
||||
self.doc.draw_line(style, ex, sy, ex, ey)
|
||||
self.doc.draw_line(style, sx, ey, ex, ey)
|
||||
|
||||
### The rest of these all have to deal with calendar specific things
|
||||
|
||||
def add_day_item(self, text, year, month, day):
|
||||
month_dict = self.calendar.get(month, {})
|
||||
day_list = month_dict.get(day, [])
|
||||
day_list.append(text)
|
||||
month_dict[day] = day_list
|
||||
self.calendar[month] = month_dict
|
||||
|
||||
def get_holidays(self, year, country = "US"):
|
||||
""" Looks in multiple places for holidays.xml files """
|
||||
locations = [const.pluginsDir,
|
||||
os.path.expanduser("~/.gramps/plugins")]
|
||||
holiday_file = 'holidays.xml'
|
||||
for dir in locations:
|
||||
holiday_full_path = os.path.join(dir, holiday_file)
|
||||
if os.path.exists(holiday_full_path):
|
||||
self.process_holiday_file(holiday_full_path, year, country)
|
||||
|
||||
def process_holiday_file(self, filename, year, country):
|
||||
""" This will process a holiday file """
|
||||
parser = Xml2Obj()
|
||||
element = parser.Parse(filename)
|
||||
calendar = Holidays(element, country)
|
||||
date = datetime.date(year, 1, 1)
|
||||
while date.year == year:
|
||||
holidays = calendar.check_date( date )
|
||||
for text in holidays:
|
||||
self.add_day_item(text, date.year, date.month, date.day)
|
||||
date = date.fromordinal( date.toordinal() + 1)
|
||||
|
||||
def write_report(self):
|
||||
""" The short method that runs through each month and creates a page. """
|
||||
# initialize the dict to fill:
|
||||
self.calendar = {}
|
||||
# get the information, first from holidays:
|
||||
if self["holidays"]:
|
||||
self.get_holidays(self["year"], _country) # currently global
|
||||
# get data from database:
|
||||
self.collect_data()
|
||||
# generate the report:
|
||||
for month in range(1, 13):
|
||||
self.print_page(month)
|
||||
|
||||
def print_page(self, month):
|
||||
"""
|
||||
This method actually writes the calendar page.
|
||||
"""
|
||||
self.doc.start_page()
|
||||
width = self.doc.get_usable_width()
|
||||
height = self.doc.get_usable_height()
|
||||
header = self.doc.tmargin
|
||||
self.draw_rectangle("border", 0, 0, width, height)
|
||||
self.doc.draw_bar("title", 0, 0, width, header)
|
||||
self.doc.draw_line("border", 0, header, width, header)
|
||||
year = self["year"]
|
||||
title = "%s %d" % (DateDisplay.DateDisplay._months[month], year)
|
||||
font_height = pt2cm(1.25 * self["title"].get_size())
|
||||
self.doc.center_text("title", title, width/2, font_height + self["offset"]) # 1.0
|
||||
cell_width = width / 7
|
||||
cell_height = (height - header)/ 6
|
||||
current_date = datetime.date(year, month, 1)
|
||||
spacing = pt2cm(1.25 * self["text"].get_size()) # 158
|
||||
if current_date.isoweekday() != 7: # start dow here is 7, sunday
|
||||
current_ord = current_date.toordinal() - current_date.isoweekday()
|
||||
else:
|
||||
current_ord = current_date.toordinal()
|
||||
for day_col in range(7):
|
||||
self.doc.center_text("daynames", _days[day_col], # global
|
||||
day_col * cell_width + cell_width/2,
|
||||
header - font_height/3.0 + self["offset"]) # .35
|
||||
for week_row in range(6):
|
||||
something_this_week = 0
|
||||
for day_col in range(7):
|
||||
thisday = current_date.fromordinal(current_ord)
|
||||
if thisday.month == month:
|
||||
something_this_week = 1
|
||||
self.draw_rectangle("border", day_col * cell_width,
|
||||
header + week_row * cell_height,
|
||||
(day_col + 1) * cell_width,
|
||||
header + (week_row + 1) * cell_height)
|
||||
last_edge = (day_col + 1) * cell_width
|
||||
self.doc.center_text("numbers", str(thisday.day),
|
||||
day_col * cell_width + cell_width/2,
|
||||
header + week_row * cell_height + .5 + self["offset"])
|
||||
list = self.calendar.get(month, {}).get(thisday.day, [])
|
||||
position = 0.0
|
||||
for p in list:
|
||||
lines = p.count("\n") + 1 # lines in the text
|
||||
position += (lines * spacing)
|
||||
current = 0
|
||||
for line in p.split("\n"):
|
||||
self.doc.write_at("text", line,
|
||||
day_col * cell_width + .1,
|
||||
header + (week_row + 1) * cell_height - position + (current * spacing) + self["offset"])
|
||||
current += 1
|
||||
current_ord += 1
|
||||
if not something_this_week:
|
||||
last_edge = 0
|
||||
font_height = pt2cm(1.25 * self["text1style"].get_size())
|
||||
self.doc.center_text("text1style", self["text1"], last_edge + (width - last_edge)/2, height - font_height * 3 + self["offset"]) # - 1.5
|
||||
self.doc.center_text("text2style", self["text2"], last_edge + (width - last_edge)/2, height - font_height * 2 + self["offset"]) # - 0.78
|
||||
self.doc.center_text("text3style", self["text3"], last_edge + (width - last_edge)/2, height - font_height * 1 + self["offset"]) # - 0.30
|
||||
self.doc.end_page()
|
||||
|
||||
def collect_data(self):
|
||||
"""
|
||||
This method runs through the data, and collects the relevant dates
|
||||
and text.
|
||||
"""
|
||||
filter_num = self.options_class.get_filter_number()
|
||||
filters = self.options_class.get_report_filters(self.start_person)
|
||||
filters.extend(GenericFilter.CustomFilters.get_filters())
|
||||
self.filter = filters[filter_num]
|
||||
people = self.filter.apply(self.database,
|
||||
self.database.get_person_handles(sort_handles=False))
|
||||
for person_handle in people:
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
birth_handle = person.get_birth_handle()
|
||||
birth_date = None
|
||||
if birth_handle:
|
||||
birth_event = self.database.get_event_from_handle(birth_handle)
|
||||
birth_date = birth_event.get_date()
|
||||
if birth_date == "":
|
||||
birth_date = None
|
||||
else:
|
||||
birth_date_obj = birth_event.get_date_object()
|
||||
death_handle = person.get_death_handle()
|
||||
death_date = None
|
||||
if death_handle:
|
||||
death_event = self.database.get_event_from_handle(death_handle)
|
||||
death_date = death_event.get_date()
|
||||
if death_date == "": # BUG: couldn't remove event
|
||||
death_date = None
|
||||
else:
|
||||
death_date_obj = death_event.get_date_object()
|
||||
if death_date == None:
|
||||
alive = True # well, until we get probably_alive in here
|
||||
else:
|
||||
alive = False
|
||||
if self["birthdays"] and birth_date != None and ((self["alive"] and alive) or not self["alive"]):
|
||||
year = birth_date_obj.get_year()
|
||||
month = birth_date_obj.get_month()
|
||||
day = birth_date_obj.get_day()
|
||||
age = self["year"] - year
|
||||
# add some things to handle maiden name:
|
||||
father_lastname = None # husband, actually
|
||||
if self["maiden_name"] == 0: # get husband's last name:
|
||||
if person.get_gender() == RelLib.Person.FEMALE:
|
||||
family_list = person.get_family_handle_list()
|
||||
if len(family_list) > 0:
|
||||
fhandle = family_list[0] # first is primary
|
||||
fam = self.database.get_family_from_handle(fhandle)
|
||||
father_handle = fam.get_father_handle()
|
||||
mother_handle = fam.get_mother_handle()
|
||||
if mother_handle == person_handle:
|
||||
if father_handle:
|
||||
father = self.database.get_person_from_handle(father_handle)
|
||||
if father != None:
|
||||
father_lastname = father.get_primary_name().get_surname()
|
||||
short_name = self.get_short_name(person, father_lastname)
|
||||
self.add_day_item("%s, %d" % (short_name, age), year, month, day)
|
||||
if self["anniversaries"] and ((self["alive"] and alive) or not self["alive"]):
|
||||
family_list = person.get_family_handle_list()
|
||||
for fhandle in family_list:
|
||||
fam = self.database.get_family_from_handle(fhandle)
|
||||
father_handle = fam.get_father_handle()
|
||||
mother_handle = fam.get_mother_handle()
|
||||
if father_handle == person.get_handle():
|
||||
spouse_handle = mother_handle
|
||||
else:
|
||||
continue # with next person if this was the marriage event
|
||||
if spouse_handle:
|
||||
spouse = self.database.get_person_from_handle(spouse_handle)
|
||||
if spouse:
|
||||
spouse_name = self.get_short_name(spouse)
|
||||
short_name = self.get_short_name(person)
|
||||
if self["alive"]:
|
||||
spouse_death_handle = spouse.get_death_handle()
|
||||
if spouse_death_handle != None:
|
||||
# there is a death event, maybe empty though
|
||||
spouse_death_event = self.database.get_event_from_handle(spouse_death_handle)
|
||||
if spouse_death_event != None:
|
||||
spouse_death_date = spouse_death_event.get_date()
|
||||
if spouse_death_date != "": # BUG: couldn't remove event
|
||||
continue
|
||||
for event_handle in fam.get_event_list():
|
||||
event = self.database.get_event_from_handle(event_handle)
|
||||
event_obj = event.get_date_object()
|
||||
year = event_obj.get_year()
|
||||
month = event_obj.get_month()
|
||||
day = event_obj.get_day()
|
||||
years = self["year"] - year
|
||||
text = _("%(spouse)s and\n %(person)s, %(nyears)d") % {
|
||||
'spouse' : spouse_name,
|
||||
'person' : short_name,
|
||||
'nyears' : years,
|
||||
}
|
||||
self.add_day_item(text, year, month, day)
|
||||
|
||||
###################################################################################
|
||||
# These classes are a suggested of how to rework the graphics out of reports. It also
|
||||
# makes these items abstractions, which makes it easy to change the report
|
||||
# infrastructure without having everyone rewrite their reports each time.
|
||||
#
|
||||
# This builds on the current document code, so no changes are needed.
|
||||
###################################################################################
|
||||
class Widget:
|
||||
""" A Widget virtual base class. This contains no graphics specifics. """
|
||||
commonDefaults = {
|
||||
"wtype" : None,
|
||||
"name" : None,
|
||||
"label" : None,
|
||||
"help" : None,
|
||||
"wtype" : None,
|
||||
"valid_text" : None,
|
||||
"frame" : None,
|
||||
"value" : None,
|
||||
}
|
||||
defaults = {}
|
||||
def __init__(self, option_object, **args):
|
||||
self.option_object = option_object
|
||||
self.setup(args)
|
||||
self.register()
|
||||
def __getitem__(self, key):
|
||||
if key in self.settings:
|
||||
return self.settings[key]
|
||||
else:
|
||||
raise AttributeError, ("no widget attribute named '%s'" % key)
|
||||
def __setitem__(self, key, value):
|
||||
self.settings[key] = value
|
||||
def setup(self, args = {}):
|
||||
# start with the base defaults common to all:
|
||||
self.settings = self.commonDefaults.copy()
|
||||
# now add those from the subclass:
|
||||
self.settings.update(self.defaults)
|
||||
# ad finally, those from the user:
|
||||
self.settings.update(args)
|
||||
def register(self):
|
||||
className = self.__class__.__name__
|
||||
if className == "FilterWidget":
|
||||
self.option_object.enable_dict['filter'] = 0
|
||||
elif className == "StyleWidget":
|
||||
self.option_object[self["name"]] = self["value"]
|
||||
else:
|
||||
self.option_object[self["name"]] = self["value"]
|
||||
self.option_object.options_help[self["name"]] = (
|
||||
self["wtype"], self["help"], self["valid_text"])
|
||||
def add_gui(self, dialog): pass
|
||||
def update(self): pass
|
||||
class SpinWidget(Widget):
|
||||
""" A spinner number selector widget for GTK. """
|
||||
defaults = {
|
||||
"wtype" : "=num",
|
||||
"help" : "Numeric option",
|
||||
"valid_text": "Any number",
|
||||
}
|
||||
def add_gui(self, dialog):
|
||||
keyword = self["name"]
|
||||
obj = self.option_object.__dict__
|
||||
obj[keyword] = gtk.SpinButton()
|
||||
obj[keyword].set_digits(0)
|
||||
obj[keyword].set_increments(1,2)
|
||||
obj[keyword].set_range(0,2100)
|
||||
obj[keyword].set_numeric(True)
|
||||
obj[keyword].set_value(self.option_object[keyword])
|
||||
if self["frame"] != None:
|
||||
dialog.add_frame_option(self["frame"], self["label"], obj[keyword])
|
||||
else:
|
||||
dialog.add_option(self["label"], obj[keyword])
|
||||
def update(self):
|
||||
dict = self.option_object.__dict__
|
||||
keyword = self["name"]
|
||||
self.option_object[keyword] = dict[keyword].get_value_as_int()
|
||||
self[keyword] = dict[keyword].get_value_as_int()
|
||||
class CheckWidget(Widget):
|
||||
""" A check box widget for GTK. """
|
||||
defaults = {
|
||||
"wtype" : "=0/1",
|
||||
"help" : "Yes/No option",
|
||||
"valid_text": "1 for yes, 0 for no",
|
||||
}
|
||||
def add_gui(self, dialog):
|
||||
keyword = self["name"]
|
||||
obj = self.option_object.__dict__
|
||||
obj[keyword] = gtk.CheckButton(self["label"])
|
||||
obj[keyword].set_active(self.option_object[keyword])
|
||||
if self["frame"] != None:
|
||||
dialog.add_frame_option(self["frame"], "", obj[keyword])
|
||||
else:
|
||||
dialog.add_option("", obj[keyword])
|
||||
def update(self):
|
||||
dict = self.option_object.__dict__
|
||||
keyword = self["name"]
|
||||
self.option_object[keyword] = int(dict[keyword].get_active())
|
||||
self[keyword] = int(dict[keyword].get_active())
|
||||
class EntryWidget(Widget):
|
||||
""" A text widget for GTK. """
|
||||
defaults = {
|
||||
"wtype" : "=str",
|
||||
"help" : "String option",
|
||||
"valid_text": "Any textual data",
|
||||
}
|
||||
def add_gui(self, dialog):
|
||||
keyword = self["name"]
|
||||
obj = self.option_object.__dict__
|
||||
obj[keyword] = gtk.Entry()
|
||||
obj[keyword].set_text(self.option_object[keyword])
|
||||
if self["frame"] != None:
|
||||
dialog.add_frame_option(self["frame"], self["label"], obj[keyword])
|
||||
else:
|
||||
dialog.add_option(self["label"], obj[keyword])
|
||||
def update(self):
|
||||
dict = self.option_object.__dict__
|
||||
keyword = self["name"]
|
||||
self.option_object[keyword] = unicode(dict[keyword].get_text())
|
||||
self[keyword] = unicode(dict[keyword].get_text())
|
||||
class NumberWidget(EntryWidget):
|
||||
""" A number widget for GTK. """
|
||||
defaults = {
|
||||
"wtype" : "=num",
|
||||
"help" : "Numeric option",
|
||||
"valid_text": "Any number",
|
||||
}
|
||||
def add_gui(self, dialog):
|
||||
keyword = self["name"]
|
||||
obj = self.option_object.__dict__
|
||||
obj[keyword] = gtk.Entry()
|
||||
obj[keyword].set_text(str(self.option_object[keyword]))
|
||||
if self["frame"] != None:
|
||||
dialog.add_frame_option(self["frame"], self["label"], obj[keyword])
|
||||
else:
|
||||
dialog.add_option(self["label"], obj[keyword])
|
||||
def update(self):
|
||||
dict = self.option_object.__dict__
|
||||
keyword = self["name"]
|
||||
self.option_object[keyword] = float(dict[keyword].get_text())
|
||||
self[keyword] = float(dict[keyword].get_text())
|
||||
class StyleWidget(Widget):
|
||||
defaults = {
|
||||
"size" : 8,
|
||||
"bold" : 0,
|
||||
"italics" : 0,
|
||||
"type_face" : BaseDoc.FONT_SERIF,
|
||||
"fill_color": None,
|
||||
}
|
||||
def make_default_style(self, default_style):
|
||||
f = BaseDoc.FontStyle()
|
||||
f.set_size(self["size"])
|
||||
f.set_italic(self["italics"])
|
||||
f.set_bold(self["bold"])
|
||||
f.set_type_face(self["type_face"])
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
p.set_font(f)
|
||||
p.set_description(self["label"])
|
||||
default_style.add_style(self["name"],p)
|
||||
def define_graphics_style(self, document):
|
||||
g = BaseDoc.GraphicsStyle()
|
||||
g.set_paragraph_style(self["name"])
|
||||
if self["fill_color"]:
|
||||
g.set_fill_color(self["fill_color"])
|
||||
# FIXME: add all other graphics items (color, etc) here
|
||||
document.add_draw_style(self["name"],g)
|
||||
class FilterWidget(Widget):
|
||||
"""
|
||||
A filter widget. This doesn't have the GTK code here, but should.
|
||||
This class takes names of the filters and does everything for you.
|
||||
"all filters" - all of them
|
||||
"everyone" - all people in table
|
||||
"descendents" - direct descendents
|
||||
"descendent familes" - direct descendents and their familes
|
||||
"ancestors" - all ancestors of person
|
||||
"common ancestors" - all common ancestors
|
||||
"calendar attribute" - experimental filter for tagging people
|
||||
"""
|
||||
def get_filters(self, person):
|
||||
"""Set up the list of possible content filters."""
|
||||
if person:
|
||||
name = person.get_primary_name().get_name()
|
||||
gramps_id = person.get_gramps_id()
|
||||
else:
|
||||
name = 'PERSON'
|
||||
gramps_id = ''
|
||||
retval = []
|
||||
for filter in self["filters"]:
|
||||
if filter in ["everyone", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("Entire Database"))
|
||||
f.add_rule(GenericFilter.Everyone([]))
|
||||
retval.append(f)
|
||||
if filter in ["descendants", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("Descendants of %s") % name)
|
||||
f.add_rule(GenericFilter.IsDescendantOf([gramps_id,1]))
|
||||
retval.append(f)
|
||||
if filter in ["descendant families", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("Descendant Families of %s") % name)
|
||||
f.add_rule(GenericFilter.IsDescendantFamilyOf([gramps_id]))
|
||||
retval.append(f)
|
||||
if filter in ["ancestors", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("Ancestors of %s") % name)
|
||||
f.add_rule(GenericFilter.IsAncestorOf([gramps_id,1]))
|
||||
retval.append(f)
|
||||
if filter in ["common ancestors", "all filters"]:
|
||||
f = GenericFilter.GenericFilter()
|
||||
f.set_name(_("People with common ancestor with %s") % name)
|
||||
f.add_rule(GenericFilter.HasCommonAncestorWith([gramps_id]))
|
||||
retval.append(f)
|
||||
if filter in ["calendar attribute", "all filters"]:
|
||||
f = GenericFilter.ParamFilter()
|
||||
f.set_name(_("People with a Calendar attribute"))
|
||||
f.add_rule(GenericFilter.HasTextMatchingSubstringOf(['Calendar',0,0]))
|
||||
retval.append(f)
|
||||
return retval
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# The following could all be moved to the parent class, if you wanted
|
||||
# to adopt this report reworking. Even if you didn't want to use them
|
||||
# it would be ok to put there, because self.widgets would be empty.
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
class NewReportOptions(ReportOptions.ReportOptions):
|
||||
"""
|
||||
Defines options and provides code to handling the interface.
|
||||
This is free of any graphics specifics.
|
||||
"""
|
||||
def __getitem__(self, keyword):
|
||||
""" This could be moved up to ReportOptions """
|
||||
if keyword in self.options_dict:
|
||||
return self.options_dict[keyword]
|
||||
else:
|
||||
raise AttributeError, ("no widget named '%s'" % keyword)
|
||||
|
||||
def __setitem__(self, keyword, value):
|
||||
""" This could be moved up to ReportOptions """
|
||||
self.options_dict[keyword] = value
|
||||
|
||||
def add_user_options(self,dialog):
|
||||
for widget in self.widgets:
|
||||
widget.add_gui(dialog)
|
||||
|
||||
def parse_user_options(self,dialog):
|
||||
for widget in self.widgets:
|
||||
widget.update()
|
||||
|
||||
def get_report_filters(self,person):
|
||||
for widget in self.widgets:
|
||||
if widget.__class__.__name__ == "FilterWidget":
|
||||
return widget.get_filters(person)
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
for widget in self.widgets:
|
||||
if widget.__class__.__name__ == "StyleWidget":
|
||||
widget.make_default_style(default_style)
|
||||
|
||||
class CalendarOptions(NewReportOptions):
|
||||
def enable_options(self):
|
||||
self.enable_dict = {}
|
||||
self.widgets = [
|
||||
FilterWidget(self, label = _("Filter"),
|
||||
name = "filter",
|
||||
filters = ["all filters"]),
|
||||
EntryWidget(self, label = _("Text 1"),
|
||||
name = "text1",
|
||||
value = "My Calendar",
|
||||
help = "Large text area",
|
||||
valid_text = "Any text",
|
||||
frame = _("Text Options")
|
||||
),
|
||||
EntryWidget(self, label = _("Text 2"),
|
||||
name = "text2",
|
||||
value = "Produced with GRAMPS",
|
||||
help = "Medium size text",
|
||||
valid_text = "Any text",
|
||||
frame = _("Text Options")
|
||||
),
|
||||
EntryWidget(self, label = _("Text 3"),
|
||||
name = "text3",
|
||||
value = "http://gramps-project.org/",
|
||||
help = "Small text area",
|
||||
valid_text = "Any text",
|
||||
frame = _("Text Options")
|
||||
),
|
||||
SpinWidget(self, label = _("Year of calendar"),
|
||||
name = "year",
|
||||
value = time.localtime()[0], # the current year
|
||||
help = "Year of calendar",
|
||||
valid_text = "Any year",
|
||||
),
|
||||
CheckWidget(self, label = _("Use maiden names"),
|
||||
name = "maiden_name",
|
||||
value = 1,
|
||||
help = "Use married women's maiden name.",
|
||||
valid_text = "Select to use married women's maiden name.",
|
||||
),
|
||||
CheckWidget(self, label = _("Only include living people"),
|
||||
name = "alive",
|
||||
value = 1,
|
||||
help = "Include only living people",
|
||||
valid_text = "Select to only include living people",
|
||||
),
|
||||
CheckWidget(self, label = _("Include birthdays"),
|
||||
name = "birthdays",
|
||||
value = 1,
|
||||
help = "Include birthdays",
|
||||
valid_text = "Select to include birthdays",
|
||||
),
|
||||
CheckWidget(self, label = _("Include anniversaries"),
|
||||
name = "anniversaries",
|
||||
value = 1,
|
||||
help = "Include anniversaries",
|
||||
valid_text = "Select to include anniversaries",
|
||||
),
|
||||
CheckWidget(self, label = _("Include holidays"),
|
||||
name = "holidays",
|
||||
value = 1,
|
||||
help = "Include holidays",
|
||||
valid_text = "Select to include holidays",
|
||||
),
|
||||
NumberWidget(self, label = "Offset",
|
||||
name = "offset",
|
||||
value = -0.5,
|
||||
help = "Distance to move text on page",
|
||||
valid_text = "Any number",
|
||||
frame = "Text Options"
|
||||
),
|
||||
StyleWidget(self, label = _('Title text and background color.'),
|
||||
name = "title",
|
||||
size = 20,
|
||||
italics = 1,
|
||||
bold = 1,
|
||||
fill_color = (0xEA,0xEA,0xEA),
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Border lines of calendar boxes.'),
|
||||
name = "border",
|
||||
),
|
||||
StyleWidget(self, label = _('Calendar day numbers.'),
|
||||
name = "numbers",
|
||||
size = 13,
|
||||
bold = 1,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Daily text display.'),
|
||||
name = "text",
|
||||
size = 9,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Days of the week text.'),
|
||||
name = "daynames",
|
||||
size = 12,
|
||||
italics = 1,
|
||||
bold = 1,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Text at bottom, line 1.'),
|
||||
name = "text1style",
|
||||
size = 12,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Text at bottom, line 2.'),
|
||||
name = "text2style",
|
||||
size = 12,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
StyleWidget(self, label = _('Text at bottom, line 3.'),
|
||||
name = "text3style",
|
||||
size = 9,
|
||||
type_face = BaseDoc.FONT_SERIF,
|
||||
),
|
||||
]
|
||||
|
||||
class Element:
|
||||
""" A parsed XML element """
|
||||
def __init__(self,name,attributes):
|
||||
'Element constructor'
|
||||
# The element's tag name
|
||||
self.name = name
|
||||
# The element's attribute dictionary
|
||||
self.attributes = attributes
|
||||
# The element's cdata
|
||||
self.cdata = ''
|
||||
# The element's child element list (sequence)
|
||||
self.children = []
|
||||
|
||||
def AddChild(self,element):
|
||||
'Add a reference to a child element'
|
||||
self.children.append(element)
|
||||
|
||||
def getAttribute(self,key):
|
||||
'Get an attribute value'
|
||||
return self.attributes.get(key)
|
||||
|
||||
def getData(self):
|
||||
'Get the cdata'
|
||||
return self.cdata
|
||||
|
||||
def getElements(self,name=''):
|
||||
'Get a list of child elements'
|
||||
#If no tag name is specified, return the all children
|
||||
if not name:
|
||||
return self.children
|
||||
else:
|
||||
# else return only those children with a matching tag name
|
||||
elements = []
|
||||
for element in self.children:
|
||||
if element.name == name:
|
||||
elements.append(element)
|
||||
return elements
|
||||
|
||||
def toString(self, level=0):
|
||||
retval = " " * level
|
||||
retval += "<%s" % self.name
|
||||
for attribute in self.attributes:
|
||||
retval += " %s=\"%s\"" % (attribute, self.attributes[attribute])
|
||||
c = ""
|
||||
for child in self.children:
|
||||
c += child.toString(level+1)
|
||||
if c == "":
|
||||
retval += "/>\n"
|
||||
else:
|
||||
retval += ">\n" + c + ("</%s>\n" % self.name)
|
||||
return retval
|
||||
|
||||
class Xml2Obj:
|
||||
""" XML to Object """
|
||||
def __init__(self):
|
||||
self.root = None
|
||||
self.nodeStack = []
|
||||
|
||||
def StartElement(self,name,attributes):
|
||||
'SAX start element even handler'
|
||||
# Instantiate an Element object
|
||||
element = Element(name.encode(),attributes)
|
||||
# Push element onto the stack and make it a child of parent
|
||||
if len(self.nodeStack) > 0:
|
||||
parent = self.nodeStack[-1]
|
||||
parent.AddChild(element)
|
||||
else:
|
||||
self.root = element
|
||||
self.nodeStack.append(element)
|
||||
|
||||
def EndElement(self,name):
|
||||
'SAX end element event handler'
|
||||
self.nodeStack = self.nodeStack[:-1]
|
||||
|
||||
def CharacterData(self,data):
|
||||
'SAX character data event handler'
|
||||
if data.strip():
|
||||
data = data.encode()
|
||||
element = self.nodeStack[-1]
|
||||
element.cdata += data
|
||||
return
|
||||
|
||||
def Parse(self,filename):
|
||||
# Create a SAX parser
|
||||
Parser = expat.ParserCreate()
|
||||
# SAX event handlers
|
||||
Parser.StartElementHandler = self.StartElement
|
||||
Parser.EndElementHandler = self.EndElement
|
||||
Parser.CharacterDataHandler = self.CharacterData
|
||||
# Parse the XML File
|
||||
ParserStatus = Parser.Parse(open(filename,'r').read(), 1)
|
||||
return self.root
|
||||
|
||||
class Holidays:
|
||||
""" Class used to read XML holidays to add to calendar. """
|
||||
def __init__(self, elements, country="US"):
|
||||
self.debug = 0
|
||||
self.elements = elements
|
||||
self.country = country
|
||||
self.dates = []
|
||||
self.initialize()
|
||||
def set_country(self, country):
|
||||
self.country = country
|
||||
self.dates = []
|
||||
self.initialize()
|
||||
def initialize(self):
|
||||
# parse the date objects
|
||||
for country_set in self.elements.children:
|
||||
if country_set.name == "country" and country_set.attributes["name"] == self.country:
|
||||
for date in country_set.children:
|
||||
if date.name == "date":
|
||||
data = {"value" : "",
|
||||
"name" : "",
|
||||
"offset": "",
|
||||
"type": "",
|
||||
"if": "",
|
||||
} # defaults
|
||||
for attr in date.attributes:
|
||||
data[attr] = date.attributes[attr]
|
||||
self.dates.append(data)
|
||||
def get_daynames(self, y, m, dayname):
|
||||
if self.debug: print "%s's in %d %d..." % (dayname, m, y)
|
||||
retval = [0]
|
||||
dow = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'].index(dayname)
|
||||
for d in range(1, 32):
|
||||
try:
|
||||
date = datetime.date(y, m, d)
|
||||
except ValueError:
|
||||
continue
|
||||
if date.weekday() == dow:
|
||||
retval.append( d )
|
||||
if self.debug: print "dow=", dow, "days=", retval
|
||||
return retval
|
||||
def check_date(self, date):
|
||||
retval = []
|
||||
for rule in self.dates:
|
||||
if self.debug: print "Checking ", rule["name"], "..."
|
||||
offset = 0
|
||||
if rule["offset"] != "":
|
||||
if rule["offset"].isdigit():
|
||||
offset = int(rule["offset"])
|
||||
elif rule["offset"][0] in ["-","+"] and rule["offset"][1:].isdigit():
|
||||
offset = int(rule["offset"])
|
||||
else:
|
||||
# must be a dayname
|
||||
offset = rule["offset"]
|
||||
if rule["value"].count("/") == 3: # year/num/day/month, "3rd wednesday in april"
|
||||
y, num, dayname, mon = rule["value"].split("/")
|
||||
if y == "*":
|
||||
y = date.year
|
||||
else:
|
||||
y = int(y)
|
||||
if mon.isdigit():
|
||||
m = int(mon)
|
||||
elif mon == "*":
|
||||
m = date.month
|
||||
else:
|
||||
m = ['jan', 'feb', 'mar', 'apr', 'may', 'jun',
|
||||
'jul', 'aug', 'sep', 'oct', 'nov', 'dec'].index(mon) + 1
|
||||
dates_of_dayname = self.get_daynames(y, m, dayname)
|
||||
if self.debug: print "num =", num
|
||||
d = dates_of_dayname[int(num)]
|
||||
elif rule["value"].count("/") == 2: # year/month/day
|
||||
y, m, d = rule["value"].split("/")
|
||||
if y == "*":
|
||||
y = date.year
|
||||
else:
|
||||
y = int(y)
|
||||
if m == "*":
|
||||
m = date.month
|
||||
else:
|
||||
m = int(m)
|
||||
if d == "*":
|
||||
d = date.day
|
||||
else:
|
||||
d = int(d)
|
||||
ndate = datetime.date(y, m, d)
|
||||
if self.debug: print ndate, offset, type(offset)
|
||||
if type(offset) == int:
|
||||
if offset != 0:
|
||||
ndate = ndate.fromordinal(ndate.toordinal() + offset)
|
||||
elif type(offset) in [type(u''), str]:
|
||||
dir = 1
|
||||
if offset[0] == "-":
|
||||
dir = -1
|
||||
offset = offset[1:]
|
||||
if offset in ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']:
|
||||
# next tuesday you come to, including this one
|
||||
dow = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'].index(offset)
|
||||
ord = ndate.toordinal()
|
||||
while ndate.fromordinal(ord).weekday() != dow:
|
||||
ord += dir
|
||||
ndate = ndate.fromordinal(ord)
|
||||
if self.debug: print "ndate:", ndate, "date:", date
|
||||
if ndate == date:
|
||||
if rule["if"] != "":
|
||||
if not eval(rule["if"]):
|
||||
continue
|
||||
retval.append(rule["name"])
|
||||
return retval
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Register this plugin
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from PluginMgr import register_report
|
||||
register_report(
|
||||
name = 'calendar',
|
||||
category = Report.CATEGORY_DRAW,
|
||||
report_class = Calendar,
|
||||
options_class = CalendarOptions,
|
||||
modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI,
|
||||
translated_name = _("Calendar"),
|
||||
status = _("Experimental"),
|
||||
author_name = "Douglas S. Blank",
|
||||
author_email = "Doug.Blank@gmail.com",
|
||||
description = _("Produces a graphical calendar"),
|
||||
)
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -80,10 +80,11 @@ class ChangeTypes(Tool.Tool):
|
||||
|
||||
AutoComp.fill_combo(self.auto1,const.personalEvents)
|
||||
AutoComp.fill_combo(self.auto2,const.personalEvents)
|
||||
self.auto1.child.set_text(
|
||||
self.options.handler.options_dict['fromtype'])
|
||||
self.auto2.child.set_text(
|
||||
self.options.handler.options_dict['totype'])
|
||||
# Need to display localized event names
|
||||
self.auto1.child.set_text(const.display_event(
|
||||
self.options.handler.options_dict['fromtype']))
|
||||
self.auto2.child.set_text(const.display_event(
|
||||
self.options.handler.options_dict['totype']))
|
||||
|
||||
self.title = _('Change Event Types')
|
||||
self.window = self.glade.get_widget('top')
|
||||
@ -103,6 +104,7 @@ class ChangeTypes(Tool.Tool):
|
||||
|
||||
def run_tool(self,cli=False):
|
||||
# Run tool and return results
|
||||
# These are English names, no conversion needed
|
||||
fromtype = self.options.handler.options_dict['fromtype']
|
||||
totype = self.options.handler.options_dict['totype']
|
||||
|
||||
@ -162,10 +164,11 @@ class ChangeTypes(Tool.Tool):
|
||||
self.window.present()
|
||||
|
||||
def on_apply_clicked(self,obj):
|
||||
self.options.handler.options_dict['fromtype'] = unicode(
|
||||
self.auto1.child.get_text())
|
||||
self.options.handler.options_dict['totype'] = unicode(
|
||||
self.auto2.child.get_text())
|
||||
# Need to store English names for later comparison
|
||||
self.options.handler.options_dict['fromtype'] = const.save_event(
|
||||
unicode(self.auto1.child.get_text()))
|
||||
self.options.handler.options_dict['totype'] = const.save_event(
|
||||
unicode(self.auto2.child.get_text()))
|
||||
|
||||
modified,msg = self.run_tool(cli=False)
|
||||
OkDialog(_('Change types'),msg,self.parent.topWindow)
|
||||
|
@ -51,6 +51,79 @@ import const
|
||||
import Tool
|
||||
from QuestionDialog import OkDialog, MissingMediaDialog
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Low Level repair
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def low_level(db):
|
||||
"""
|
||||
This is a low-level repair routine.
|
||||
|
||||
It is fixing DB inconsistencies such as duplicates.
|
||||
Returns a (status,name) tuple.
|
||||
The boolean status indicates the success of the procedure.
|
||||
The name indicates the problematic table (empty if status is True).
|
||||
"""
|
||||
|
||||
for the_map in [('Person',db.person_map),
|
||||
('Family',db.family_map),
|
||||
('Event',db.event_map),
|
||||
('Place',db.place_map),
|
||||
('Source',db.source_map),
|
||||
('Media',db.media_map)]:
|
||||
|
||||
print "Low-level repair: table: %s" % the_map[0]
|
||||
if _table_low_level(db,the_map[1]):
|
||||
print "Done."
|
||||
else:
|
||||
print "Low-level repair: Problem with table: %s" % the_map[0]
|
||||
return (False,the_map[0])
|
||||
return (True,'')
|
||||
|
||||
|
||||
def _table_low_level(db,table):
|
||||
"""
|
||||
Low level repair for a given db table.
|
||||
"""
|
||||
handle_list = table.keys()
|
||||
dup_handles = sets.Set(
|
||||
[ handle for handle in handle_list if handle_list.count(handle) > 1 ]
|
||||
)
|
||||
|
||||
if not dup_handles:
|
||||
print " No dupes found for this table"
|
||||
return True
|
||||
|
||||
import GrampsBSDDB
|
||||
table_cursor = GrampsBSDDB.GrampsBSDDBDupCursor(table)
|
||||
for handle in dup_handles:
|
||||
print " Duplicates found for handle: %s" % handle
|
||||
try:
|
||||
ret = table_cursor.set(handle)
|
||||
except:
|
||||
print " Failed setting initial cursor."
|
||||
return False
|
||||
|
||||
for count in range(handle_list.count(handle)-1):
|
||||
try:
|
||||
table_cursor.delete()
|
||||
print " Succesfully deleted dupe #%d" % (count+1)
|
||||
except:
|
||||
print " Failed deleting dupe."
|
||||
return False
|
||||
|
||||
try:
|
||||
ret = table_cursor.next_dup()
|
||||
except:
|
||||
print " Failed moving the cursor."
|
||||
return False
|
||||
|
||||
table_cursor.close()
|
||||
table.sync()
|
||||
return True
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# runTool
|
||||
@ -68,6 +141,12 @@ class Check(Tool.Tool):
|
||||
# TODO: split plugin in a check and repair part to support
|
||||
# checking of a read only database
|
||||
return
|
||||
|
||||
# The low-level repair is bypassing the transaction mechanism.
|
||||
# As such, we run it before starting the transaction.
|
||||
# We only do this for the BSDDB backend.
|
||||
if db.__class__.__name__ == 'GrampsBSDDB':
|
||||
low_level(db)
|
||||
|
||||
trans = db.transaction_begin("",batch=True)
|
||||
db.disable_signals()
|
||||
@ -136,10 +215,8 @@ class CheckIntegrity:
|
||||
self.progress.set_pass(_('Looking for duplicate spouses'),
|
||||
self.db.get_number_of_people())
|
||||
|
||||
cursor = self.db.get_person_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
(handle,value) = data
|
||||
for handle in self.db.person_map.keys():
|
||||
value = self.db.person_map[handle]
|
||||
p = RelLib.Person(value)
|
||||
splist = p.get_family_handle_list()
|
||||
if len(splist) != len(sets.Set(splist)):
|
||||
@ -150,27 +227,21 @@ class CheckIntegrity:
|
||||
self.duplicate_links.append((handle,value))
|
||||
p.set_family_handle_list(new_list)
|
||||
self.db.commit_person(p,self.trans)
|
||||
data = cursor.next()
|
||||
self.progress.step()
|
||||
cursor.close()
|
||||
|
||||
|
||||
def fix_encoding(self):
|
||||
self.progress.set_pass(_('Looking for character encoding errors'),
|
||||
self.db.get_number_of_media_objects())
|
||||
|
||||
cursor = self.db.get_media_cursor()
|
||||
value = cursor.first()
|
||||
while value:
|
||||
(handle,data) = value
|
||||
for handle in self.db.media_map.keys():
|
||||
data = self.db.media_map[handle]
|
||||
if type(data[2]) != unicode or type(data[4]) != unicode:
|
||||
obj = self.db.get_object_from_handle(handle)
|
||||
obj.path = Utils.fix_encoding( obj.path)
|
||||
obj.desc = Utils.fix_encoding( obj.desc)
|
||||
self.db.commit_media_object(obj,self.trans)
|
||||
self.progress.step()
|
||||
value = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
def check_for_broken_family_links(self):
|
||||
# Check persons referenced by the family objects
|
||||
@ -558,11 +629,9 @@ class CheckIntegrity:
|
||||
self.progress.set_pass(_('Looking for source reference problems'),
|
||||
total)
|
||||
|
||||
cursor = self.db.get_person_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.person_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.person_map[handle]
|
||||
person = RelLib.Person()
|
||||
person.unserialize(info)
|
||||
handle_list = person.get_referenced_handles_recursively()
|
||||
@ -575,14 +644,10 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_family_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.family_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.family_map[handle]
|
||||
family = RelLib.Family()
|
||||
family.unserialize(info)
|
||||
handle_list = family.get_referenced_handles_recursively()
|
||||
@ -595,14 +660,10 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_place_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.place_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.place_map[handle]
|
||||
place = RelLib.Place()
|
||||
place.unserialize(info)
|
||||
handle_list = place.get_referenced_handles_recursively()
|
||||
@ -611,18 +672,14 @@ class CheckIntegrity:
|
||||
item[1] not in known_handles ]
|
||||
if bad_handles:
|
||||
place.remove_source_references(bad_handles)
|
||||
self.db.commit_family(place,self.trans)
|
||||
self.db.commit_place(place,self.trans)
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_source_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in known_handles:
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.source_map[handle]
|
||||
source = RelLib.Source()
|
||||
source.unserialize(info)
|
||||
handle_list = source.get_referenced_handles_recursively()
|
||||
@ -635,14 +692,10 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_media_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.media_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.media_map[handle]
|
||||
obj = RelLib.MediaObject()
|
||||
obj.unserialize(info)
|
||||
handle_list = obj.get_referenced_handles_recursively()
|
||||
@ -655,14 +708,10 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
cursor = self.db.get_event_cursor()
|
||||
data = cursor.first()
|
||||
while data:
|
||||
for handle in self.db.event_map.keys():
|
||||
self.progress.step()
|
||||
handle,info = data
|
||||
info = self.db.event_map[handle]
|
||||
event = RelLib.Event()
|
||||
event.unserialize(info)
|
||||
handle_list = event.get_referenced_handles_recursively()
|
||||
@ -675,8 +724,6 @@ class CheckIntegrity:
|
||||
new_bad_handles = [handle for handle in bad_handles if handle
|
||||
not in self.invalid_source_references]
|
||||
self.invalid_source_references += new_bad_handles
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
def build_report(self,cl=0):
|
||||
self.progress.close()
|
||||
|
@ -112,13 +112,15 @@ class DescendantReport(Report.Report):
|
||||
if birth:
|
||||
bplace_handle = birth.get_place_handle()
|
||||
if bplace_handle:
|
||||
birth_place = self.database.get_place_from_handle(bplace_handle).get_title()
|
||||
birth_place = self.database.get_place_from_handle(
|
||||
bplace_handle).get_title()
|
||||
|
||||
death_place = ""
|
||||
if death:
|
||||
dplace_handle = death.get_place_handle()
|
||||
if dplace_handle:
|
||||
death_place = self.database.get_place_from_handle(dplace_handle).get_title()
|
||||
death_place = self.database.get_place_from_handle(
|
||||
dplace_handle).get_title()
|
||||
|
||||
if birth_year_valid:
|
||||
if birth_place:
|
||||
@ -163,7 +165,6 @@ class DescendantReport(Report.Report):
|
||||
if level >= self.max_generations:
|
||||
return
|
||||
|
||||
childlist = []
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
|
||||
@ -176,10 +177,9 @@ class DescendantReport(Report.Report):
|
||||
self.dump_dates(spouse)
|
||||
self.doc.end_paragraph()
|
||||
|
||||
for child_handle in family.get_child_handle_list():
|
||||
childlist.append(child_handle)
|
||||
|
||||
childlist = family.get_child_handle_list()[:]
|
||||
childlist.sort(self.by_birthdate)
|
||||
|
||||
for child_handle in childlist:
|
||||
child = self.database.get_person_from_handle(child_handle)
|
||||
self.dump(level+1,child)
|
||||
@ -230,7 +230,8 @@ class DescendantOptions(ReportOptions.ReportOptions):
|
||||
p.set_bottom_margin(ReportUtils.pt2cm(f.get_size()*0.125))
|
||||
p.set_first_indent(-0.5)
|
||||
p.set_left_margin(min(10.0,float(i-0.5)))
|
||||
p.set_description(_("The style used for the level %d display.") % i)
|
||||
p.set_description(_("The style used for the "
|
||||
"level %d display.") % i)
|
||||
default_style.add_style("DR-Level%d" % i,p)
|
||||
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
@ -238,7 +239,8 @@ class DescendantOptions(ReportOptions.ReportOptions):
|
||||
p.set_top_margin(ReportUtils.pt2cm(f.get_size()*0.125))
|
||||
p.set_bottom_margin(ReportUtils.pt2cm(f.get_size()*0.125))
|
||||
p.set_left_margin(min(10.0,float(i-0.5)))
|
||||
p.set_description(_("The style used for the spouse level %d display.") % i)
|
||||
p.set_description(_("The style used for the "
|
||||
"spouse level %d display.") % i)
|
||||
default_style.add_style("DR-Spouse%d" % i,p)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2002 Bruce J. DeGrasse
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -235,8 +235,9 @@ class DetAncestorReport(Report.Report):
|
||||
self.endnotes(self.database.get_event_from_handle(birth_handle))
|
||||
first = 0
|
||||
|
||||
age,units = self.calc_age(person)
|
||||
text = ReportUtils.died_str(self.database,person,first,
|
||||
self.EMPTY_DATE,self.EMPTY_PLACE)
|
||||
self.EMPTY_DATE,self.EMPTY_PLACE,age,units)
|
||||
if text:
|
||||
self.doc.write_text(text)
|
||||
death_handle = person.get_birth_handle()
|
||||
@ -503,25 +504,29 @@ class DetAncestorReport(Report.Report):
|
||||
self.doc.start_paragraph('DAR-Endnotes',"%d." % key)
|
||||
self.doc.write_text(base.get_title())
|
||||
|
||||
for item in [ base.get_author(), base.get_publication_info(),
|
||||
base.get_abbreviation(),
|
||||
_dd.display(srcref.get_date_object()),]:
|
||||
if item:
|
||||
self.doc.write_text('; %s' % item)
|
||||
|
||||
item = srcref.get_text()
|
||||
if item:
|
||||
self.doc.write_text('; ')
|
||||
self.doc.write_text(_('Text:'))
|
||||
self.doc.write_text(' ')
|
||||
self.doc.write_text(item)
|
||||
|
||||
item = srcref.get_note()
|
||||
if item:
|
||||
self.doc.write_text('; ')
|
||||
self.doc.write_text(_('Comments:'))
|
||||
self.doc.write_text(' ')
|
||||
self.doc.write_text(item)
|
||||
# Disable writing reference details, because only the details
|
||||
# the first reference to this source will appear.
|
||||
# FIXME: need to properly change self.endnotes() to put
|
||||
# this feature back correclty.
|
||||
## for item in [ base.get_author(), base.get_publication_info(),
|
||||
## base.get_abbreviation(),
|
||||
## _dd.display(srcref.get_date_object()),]:
|
||||
## if item:
|
||||
## self.doc.write_text('; %s' % item)
|
||||
##
|
||||
## item = srcref.get_text()
|
||||
## if item:
|
||||
## self.doc.write_text('; ')
|
||||
## self.doc.write_text(_('Text:'))
|
||||
## self.doc.write_text(' ')
|
||||
## self.doc.write_text(item)
|
||||
##
|
||||
## item = srcref.get_note()
|
||||
## if item:
|
||||
## self.doc.write_text('; ')
|
||||
## self.doc.write_text(_('Comments:'))
|
||||
## self.doc.write_text(' ')
|
||||
## self.doc.write_text(item)
|
||||
|
||||
self.doc.write_text('.')
|
||||
self.doc.end_paragraph()
|
||||
@ -551,9 +556,9 @@ class DetAncestorReport(Report.Report):
|
||||
self.sref_map[self.sref_index] = ref
|
||||
msg.write("%d" % self.sref_index)
|
||||
msg.write('</super>')
|
||||
str = msg.getvalue()
|
||||
the_str = msg.getvalue()
|
||||
msg.close()
|
||||
return str
|
||||
return the_str
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2002 Bruce J. DeGrasse
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -88,6 +88,7 @@ class DetDescendantReport(Report.Report):
|
||||
firstName - Whether to use first names instead of pronouns.
|
||||
fullDate - Whether to use full dates instead of just year.
|
||||
listChildren - Whether to list children.
|
||||
includeMates - Whether to include information about spouses
|
||||
includeNotes - Whether to include notes.
|
||||
blankPlace - Whether to replace missing Places with ___________.
|
||||
blankDate - Whether to replace missing Dates with ___________.
|
||||
@ -116,6 +117,7 @@ class DetDescendantReport(Report.Report):
|
||||
self.includeNames = options_class.handler.options_dict['incnames']
|
||||
self.includeEvents = options_class.handler.options_dict['incevents']
|
||||
self.includeSources= options_class.handler.options_dict['incsources']
|
||||
self.includeMates = options_class.handler.options_dict['incmates']
|
||||
|
||||
self.gen_handles = {}
|
||||
self.prev_gen_handles= {}
|
||||
@ -261,9 +263,10 @@ class DetDescendantReport(Report.Report):
|
||||
if birth_handle:
|
||||
self.endnotes(self.database.get_event_from_handle(birth_handle))
|
||||
first = 0
|
||||
|
||||
|
||||
age,units = self.calc_age(person)
|
||||
text = ReportUtils.died_str(self.database,person,first,
|
||||
self.EMPTY_DATE,self.EMPTY_PLACE)
|
||||
self.EMPTY_DATE,self.EMPTY_PLACE,age,units)
|
||||
if text:
|
||||
self.doc.write_text(text)
|
||||
death_handle = person.get_birth_handle()
|
||||
@ -283,7 +286,7 @@ class DetDescendantReport(Report.Report):
|
||||
self.write_marriage(person)
|
||||
self.doc.end_paragraph()
|
||||
|
||||
if key == 1:
|
||||
if self.includeMates:
|
||||
self.write_mate(person)
|
||||
|
||||
if person.get_note() != "" and self.includeNotes:
|
||||
@ -528,24 +531,28 @@ class DetDescendantReport(Report.Report):
|
||||
self.doc.start_paragraph('DDR-Endnotes',"%d." % key)
|
||||
self.doc.write_text(base.get_title())
|
||||
|
||||
for item in [ base.get_author(), base.get_publication_info(), base.get_abbreviation(),
|
||||
_dd.display(srcref.get_date_object()),]:
|
||||
if item:
|
||||
self.doc.write_text('; %s' % item)
|
||||
|
||||
item = srcref.get_text()
|
||||
if item:
|
||||
self.doc.write_text('; ')
|
||||
self.doc.write_text(_('Text:'))
|
||||
self.doc.write_text(' ')
|
||||
self.doc.write_text(item)
|
||||
|
||||
item = srcref.get_note()
|
||||
if item:
|
||||
self.doc.write_text('; ')
|
||||
self.doc.write_text(_('Comments:'))
|
||||
self.doc.write_text(' ')
|
||||
self.doc.write_text(item)
|
||||
# Disable writing reference details, because only the details
|
||||
# the first reference to this source will appear.
|
||||
# FIXME: need to properly change self.endnotes() to put
|
||||
# this feature back correclty.
|
||||
## for item in [ base.get_author(), base.get_publication_info(), base.get_abbreviation(),
|
||||
## _dd.display(srcref.get_date_object()),]:
|
||||
## if item:
|
||||
## self.doc.write_text('; %s' % item)
|
||||
##
|
||||
## item = srcref.get_text()
|
||||
## if item:
|
||||
## self.doc.write_text('; ')
|
||||
## self.doc.write_text(_('Text:'))
|
||||
## self.doc.write_text(' ')
|
||||
## self.doc.write_text(item)
|
||||
##
|
||||
## item = srcref.get_note()
|
||||
## if item:
|
||||
## self.doc.write_text('; ')
|
||||
## self.doc.write_text(_('Comments:'))
|
||||
## self.doc.write_text(' ')
|
||||
## self.doc.write_text(item)
|
||||
|
||||
self.doc.write_text('.')
|
||||
self.doc.end_paragraph()
|
||||
@ -610,6 +617,7 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
'incnames' : 0,
|
||||
'incevents' : 0,
|
||||
'incsources' : 0,
|
||||
'incmates' : 1,
|
||||
}
|
||||
self.options_help = {
|
||||
'fulldates' : ("=0/1","Whether to use full dates instead of just year.",
|
||||
@ -651,6 +659,9 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
'incsources' : ("=0/1","Whether to include source references.",
|
||||
["Do not include sources","Include sources"],
|
||||
True),
|
||||
'incmates' : ("=0/1","Whether to include detailed spouse information.",
|
||||
["Do not include spouse info","Include spouse info"],
|
||||
True),
|
||||
}
|
||||
|
||||
def enable_options(self):
|
||||
@ -820,6 +831,10 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
self.include_sources_option = gtk.CheckButton(_("Include sources"))
|
||||
self.include_sources_option.set_active(self.options_dict['incsources'])
|
||||
|
||||
# Print Spouses
|
||||
self.include_spouses_option = gtk.CheckButton(_("Include spouses"))
|
||||
self.include_spouses_option.set_active(self.options_dict['incmates'])
|
||||
|
||||
# Add new options. The first argument is the tab name for grouping options.
|
||||
# if you want to put everyting in the generic "Options" category, use
|
||||
# self.add_option(text,widget) instead of self.add_frame_option(category,text,widget)
|
||||
@ -834,6 +849,7 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
dialog.add_frame_option(_('Include'),'',self.include_names_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_events_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_sources_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_spouses_option)
|
||||
dialog.add_frame_option(_('Missing information'),'',self.place_option)
|
||||
dialog.add_frame_option(_('Missing information'),'',self.date_option)
|
||||
|
||||
@ -854,6 +870,7 @@ class DetDescendantOptions(ReportOptions.ReportOptions):
|
||||
self.options_dict['incnames'] = int(self.include_names_option.get_active())
|
||||
self.options_dict['incevents'] = int(self.include_events_option.get_active())
|
||||
self.options_dict['incsources'] = int(self.include_sources_option.get_active())
|
||||
self.options_dict['incmates'] = int(self.include_spouses_option.get_active())
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -312,8 +312,9 @@ class DisplayChart:
|
||||
|
||||
titles = []
|
||||
index = 0
|
||||
for v in self.event_titles:
|
||||
titles.append((v,index,150))
|
||||
for event_name in self.event_titles:
|
||||
# Need to display localized event names
|
||||
titles.append((const.display_event(event_name),index,150))
|
||||
index = index + 1
|
||||
|
||||
self.list = ListModel.ListModel(self.eventlist,titles)
|
||||
@ -436,10 +437,12 @@ class DisplayChart:
|
||||
|
||||
pstyle = BaseDoc.PaperStyle("junk",10,10)
|
||||
doc = OpenSpreadSheet.OpenSpreadSheet(pstyle,BaseDoc.PAPER_PORTRAIT)
|
||||
doc.creator(self.db.get_researcher().get_name())
|
||||
spreadsheet = TableReport(name,doc)
|
||||
spreadsheet.initialize(len(self.event_titles))
|
||||
|
||||
spreadsheet.write_table_head(self.event_titles)
|
||||
spreadsheet.write_table_head([const.display_event(event_name)
|
||||
for event_name in self.event_titles])
|
||||
|
||||
index = 0
|
||||
for top in self.row_data:
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -72,7 +72,7 @@ class FamilyGroup(Report.Report):
|
||||
"""
|
||||
Report.Report.__init__(self,database,person,options_class)
|
||||
|
||||
self.family = None
|
||||
self.family_handle = None
|
||||
|
||||
spouse_id = options_class.handler.options_dict['spouse_id']
|
||||
if spouse_id:
|
||||
@ -86,9 +86,18 @@ class FamilyGroup(Report.Report):
|
||||
this_spouse = database.get_person_from_handle(this_spouse_handle)
|
||||
this_spouse_id = this_spouse.get_gramps_id()
|
||||
if spouse_id == this_spouse_id:
|
||||
self.family = family
|
||||
self.family_handle = family_handle
|
||||
break
|
||||
|
||||
self.recursive = options_class.handler.options_dict['recursive']
|
||||
self.missingInfo = options_class.handler.options_dict['missinginfo']
|
||||
self.generations = options_class.handler.options_dict['generations']
|
||||
self.incParEvents = options_class.handler.options_dict['incParEvents']
|
||||
self.incParAddr = options_class.handler.options_dict['incParAddr']
|
||||
self.incParNotes = options_class.handler.options_dict['incParNotes']
|
||||
self.incParNames = options_class.handler.options_dict['incParNames']
|
||||
self.incRelDates = options_class.handler.options_dict['incRelDates']
|
||||
|
||||
def define_table_styles(self):
|
||||
"""
|
||||
Define the table styles used by the report.
|
||||
@ -152,18 +161,58 @@ class FamilyGroup(Report.Report):
|
||||
table.set_column_width(3,40)
|
||||
self.doc.add_table_style('FGR-ChildTable',table)
|
||||
|
||||
def dump_parent_event(self,name,event):
|
||||
place = ""
|
||||
date = ""
|
||||
if event:
|
||||
date = event.get_date()
|
||||
place_handle = event.get_place_handle()
|
||||
if place_handle:
|
||||
place = self.database.get_place_from_handle(place_handle).get_title()
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(date)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(place)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
def dump_parent_line(self,name,text):
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd",2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(text)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
def dump_parent(self,person_handle):
|
||||
|
||||
if not person_handle:
|
||||
return
|
||||
|
||||
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
|
||||
|
||||
if person.get_gender() == RelLib.Person.MALE:
|
||||
the_id = _("Husband")
|
||||
else:
|
||||
the_id = _("Wife")
|
||||
|
||||
|
||||
self.doc.start_table(the_id,'FGR-ParentTable')
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-ParentHead',3)
|
||||
@ -173,62 +222,20 @@ class FamilyGroup(Report.Report):
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
|
||||
birth_handle = person.get_birth_handle()
|
||||
bdate = ""
|
||||
bplace = ""
|
||||
birth = None
|
||||
if birth_handle:
|
||||
birth = self.database.get_event_from_handle(birth_handle)
|
||||
bdate = DateHandler.get_date(birth)
|
||||
bplace_handle = birth.get_place_handle()
|
||||
if bplace_handle:
|
||||
bplace = self.database.get_place_from_handle(bplace_handle).get_title()
|
||||
|
||||
if birth or self.missingInfo:
|
||||
self.dump_parent_event(_("Birth"),birth)
|
||||
|
||||
death_handle = person.get_death_handle()
|
||||
ddate = ""
|
||||
dplace = ""
|
||||
death = None
|
||||
if death_handle:
|
||||
death = self.database.get_event_from_handle(death_handle)
|
||||
ddate = DateHandler.get_date(death)
|
||||
dplace_handle = death.get_place_handle()
|
||||
if dplace_handle:
|
||||
dplace = self.database.get_place_from_handle(dplace_handle).get_title()
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Birth"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(bdate)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(bplace)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Death"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(ddate)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(dplace)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
if death or self.missingInfo:
|
||||
self.dump_parent_event(_("Death"),death)
|
||||
|
||||
family_handle = person.get_main_parents_family_handle()
|
||||
father_name = ""
|
||||
@ -237,36 +244,81 @@ class FamilyGroup(Report.Report):
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
father_handle = family.get_father_handle()
|
||||
if father_handle:
|
||||
father_name = self.database.get_person_from_handle(father_handle).get_primary_name().get_regular_name()
|
||||
father = self.database.get_person_from_handle(father_handle)
|
||||
father_name = father.get_primary_name().get_regular_name()
|
||||
if self.incRelDates:
|
||||
birth_handle = father.get_birth_handle()
|
||||
birth = " "
|
||||
if birth_handle:
|
||||
birth = self.database.get_event_from_handle(birth_handle).get_date()
|
||||
death_handle = father.get_death_handle()
|
||||
death = " "
|
||||
if death_handle:
|
||||
death = self.database.get_event_from_handle(death_handle).get_date()
|
||||
if birth_handle or death_handle:
|
||||
father_name = "%s (%s - %s)" % (father_name,birth,death)
|
||||
mother_handle = family.get_mother_handle()
|
||||
if mother_handle:
|
||||
mother_name = self.database.get_person_from_handle(mother_handle).get_primary_name().get_regular_name()
|
||||
mother = self.database.get_person_from_handle(mother_handle)
|
||||
mother_name = mother.get_primary_name().get_regular_name()
|
||||
if self.incRelDates:
|
||||
birth_handle = mother.get_birth_handle()
|
||||
birth = " "
|
||||
if birth_handle:
|
||||
birth = self.database.get_event_from_handle(birth_handle).get_date()
|
||||
death_handle = mother.get_death_handle()
|
||||
death = " "
|
||||
if death_handle:
|
||||
death = self.database.get_event_from_handle(death_handle).get_date()
|
||||
if birth_handle or death_handle:
|
||||
mother_name = "%s (%s - %s)" % (mother_name,birth,death)
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Father"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd",2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(father_name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
if self.missingInfo or father_name != "":
|
||||
self.dump_parent_line(_("Father"),father_name)
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Mother"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd",2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(mother_name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
if self.missingInfo or mother_name != "":
|
||||
self.dump_parent_line(_("Mother"),mother_name)
|
||||
|
||||
if self.incParEvents:
|
||||
for event_handle in person.get_event_list():
|
||||
event = self.database.get_event_from_handle(event_handle)
|
||||
evtName = event.get_name()
|
||||
if (evtName != "Death") and (evtName != "Birth"):
|
||||
self.dump_parent_event(_(evtName),event)
|
||||
|
||||
if self.incParAddr:
|
||||
addrlist = person.get_address_list()[:]
|
||||
for addr in addrlist:
|
||||
location = "%s %s %s %s" % (addr.get_street(),addr.get_city(),
|
||||
addr.get_state(),addr.get_country())
|
||||
date = addr.get_date()
|
||||
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Address"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContents")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(date)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell("FGR-TextContentsEnd")
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(location)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
if self.incParNotes and (person.get_note() != ""):
|
||||
self.dump_parent_line(_("Notes"),person.get_note())
|
||||
|
||||
if self.incParNames:
|
||||
for alt_name in person.get_alternate_names():
|
||||
type = const.NameTypesMap.find_value(alt_name.get_type())
|
||||
name = alt_name.get_regular_name()
|
||||
self.dump_parent_line(type,name)
|
||||
|
||||
self.doc.end_table()
|
||||
|
||||
@ -304,22 +356,6 @@ class FamilyGroup(Report.Report):
|
||||
def dump_child(self,index,person_handle):
|
||||
|
||||
person = self.database.get_person_from_handle(person_handle)
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-TextChild1')
|
||||
self.doc.start_paragraph('FGR-ChildText')
|
||||
if person.get_gender() == RelLib.Person.MALE:
|
||||
self.doc.write_text("%dM" % index)
|
||||
else:
|
||||
self.doc.write_text("%dF" % index)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-ChildName',3)
|
||||
self.doc.start_paragraph('FGR-ChildText')
|
||||
self.doc.write_text(person.get_primary_name().get_regular_name())
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
families = len(person.get_family_handle_list())
|
||||
birth_handle = person.get_birth_handle()
|
||||
if birth_handle:
|
||||
@ -331,14 +367,55 @@ class FamilyGroup(Report.Report):
|
||||
death = self.database.get_event_from_handle(death_handle)
|
||||
else:
|
||||
death = None
|
||||
self.dump_child_event('FGR-TextChild1',_('Birth'),birth)
|
||||
if families == 0:
|
||||
self.dump_child_event('FGR-TextChild2',_('Death'),death)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild1',_('Death'),death)
|
||||
|
||||
index = 1
|
||||
|
||||
spouse_count = 0;
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
spouse_id = None
|
||||
if person_handle == family.get_father_handle():
|
||||
spouse_id = family.get_mother_handle()
|
||||
else:
|
||||
spouse_id = family.get_father_handle()
|
||||
if spouse_id:
|
||||
spouse_count = spouse_count + 1
|
||||
|
||||
self.doc.start_row()
|
||||
if spouse_count != 0 or self.missingInfo or death != None or birth != None:
|
||||
self.doc.start_cell('FGR-TextChild1')
|
||||
else:
|
||||
self.doc.start_cell('FGR-TextChild2')
|
||||
self.doc.start_paragraph('FGR-ChildText')
|
||||
if person.get_gender() == RelLib.Person.MALE:
|
||||
self.doc.write_text("%dM" % index)
|
||||
elif person.get_gender() == RelLib.Person.FEMALE:
|
||||
self.doc.write_text("%dF" % index)
|
||||
else:
|
||||
self.doc.write_text("%dU" % index)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-ChildName',3)
|
||||
self.doc.start_paragraph('FGR-ChildText')
|
||||
self.doc.write_text(person.get_primary_name().get_regular_name())
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
if self.missingInfo or birth != None:
|
||||
if spouse_count != 0 or self.missingInfo or death != None:
|
||||
self.dump_child_event('FGR-TextChild1',_('Birth'),birth)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild2',_('Birth'),birth)
|
||||
|
||||
|
||||
if self.missingInfo or death != None:
|
||||
if spouse_count == 0:
|
||||
self.dump_child_event('FGR-TextChild2',_('Death'),death)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild1',_('Death'),death)
|
||||
|
||||
index = 0
|
||||
for family_handle in person.get_family_handle_list():
|
||||
index = index + 1
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
for event_handle in family.get_event_list():
|
||||
if event_handle:
|
||||
@ -349,63 +426,98 @@ class FamilyGroup(Report.Report):
|
||||
else:
|
||||
m = None
|
||||
|
||||
spouse_id = None
|
||||
if person_handle == family.get_father_handle():
|
||||
spouse_id = family.get_mother_handle()
|
||||
else:
|
||||
spouse_id = family.get_father_handle()
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-TextChild1')
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-TextContents')
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Spouse"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-TextContentsEnd',2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
|
||||
if spouse_id:
|
||||
spouse = self.database.get_person_from_handle(spouse_id)
|
||||
self.doc.write_text(spouse.get_primary_name().get_regular_name())
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
|
||||
if index == families:
|
||||
self.dump_child_event('FGR-TextChild2',_("Married"),m)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild1',_("Married"),m)
|
||||
|
||||
|
||||
def write_report(self):
|
||||
self.doc.start_paragraph('FGR-Title')
|
||||
self.doc.write_text(_("Family Group Report"))
|
||||
self.doc.end_paragraph()
|
||||
|
||||
if self.family:
|
||||
self.dump_parent(self.family.get_father_handle())
|
||||
self.doc.start_paragraph("FGR-blank")
|
||||
self.doc.end_paragraph()
|
||||
self.dump_parent(self.family.get_mother_handle())
|
||||
|
||||
length = len(self.family.get_child_handle_list())
|
||||
if length > 0:
|
||||
self.doc.start_paragraph("FGR-blank")
|
||||
self.doc.end_paragraph()
|
||||
self.doc.start_table('FGR-Children','FGR-ChildTable')
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-ParentHead',4)
|
||||
self.doc.start_paragraph('FGR-ParentName')
|
||||
self.doc.write_text(_("Children"))
|
||||
self.doc.start_cell('FGR-TextChild1')
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-TextContents')
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
self.doc.write_text(_("Spouse"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.start_cell('FGR-TextContentsEnd',2)
|
||||
self.doc.start_paragraph('FGR-Normal')
|
||||
if spouse_id:
|
||||
spouse = self.database.get_person_from_handle(spouse_id)
|
||||
spouse_name = spouse.get_primary_name().get_regular_name()
|
||||
if self.incRelDates:
|
||||
birth_handle = spouse.get_birth_handle()
|
||||
birth = " "
|
||||
if birth_handle:
|
||||
birth = self.database.get_event_from_handle(birth_handle).get_date()
|
||||
death_handle = spouse.get_death_handle()
|
||||
death = " "
|
||||
if death_handle:
|
||||
death = self.database.get_event_from_handle(death_handle).get_date()
|
||||
if birth_handle or death_handle:
|
||||
spouse_name = "%s (%s - %s)" % (spouse_name,birth,death)
|
||||
self.doc.write_text(spouse_name)
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
index = 1
|
||||
for child_handle in self.family.get_child_handle_list():
|
||||
self.dump_child(index,child_handle)
|
||||
index = index + 1
|
||||
self.doc.end_table()
|
||||
|
||||
if m:
|
||||
if index == families:
|
||||
self.dump_child_event('FGR-TextChild2',_("Married"),m)
|
||||
else:
|
||||
self.dump_child_event('FGR-TextChild1',_("Married"),m)
|
||||
|
||||
def dump_family(self,family_handle,generation):
|
||||
self.doc.start_paragraph('FGR-Title')
|
||||
if self.recursive and self.generations:
|
||||
self.doc.write_text(_("Family Group Report - Generation %d") % generation)
|
||||
else:
|
||||
self.doc.write_text(_("Family Group Report") )
|
||||
self.doc.end_paragraph()
|
||||
|
||||
family = self.database.get_family_from_handle(family_handle)
|
||||
|
||||
self.dump_parent(family.get_father_handle())
|
||||
self.doc.start_paragraph("FGR-blank")
|
||||
self.doc.end_paragraph()
|
||||
self.dump_parent(family.get_mother_handle())
|
||||
|
||||
length = len(family.get_child_handle_list())
|
||||
if length > 0:
|
||||
self.doc.start_paragraph("FGR-blank")
|
||||
self.doc.end_paragraph()
|
||||
self.doc.start_table('FGR-Children','FGR-ChildTable')
|
||||
self.doc.start_row()
|
||||
self.doc.start_cell('FGR-ParentHead',4)
|
||||
self.doc.start_paragraph('FGR-ParentName')
|
||||
self.doc.write_text(_("Children"))
|
||||
self.doc.end_paragraph()
|
||||
self.doc.end_cell()
|
||||
self.doc.end_row()
|
||||
index = 1
|
||||
for child_handle in family.get_child_handle_list():
|
||||
self.dump_child(index,child_handle)
|
||||
index = index + 1
|
||||
self.doc.end_table()
|
||||
|
||||
if self.recursive:
|
||||
for child_handle in family.get_child_handle_list():
|
||||
child = self.database.get_person_from_handle(child_handle)
|
||||
for child_family_handle in child.get_family_handle_list():
|
||||
if child_family_handle != family_handle:
|
||||
self.doc.page_break()
|
||||
self.dump_family(child_family_handle,(generation+1))
|
||||
|
||||
def write_report(self):
|
||||
if self.family_handle:
|
||||
self.dump_family(self.family_handle,1)
|
||||
else:
|
||||
self.doc.start_paragraph('FGR-Title')
|
||||
self.doc.write_text(_("Family Group Report"))
|
||||
self.doc.end_paragraph()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@ -425,6 +537,14 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
|
||||
# Options specific for this report
|
||||
self.options_dict = {
|
||||
'spouse_id' : '',
|
||||
'recursive' : 0,
|
||||
'missinginfo' : 1,
|
||||
'generations' : 1,
|
||||
'incParEvents' : 0,
|
||||
'incParAddr' : 0,
|
||||
'incParNotes' : 0,
|
||||
'incParNames' : 0,
|
||||
'incRelDates' : 0,
|
||||
}
|
||||
|
||||
self.options_help = {
|
||||
@ -433,6 +553,37 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
|
||||
#[item[0] for item in self.get_spouses(None,None)],
|
||||
#False
|
||||
),
|
||||
'recursive' : ("=0/1","Create reports for all decendants of this family.",
|
||||
["Do not create reports for decendants","Create reports for decendants"],
|
||||
False),
|
||||
|
||||
'missinginfo' : ("=0/1","Whether to include fields for missing information.",
|
||||
["Do not include missing info","Include missing info"],
|
||||
True),
|
||||
|
||||
'generations' : ("=0/1","Whether to include the generation on each report (recursive only).",
|
||||
["Do not include the generation","Include the generation"],
|
||||
True),
|
||||
|
||||
'incParEvents' : ("=0/1","Whether to include events for parents.",
|
||||
["Do not include parental events","Include parental events"],
|
||||
True),
|
||||
|
||||
'incParAddr' : ("=0/1","Whether to include addresses for parents.",
|
||||
["Do not include parental addresses","Include parental addresses"],
|
||||
True),
|
||||
|
||||
'incParNotes' : ("=0/1","Whether to include notes for parents.",
|
||||
["Do not include parental notes","Include parental notes"],
|
||||
True),
|
||||
|
||||
'incParNames' : ("=0/1","Whether to include alternate names for parents.",
|
||||
["Do not include parental names","Include parental names"],
|
||||
True),
|
||||
|
||||
'incRelDates' : ("=0/1","Whether to include dates for relatives.",
|
||||
["Do not include dates of relatives","Include dates of relatives"],
|
||||
True),
|
||||
}
|
||||
|
||||
def get_spouses(self,database,person):
|
||||
@ -477,8 +628,48 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
|
||||
spouse_index = index
|
||||
index = index + 1
|
||||
self.spouse_menu.set_active(spouse_index)
|
||||
|
||||
# Recursive
|
||||
self.recursive_option = gtk.CheckButton()
|
||||
self.recursive_option.set_active(self.options_dict['recursive'])
|
||||
|
||||
# Missing Info
|
||||
self.missing_info_option = gtk.CheckButton(_("Print fields for missing information"))
|
||||
self.missing_info_option.set_active(self.options_dict['missinginfo'])
|
||||
|
||||
# Generations
|
||||
self.include_generations_option = gtk.CheckButton(_("Generation numbers (recursive only)"))
|
||||
self.include_generations_option.set_active(self.options_dict['generations'])
|
||||
|
||||
# Parental Events
|
||||
self.include_par_events_option = gtk.CheckButton(_("Parent Events"))
|
||||
self.include_par_events_option.set_active(self.options_dict['incParEvents'])
|
||||
|
||||
# Parental Addresses
|
||||
self.include_par_addr_option = gtk.CheckButton(_("Parent Addresses"))
|
||||
self.include_par_addr_option.set_active(self.options_dict['incParAddr'])
|
||||
|
||||
# Parental Notes
|
||||
self.include_par_notes_option = gtk.CheckButton(_("Parent Notes"))
|
||||
self.include_par_notes_option.set_active(self.options_dict['incParNotes'])
|
||||
|
||||
# Parental Names
|
||||
self.include_par_names_option = gtk.CheckButton(_("Alternate Parent Names"))
|
||||
self.include_par_names_option.set_active(self.options_dict['incParNames'])
|
||||
|
||||
# Relatives Dates
|
||||
self.include_rel_dates_option = gtk.CheckButton(_("Dates of Relatives (father, mother, spouse)"))
|
||||
self.include_rel_dates_option.set_active(self.options_dict['incRelDates'])
|
||||
|
||||
dialog.add_option(_("Spouse"),self.spouse_menu)
|
||||
dialog.add_option(_("Recursive"),self.recursive_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_generations_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_par_events_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_par_addr_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_par_notes_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_par_names_option)
|
||||
dialog.add_frame_option(_('Include'),'',self.include_rel_dates_option)
|
||||
dialog.add_frame_option(_('Missing Information'),'',self.missing_info_option)
|
||||
|
||||
def parse_user_options(self,dialog):
|
||||
"""
|
||||
@ -488,6 +679,15 @@ class FamilyGroupOptions(ReportOptions.ReportOptions):
|
||||
spouse_index = self.spouse_menu.get_active()
|
||||
if spouses:
|
||||
self.options_dict['spouse_id'] = spouses[spouse_index][0]
|
||||
|
||||
self.options_dict['recursive'] = int(self.recursive_option.get_active())
|
||||
self.options_dict['missinginfo'] = int(self.missing_info_option.get_active())
|
||||
self.options_dict['generations'] = int(self.include_generations_option.get_active())
|
||||
self.options_dict['incParEvents'] = int(self.include_par_events_option.get_active())
|
||||
self.options_dict['incParAddr'] = int(self.include_par_addr_option.get_active())
|
||||
self.options_dict['incParNotes'] = int(self.include_par_notes_option.get_active())
|
||||
self.options_dict['incParNames'] = int(self.include_par_names_option.get_active())
|
||||
self.options_dict['incRelDates'] = int(self.include_rel_dates_option.get_active())
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
"""Make default output style for the Family Group Report."""
|
||||
|
@ -307,7 +307,8 @@ class GraphViz:
|
||||
label = label + '\\n(%s - %s)' % (birth, death)
|
||||
self.f.write('p%s [shape=box, ' % the_id)
|
||||
if self.includeurl:
|
||||
self.f.write('URL="%s.html", ' % the_id)
|
||||
h = person.get_handle()
|
||||
self.f.write('URL="ppl/%s/%s/%s.html", ' % (h[0],h[1],h))
|
||||
if self.colorize != 'outline':
|
||||
if self.colorize == 'filled':
|
||||
style = 'style=filled, fillcolor'
|
||||
|
@ -112,7 +112,10 @@ class GeneWebParser:
|
||||
self.lineno += 1
|
||||
line = self.f.readline()
|
||||
if line:
|
||||
line = unicode( line.strip())
|
||||
try:
|
||||
line = unicode(line.strip())
|
||||
except UnicodeDecodeError:
|
||||
line = unicode(line.strip(),'iso-8859-1')
|
||||
else:
|
||||
line = None
|
||||
return line
|
||||
@ -258,8 +261,6 @@ class GeneWebParser:
|
||||
else:
|
||||
(idx,child) = self.parse_person(fields,1,RelLib.Person.UNKNOWN,father_surname)
|
||||
|
||||
print child.get_gender(),":",fields[1], child.get_primary_name().get_name()
|
||||
|
||||
if child:
|
||||
self.current_family.add_child_handle(child.get_handle())
|
||||
self.db.commit_family(self.current_family,self.trans)
|
||||
@ -302,7 +303,7 @@ class GeneWebParser:
|
||||
def read_notes_lines(self,line,fields):
|
||||
(idx,person) = self.parse_person(fields,1,None,None)
|
||||
note_txt = ""
|
||||
while 1:
|
||||
while True:
|
||||
line = self.get_next_line()
|
||||
if line == None:
|
||||
break
|
||||
@ -402,16 +403,18 @@ class GeneWebParser:
|
||||
if not father_surname:
|
||||
if not idx < len(fields):
|
||||
print "Missing surname of person in line %d!" % self.lineno
|
||||
return (idx,None)
|
||||
surname = self.decode(fields[idx])
|
||||
surname =""
|
||||
else:
|
||||
surname = self.decode(fields[idx])
|
||||
idx = idx + 1
|
||||
else:
|
||||
surname = father_surname
|
||||
|
||||
if not idx < len(fields):
|
||||
print "Missing firstname of person in line %d!" % self.lineno
|
||||
return (idx,None)
|
||||
firstname = self.decode(fields[idx])
|
||||
firstname = ""
|
||||
else:
|
||||
firstname = self.decode(fields[idx])
|
||||
idx = idx + 1
|
||||
if idx < len(fields) and father_surname:
|
||||
noSurnameRe = re.compile("^[({\[~><?0-9#].*$")
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2003-2005 Donald N. Allingham
|
||||
# Copyright (C) 2003-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -31,6 +31,7 @@ Show uncollected objects in a window.
|
||||
#------------------------------------------------------------------------
|
||||
import os
|
||||
from gettext import gettext as _
|
||||
from bsddb.db import DBError
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@ -114,10 +115,15 @@ class Leak(Tool.Tool):
|
||||
mylist = []
|
||||
if len(gc.garbage):
|
||||
for each in gc.garbage:
|
||||
mylist.append(str(each))
|
||||
self.ebuf.set_text(_("Uncollected objects:\n\n") + '\n\n'.join(mylist))
|
||||
try:
|
||||
mylist.append(str(each))
|
||||
except DBError:
|
||||
mylist.append('db.DB instance at %s' % id(each))
|
||||
self.ebuf.set_text(_("Uncollected objects:\n\n")
|
||||
+ '\n\n'.join(mylist))
|
||||
else:
|
||||
self.ebuf.set_text(_("No uncollected objects\n") + str(gc.get_debug()))
|
||||
self.ebuf.set_text(_("No uncollected objects\n")
|
||||
+ str(gc.get_debug()))
|
||||
|
||||
def apply_clicked(self,obj):
|
||||
self.display()
|
||||
|
@ -112,12 +112,12 @@ _character_sets = [
|
||||
]
|
||||
|
||||
_cc = [
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nd/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-sa/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/"><img alt="Creative Commons License" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by/2.5/"><img alt="Creative Commons License - By attribution" title="Creative Commons License - By attribution" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nd/2.5/"><img alt="Creative Commons License - By attribution, No derivations" title="Creative Commons License - By attribution, No derivations" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-sa/2.5/"><img alt="Creative Commons License - By attribution, Share-alike" title="Creative Commons License - By attribution, Share-alike" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc/2.5/"><img alt="Creative Commons License - By attribution, Non-commercial" title="Creative Commons License - By attribution, Non-commercial" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.5/"><img alt="Creative Commons License - By attribution, Non-commercial, No derivations" title="Creative Commons License - By attribution, Non-commercial, No derivations" src="#PATH#images/somerights20.gif" /></a>',
|
||||
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/"><img alt="Creative Commons License - By attribution, Non-commerical, Share-alike" title="Creative Commons License - By attribution, Non-commerical, Share-alike" src="#PATH#images/somerights20.gif" /></a>',
|
||||
]
|
||||
|
||||
|
||||
@ -1665,6 +1665,14 @@ class IndividualPage(BasePage):
|
||||
|
||||
of.write('</td>\n</tr>\n')
|
||||
|
||||
# Gender
|
||||
|
||||
nick = self.person.get_nick_name()
|
||||
if nick:
|
||||
of.write('<tr><td class="field">%s</td>\n' % _('Nickname'))
|
||||
of.write('<td class="data">%s</td>\n' % nick)
|
||||
of.write('</tr>\n')
|
||||
|
||||
# Gender
|
||||
of.write('<tr><td class="field">%s</td>\n' % _('Gender'))
|
||||
gender = self.gender_map[self.person.gender]
|
||||
@ -2100,7 +2108,7 @@ class WebReport(Report.Report):
|
||||
|
||||
# Copy the Creative Commons icon if the a Creative Commons
|
||||
# license is requested
|
||||
if 1 < self.copyright < 7:
|
||||
if 0 < self.copyright < 7:
|
||||
from_path = os.path.join(const.dataDir,"somerights20.gif")
|
||||
to_path = os.path.join("images","somerights20.gif")
|
||||
self.store_file(archive,self.target_path,from_path,to_path)
|
||||
@ -2837,7 +2845,7 @@ def nameof(person,private):
|
||||
if person.private and private:
|
||||
return _("Private")
|
||||
else:
|
||||
return _nd.display(person)
|
||||
return _nd.display_with_nick(person)
|
||||
|
||||
def name_nameof(name,private):
|
||||
if name.private and private:
|
||||
|
@ -66,8 +66,10 @@ prefix_list = [
|
||||
|
||||
_title_re = re.compile(r"^([A-Za-z][A-Za-z]+\.)\s+(.*)$")
|
||||
_nick_re = re.compile(r"(.+)\s*[(\"](.*)[)\"]")
|
||||
_fn_prefix_re = re.compile("(.*)\s+(%s)\s*$" % '|'.join(prefix_list),re.IGNORECASE)
|
||||
_sn_prefix_re = re.compile("^\s*(%s)\s+(.*)" % '|'.join(prefix_list),re.IGNORECASE)
|
||||
_fn_prefix_re = re.compile("(.*)\s+(%s)\s*$" % '|'.join(prefix_list),
|
||||
re.IGNORECASE)
|
||||
_sn_prefix_re = re.compile("^\s*(%s)\s+(.*)" % '|'.join(prefix_list),
|
||||
re.IGNORECASE)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -111,19 +113,22 @@ class PatchNames(Tool.Tool):
|
||||
first = name.get_first_name()
|
||||
sname = name.get_surname()
|
||||
|
||||
match = _title_re.match(first)
|
||||
if name.get_title():
|
||||
current_title = [name.get_title()]
|
||||
old_title = [name.get_title()]
|
||||
else:
|
||||
current_title = []
|
||||
old_title = []
|
||||
new_title = []
|
||||
|
||||
match = _title_re.match(first)
|
||||
while match:
|
||||
groups = match.groups()
|
||||
first = groups[1]
|
||||
current_title.append(groups[0])
|
||||
new_title.append(groups[0])
|
||||
match = _title_re.match(first)
|
||||
|
||||
if current_title:
|
||||
self.title_list.append((key," ".join(current_title),first))
|
||||
if new_title:
|
||||
self.title_list.append((key," ".join(old_title+new_title),
|
||||
first))
|
||||
continue
|
||||
|
||||
match = _nick_re.match(first)
|
||||
@ -131,15 +136,24 @@ class PatchNames(Tool.Tool):
|
||||
groups = match.groups()
|
||||
self.nick_list.append((key,groups[0],groups[1]))
|
||||
continue
|
||||
|
||||
old_prefix = name.get_surname_prefix()
|
||||
|
||||
match = _fn_prefix_re.match(first)
|
||||
if match:
|
||||
groups = match.groups()
|
||||
self.prefix1_list.append((key,groups[0],groups[1]))
|
||||
self.prefix1_list.append((key,groups[0],
|
||||
" ".join([groups[1],old_prefix]))
|
||||
)
|
||||
continue
|
||||
|
||||
match = _sn_prefix_re.match(sname)
|
||||
if match:
|
||||
groups = match.groups()
|
||||
self.prefix2_list.append((key,groups[1],groups[0]))
|
||||
self.prefix2_list.append((key,groups[1],
|
||||
" ".join([old_prefix,groups[0]]))
|
||||
)
|
||||
|
||||
self.progress.step()
|
||||
|
||||
if self.nick_list or self.title_list or self.prefix1_list or self.prefix2_list:
|
||||
@ -217,38 +231,38 @@ class PatchNames(Tool.Tool):
|
||||
self.nick_hash[id] = handle
|
||||
self.progress.step()
|
||||
|
||||
for (id,title,nick) in self.title_list:
|
||||
for (id,title,name) in self.title_list:
|
||||
p = self.db.get_person_from_handle(id)
|
||||
gid = p.get_gramps_id()
|
||||
handle = self.model.append()
|
||||
self.model.set_value(handle,0,1)
|
||||
self.model.set_value(handle,1,gid)
|
||||
self.model.set_value(handle,2,_('Title'))
|
||||
self.model.set_value(handle,3,nick)
|
||||
self.model.set_value(handle,3,title)
|
||||
self.model.set_value(handle,4,p.get_primary_name().get_name())
|
||||
self.title_hash[id] = handle
|
||||
self.progress.step()
|
||||
|
||||
for (id,prefix,fname) in self.prefix1_list:
|
||||
for (id,fname,prefix) in self.prefix1_list:
|
||||
p = self.db.get_person_from_handle(id)
|
||||
gid = p.get_gramps_id()
|
||||
handle = self.model.append()
|
||||
self.model.set_value(handle,0,1)
|
||||
self.model.set_value(handle,1,gid)
|
||||
self.model.set_value(handle,2,_('Prefix'))
|
||||
self.model.set_value(handle,3,fname)
|
||||
self.model.set_value(handle,3,prefix)
|
||||
self.model.set_value(handle,4,p.get_primary_name().get_name())
|
||||
self.prefix1_hash[id] = handle
|
||||
self.progress.step()
|
||||
|
||||
for (id,prefix,fname) in self.prefix2_list:
|
||||
for (id,sname,prefix) in self.prefix2_list:
|
||||
p = self.db.get_person_from_handle(id)
|
||||
gid = p.get_gramps_id()
|
||||
handle = self.model.append()
|
||||
self.model.set_value(handle,0,1)
|
||||
self.model.set_value(handle,1,gid)
|
||||
self.model.set_value(handle,2,_('Prefix'))
|
||||
self.model.set_value(handle,3,fname)
|
||||
self.model.set_value(handle,3,prefix)
|
||||
self.model.set_value(handle,4,p.get_primary_name().get_name())
|
||||
self.prefix2_hash[id] = handle
|
||||
self.progress.step()
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -55,44 +55,51 @@ import TarFile
|
||||
#-------------------------------------------------------------------------
|
||||
def impData(database, name,cb=None,cl=0):
|
||||
# Create tempdir, if it does not exist, then check for writability
|
||||
tmpdir_path = os.path.expanduser("~/.gramps/tmp" )
|
||||
# THE TEMP DIR is named as the filname.gpkg.media and is created
|
||||
# in the same dir as the database that we are importing into.
|
||||
db_path = os.path.dirname(database.get_save_path())
|
||||
media_dir = "%s.media" % os.path.basename(name)
|
||||
tmpdir_path = os.path.join(db_path,media_dir)
|
||||
if not os.path.isdir(tmpdir_path):
|
||||
try:
|
||||
os.mkdir(tmpdir_path,0700)
|
||||
except:
|
||||
ErrorDialog( _("Could not create temporary directory %s") %
|
||||
tmpdir_path )
|
||||
tmpdir_path )
|
||||
return
|
||||
elif not os.access(tmpdir_path,os.W_OK):
|
||||
ErrorDialog( _("Temporary directory %s is not writable") % tmpdir_path )
|
||||
ErrorDialog(_("Temporary directory %s is not writable") % tmpdir_path)
|
||||
return
|
||||
else: # tempdir exists and writable -- clean it up if not empty
|
||||
files = os.listdir(tmpdir_path) ;
|
||||
for filename in files:
|
||||
os.remove( os.path.join(tmpdir_path,filename) )
|
||||
os.remove(os.path.join(tmpdir_path,filename))
|
||||
|
||||
try:
|
||||
t = TarFile.ReadTarFile(name,tmpdir_path)
|
||||
t.extract()
|
||||
t.close()
|
||||
except:
|
||||
ErrorDialog(_("Error extracting into %s") % tmpdir_path )
|
||||
ErrorDialog(_("Error extracting into %s") % tmpdir_path)
|
||||
return
|
||||
|
||||
dbname = os.path.join(tmpdir_path,const.xmlFile)
|
||||
imp_db_name = os.path.join(tmpdir_path,const.xmlFile)
|
||||
|
||||
try:
|
||||
ReadXML.importData(database,dbname,cb)
|
||||
ReadXML.importData(database,imp_db_name,cb)
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
|
||||
# Clean up tempdir after ourselves
|
||||
files = os.listdir(tmpdir_path)
|
||||
for filename in files:
|
||||
os.remove(os.path.join(tmpdir_path,filename))
|
||||
# THIS HAS BEEN CHANGED, because now we want to keep images
|
||||
# stay after the import is over. Just delete the XML file.
|
||||
os.remove(imp_db_name)
|
||||
|
||||
os.rmdir(tmpdir_path)
|
||||
## files = os.listdir(tmpdir_path)
|
||||
## for filename in files:
|
||||
## os.remove(os.path.join(tmpdir_path,filename))
|
||||
## os.rmdir(tmpdir_path)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2005 Donald N. Allingham
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -65,16 +65,13 @@ class Rebuild(Tool.Tool):
|
||||
# checking of a read only database
|
||||
return
|
||||
|
||||
total = db.get_number_of_people() + \
|
||||
db.get_number_of_families() + \
|
||||
db.get_number_of_places() + \
|
||||
db.get_number_of_sources() + \
|
||||
db.get_number_of_media_objects()
|
||||
|
||||
db.disable_signals()
|
||||
if parent:
|
||||
progress = Utils.ProgressMeter(
|
||||
_('Rebuilding Secondary Indices'))
|
||||
# Six indices to rebuild, and the first step is removing
|
||||
# old ones
|
||||
total = 7
|
||||
progress.set_pass('',total)
|
||||
db.rebuild_secondary(progress.step)
|
||||
progress.close()
|
||||
|
119
src/plugins/holidays.xml
Normal file
119
src/plugins/holidays.xml
Normal file
@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<calendar>
|
||||
<country name="US">
|
||||
<date name="New Year's Day" value="*/1/1" type="national" />
|
||||
<date name="Independence Day" value="*/7/4" type="national" />
|
||||
<date name="Veterans Day" value="*/11/11" type="national" />
|
||||
<date name="Christmas" value="*/12/25" type="national" />
|
||||
<date name="Labor Day" value="*/1/mon/sep" type="national" />
|
||||
<date name="Thanksgiving" value="*/4/thu/nov" type="national" />
|
||||
<date name="Inauguration Day" value="*/1/20" if="(y - 1980) % 4 == 0" type="national" />
|
||||
<date name="Groundhog Day" value="*/2/2" type="secular" />
|
||||
<date name="Lincoln's Birthday" value="*/2/12" type="secular" />
|
||||
<date name="Valentine's Day" value="*/2/14" type="secular" />
|
||||
<date name="Presidents' Day" value="*/3/mon/feb" type="secular" />
|
||||
<date name="Washington's Birthday" value="*/2/22" type="secular" />
|
||||
<date name="St. Patrick's Day" value="*/3/17" type="secular" />
|
||||
<date name="April Fools's Day" value="*/4/1" type="secular" />
|
||||
<date name="Earth Day" value="*/4/22" type="secular" />
|
||||
<date name="Assistants' Day" value="*/-1/sat/apr" offset="-3" type="secular" />
|
||||
<date name="Arbor Day" value="*/-1/fri/apr" type="secular" />
|
||||
<date name="Mothers' Day" value="*/2/sun/may" type="secular" />
|
||||
<date name="Fathers' Day" value="*/3/sun/jun" type="secular" />
|
||||
<date name="Parents' Day" value="*/4/sun/jul" type="secular" />
|
||||
<date name="Grandparents' Day" value="*/1/mon/sep" offset="6" type="secular" />
|
||||
<date name="Columbus Day" value="*/2/mon/oct" type="secular" />
|
||||
<date name="United Nations Day" value="*/10/24" type="secular" />
|
||||
<date name="Halloween" value="*/10/31" type="secular" />
|
||||
<date name="ML Kings's Birthday" value="*/3/mon/jan" type="secular" />
|
||||
<date name="Armed Forces Day" value="*/3/sat/may" type="secular" />
|
||||
<date name="Memorial Day" value="*/-1/mon/may" type="secular" />
|
||||
<date name="Flag Day" value="*/6/14" type="secular" />
|
||||
<date name="Election Day" value="*/11/2" offset="tue" type="secular" />
|
||||
<date name="Daylight Savings begins" value="*/1/sun/apr" type="informational" />
|
||||
<date name="Income Taxes due" value="*/4/15" type="national"
|
||||
if="date.weekday().__cmp__(4)-1" />
|
||||
<date name="Income Taxes due" value="*/4/16" type="national"
|
||||
if="date.weekday() == 0" />
|
||||
<date name="Income Taxes due" value="*/4/17" type="national"
|
||||
if="date.weekday() == 0" />
|
||||
<date name="Daylight Savings ends" value="*/-1/sun/oct" type="informational" />
|
||||
<date name="Easter" type="religious" value="1980/4/6" />
|
||||
<date name="Easter" type="religious" value="1981/4/19" />
|
||||
<date name="Easter" type="religious" value="1982/4/11" />
|
||||
<date name="Easter" type="religious" value="1983/4/3" />
|
||||
<date name="Easter" type="religious" value="1984/4/22" />
|
||||
<date name="Easter" type="religious" value="1985/4/7" />
|
||||
<date name="Easter" type="religious" value="1986/3/30" />
|
||||
<date name="Easter" type="religious" value="1987/4/19" />
|
||||
<date name="Easter" type="religious" value="1988/4/3" />
|
||||
<date name="Easter" type="religious" value="1989/3/26" />
|
||||
<date name="Easter" type="religious" value="1990/4/15" />
|
||||
<date name="Easter" type="religious" value="1991/3/31" />
|
||||
<date name="Easter" type="religious" value="1992/4/19" />
|
||||
<date name="Easter" type="religious" value="1993/4/11" />
|
||||
<date name="Easter" type="religious" value="1994/4/3" />
|
||||
<date name="Easter" type="religious" value="1995/4/16" />
|
||||
<date name="Easter" type="religious" value="1996/4/7" />
|
||||
<date name="Easter" type="religious" value="1997/3/30" />
|
||||
<date name="Easter" type="religious" value="1998/4/12" />
|
||||
<date name="Easter" type="religious" value="1999/4/4" />
|
||||
<date name="Easter" type="religious" value="2000/4/23" />
|
||||
<date name="Easter" type="religious" value="2001/4/15" />
|
||||
<date name="Easter" type="religious" value="2002/3/31" />
|
||||
<date name="Easter" type="religious" value="2003/4/20" />
|
||||
<date name="Easter" type="religious" value="2004/4/11" />
|
||||
<date name="Easter" type="religious" value="2005/3/27" />
|
||||
<date name="Easter" type="religious" value="2006/4/16" />
|
||||
<date name="Easter" type="religious" value="2007/4/8" />
|
||||
<date name="Easter" type="religious" value="2008/3/23" />
|
||||
<date name="Easter" type="religious" value="2009/4/12" />
|
||||
<date name="Easter" type="religious" value="2010/4/4" />
|
||||
<date name="Easter" type="religious" value="2011/4/24" />
|
||||
<date name="Easter" type="religious" value="2012/4/8" />
|
||||
<date name="Easter" type="religious" value="2013/3/31" />
|
||||
<date name="Easter" type="religious" value="2014/4/20" />
|
||||
<date name="Easter" type="religious" value="2015/4/5" />
|
||||
<date name="Easter" type="religious" value="2016/3/27" />
|
||||
<date name="Easter" type="religious" value="2017/4/16" />
|
||||
<date name="Easter" type="religious" value="2018/4/1" />
|
||||
<date name="Easter" type="religious" value="2019/4/21" />
|
||||
<date name="Easter" type="religious" value="2020/4/12" />
|
||||
<date name="Easter" type="religious" value="2021/4/4" />
|
||||
<date name="Easter" type="religious" value="2022/4/17" />
|
||||
<date name="Easter" type="religious" value="2023/4/9" />
|
||||
<date name="Easter" type="religious" value="2024/3/31" />
|
||||
<date name="Passover" value="2005/4/24" type="religious" />
|
||||
<date name="Passover" value="2006/4/13" type="religious" />
|
||||
<date name="Passover" value="2007/4/03" type="religious" />
|
||||
<date name="Passover" value="2008/4/20" type="religious" />
|
||||
<date name="Passover" value="2009/4/09" type="religious" />
|
||||
<date name="Passover" value="2010/3/30" type="religious" />
|
||||
<date name="Passover" value="2011/4/19" type="religious" />
|
||||
<date name="Yom Kippur" value="2005/10/13" type="religious" />
|
||||
<date name="Yom Kippur" value="2006/10/02" type="religious" />
|
||||
<date name="Yom Kippur" value="2007/9/27" type="religious" />
|
||||
<date name="Yom Kippur" value="2008/10/09" type="religious" />
|
||||
<date name="Yom Kippur" value="2009/9/28" type="religious" />
|
||||
<date name="Yom Kippur" value="2010/9/18" type="religious" />
|
||||
<date name="Hanukkah begins" value="2004/10/07" type="religious" />
|
||||
<date name="Hanukkah begins" value="2005/10/26" type="religious" />
|
||||
<date name="Hanukkah begins" value="2006/10/15" type="religious" />
|
||||
<date name="Hanukkah begins" value="2007/10/05" type="religious" />
|
||||
<date name="Hanukkah begins" value="2008/10/22" type="religious" />
|
||||
<date name="Hanukkah begins" value="2009/10/12" type="religious" />
|
||||
<date name="Hanukkah begins" value="2010/10/22" type="religious" />
|
||||
<date name="Ramadan begins" value="2006/9/24" type="religious" />
|
||||
<date name="Ramadan begins" value="2007/9/13" type="religious" />
|
||||
<date name="Ramadan begins" value="2008/9/2" type="religious" />
|
||||
<date name="Kwanzaa begins" value="*/12/26" type="religious" />
|
||||
<date name="Cinco de Mayo" value="*/5/5" type="secular" />
|
||||
</country>
|
||||
<country name="CN">
|
||||
<date name="Chinese New Year" value="2006/1/29" type="national" />
|
||||
</country>
|
||||
<country name="FI">
|
||||
<date name="Chinese New Year" value="2006/1/29" type="national" />
|
||||
<date name="Card Night" value="*/-1/thu/*" type="personal" />
|
||||
</country>
|
||||
</calendar>
|
@ -20,7 +20,4 @@ uninstall-local:
|
||||
SUFFIXES = .po .mo
|
||||
|
||||
.po.mo:
|
||||
$(MSGCONV) --to-code=UTF-8 $< -o temp.po
|
||||
$(MSGFMT) temp.po -o $@
|
||||
rm temp.po
|
||||
|
||||
$(MSGCONV) --to-code=UTF-8 $< | $(MSGFMT) - -o $@
|
||||
|
2715
src/po/de.po
2715
src/po/de.po
File diff suppressed because it is too large
Load Diff
2983
src/po/fr.po
2983
src/po/fr.po
File diff suppressed because it is too large
Load Diff
11192
src/po/lt.po
11192
src/po/lt.po
File diff suppressed because it is too large
Load Diff
7368
src/po/nb.po
7368
src/po/nb.po
File diff suppressed because it is too large
Load Diff
10381
src/po/nl.po
10381
src/po/nl.po
File diff suppressed because it is too large
Load Diff
7368
src/po/no.po
7368
src/po/no.po
File diff suppressed because it is too large
Load Diff
3048
src/po/ru.po
3048
src/po/ru.po
File diff suppressed because it is too large
Load Diff
3940
src/po/sv.po
3940
src/po/sv.po
File diff suppressed because it is too large
Load Diff
2731
src/po/template.po
2731
src/po/template.po
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@ OPTS="-i $EXAMPLE_XML"
|
||||
GRPH_FMT="sxw ps pdf svg"
|
||||
TEXT_FMT="sxw pdf kwd abw rtf txt html tex"
|
||||
|
||||
GRPH_REP="ancestor_chart2 descend_chart2 fan_chart statistics_chart timeline"
|
||||
GRPH_REP="ancestor_chart2 descend_chart2 fan_chart statistics_chart timeline calendar"
|
||||
TEXT_REP="ancestor_report ancestors_report descend_report det_ancestor_report det_descendant_report family_group"
|
||||
|
||||
# Single run with all graphical reports in all formats
|
||||
|
Loading…
Reference in New Issue
Block a user