~rosco2/ubuntu/wily/gramps/bug-1492304

« back to all changes in this revision

Viewing changes to src/plugins/AncestorReport.py

  • Committer: Bazaar Package Importer
  • Author(s): James A. Treacy
  • Date: 2004-06-16 16:53:36 UTC
  • Revision ID: james.westby@ubuntu.com-20040616165336-kjzczqef4gnxrn2b
Tags: upstream-1.0.4
ImportĀ upstreamĀ versionĀ 1.0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Gramps - a GTK+/GNOME based genealogy program
 
3
#
 
4
# Copyright (C) 2000-2003  Donald N. Allingham
 
5
#
 
6
# This program is free software; you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation; either version 2 of the License, or
 
9
# (at your option) any later version.
 
10
#
 
11
# This program is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU General Public License
 
17
# along with this program; if not, write to the Free Software
 
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
#
 
20
 
 
21
"Text Reports/Ahnentafel Report"
 
22
 
 
23
#------------------------------------------------------------------------
 
24
#
 
25
# python modules
 
26
#
 
27
#------------------------------------------------------------------------
 
28
import os
 
29
import string
 
30
 
 
31
#------------------------------------------------------------------------
 
32
#
 
33
# gramps modules
 
34
#
 
35
#------------------------------------------------------------------------
 
36
import Report
 
37
import BaseDoc
 
38
import RelLib
 
39
import Errors
 
40
from QuestionDialog import ErrorDialog
 
41
from gettext import gettext as _
 
42
 
 
43
#------------------------------------------------------------------------
 
44
#
 
45
# AncestorReport
 
46
#
 
47
#------------------------------------------------------------------------
 
48
class AncestorReport(Report.Report):
 
49
 
 
50
    def __init__(self,database,person,max,pgbrk,doc,output,newpage=0):
 
51
        self.map = {}
 
52
        self.database = database
 
53
        self.start = person
 
54
        self.max_generations = max
 
55
        self.pgbrk = pgbrk
 
56
        self.doc = doc
 
57
        self.newpage = newpage
 
58
        if output:
 
59
            self.standalone = 1
 
60
            self.doc.open(output)
 
61
            self.doc.init()
 
62
        else:
 
63
            self.standalone = 0
 
64
        
 
65
    def filter(self,person,index,generation=1):
 
66
        if person == None or generation >= self.max_generations:
 
67
            return
 
68
        self.map[index] = person
 
69
    
 
70
        family = person.getMainParents()
 
71
        if family != None:
 
72
            self.filter(family.getFather(),index*2,generation+1)
 
73
            self.filter(family.getMother(),(index*2)+1,generation+1)
 
74
 
 
75
    def write_report(self):
 
76
 
 
77
        if self.newpage:
 
78
            self.doc.page_break()
 
79
 
 
80
        self.filter(self.start,1)
 
81
        
 
82
        name = self.start.getPrimaryName().getRegularName()
 
83
        self.doc.start_paragraph("AHN-Title")
 
84
        title = _("Ahnentafel Report for %s") % name
 
85
        self.doc.write_text(title)
 
86
        self.doc.end_paragraph()
 
87
    
 
88
        keys = self.map.keys()
 
89
        keys.sort()
 
90
        generation = 0
 
91
 
 
92
        for key in keys :
 
93
            if generation == 0 or key >= ( 1 << 30):
 
94
                if self.pgbrk and generation > 0:
 
95
                    self.doc.page_break()
 
96
                self.doc.start_paragraph("AHN-Generation")
 
97
                t = _("%s Generation") % AncestorReport.gen[generation+1]
 
98
                self.doc.write_text(t)
 
99
                self.doc.end_paragraph()
 
100
                generation = generation + 1
 
101
 
 
102
            self.doc.start_paragraph("AHN-Entry","%s." % str(key))
 
103
            person = self.map[key]
 
104
            name = person.getPrimaryName().getRegularName()
 
105
        
 
106
            self.doc.start_bold()
 
107
            self.doc.write_text(name)
 
108
            self.doc.end_bold()
 
109
            if name[-1:] == '.':
 
110
                self.doc.write_text(" ")
 
111
            else:
 
112
                self.doc.write_text(". ")
 
113
 
 
114
            # Check birth record
 
115
        
 
116
            birth = person.getBirth()
 
117
            if birth:
 
118
                date = birth.getDateObj().get_start_date()
 
119
                place = birth.getPlaceName()
 
120
                if place[-1:] == '.':
 
121
                    place = place[:-1]
 
122
                if date.getDate() != "" or place != "":
 
123
                    if date.getDate() != "":
 
124
                        if date.getDayValid() and date.getMonthValid():
 
125
                            if place != "":
 
126
                                t = _("%s was born on %s in %s. ") % \
 
127
                                    (name,date.getDate(),place)
 
128
                            else:
 
129
                                t = _("%s was born on %s. ") % \
 
130
                                    (name,date.getDate())
 
131
                        else:
 
132
                            if place != "":
 
133
                                t = _("%s was born in the year %s in %s. ") % \
 
134
                                    (name,date.getDate(),place)
 
135
                            else:
 
136
                                t = _("%s was born in the year %s. ") % \
 
137
                                    (name,date.getDate())
 
138
                        self.doc.write_text(t)
 
139
 
 
140
            death = person.getDeath()
 
141
            buried = None
 
142
            for event in person.getEventList():
 
143
                if string.lower(event.getName()) == "burial":
 
144
                    buried = event
 
145
        
 
146
            if death:
 
147
                date = death.getDateObj().get_start_date()
 
148
                place = death.getPlaceName()
 
149
                if place[-1:] == '.':
 
150
                    place = place[:-1]
 
151
                if date.getDate() != "" or place != "":
 
152
                    if person.getGender() == RelLib.Person.male:
 
153
                        male = 1
 
154
                    else:
 
155
                        male = 0
 
156
 
 
157
                    if date.getDate() != "":
 
158
                        if date.getDayValid() and date.getMonthValid():
 
159
                            if male:
 
160
                                if place != "":
 
161
                                    t = _("He died on %s in %s") % \
 
162
                                        (date.getDate(),place)
 
163
                                else:
 
164
                                    t = _("He died on %s") % date.getDate()
 
165
                            else:
 
166
                                if place != "":
 
167
                                    t = _("She died on %s in %s") % \
 
168
                                        (date.getDate(),place)
 
169
                                else:
 
170
                                    t = _("She died on %s") % date.getDate()
 
171
                        else:
 
172
                            if male:
 
173
                                if place != "":
 
174
                                    t = _("He died in the year %s in %s") % \
 
175
                                        (date.getDate(),place)
 
176
                                else:
 
177
                                    t = _("He died in the year %s") % date.getDate()
 
178
                            else:
 
179
                                if place != "":
 
180
                                    t = _("She died in the year %s in %s") % \
 
181
                                        (date.getDate(),place)
 
182
                                else:
 
183
                                    t = _("She died in the year %s") % date.getDate()
 
184
 
 
185
                        self.doc.write_text(t)
 
186
 
 
187
                    if buried:
 
188
                        date = buried.getDateObj().get_start_date()
 
189
                        place = buried.getPlaceName()
 
190
                        if place[-1:] == '.':
 
191
                            place = place[:-1]
 
192
                        if date.getDate() != "" or place != "":
 
193
                            if date.getDate() != "":
 
194
                                if date.getDayValid() and date.getMonthValid():
 
195
                                    if place != "":
 
196
                                        t = _(", and was buried on %s in %s.") % \
 
197
                                            (date.getDate(),place)
 
198
                                    else:
 
199
                                        t = _(", and was buried on %s.") % \
 
200
                                            date.getDate()
 
201
                                else:
 
202
                                    if place != "":
 
203
                                        t = _(", and was buried in the year %s in %s.") % \
 
204
                                            (date.getDate(),place)
 
205
                                    else:
 
206
                                        t = _(", and was buried in the year %s.") % \
 
207
                                            date.getDate()
 
208
                            else:
 
209
                                t = _(" and was buried in %s." % place)
 
210
                        self.doc.write_text(t)
 
211
                    else:
 
212
                        self.doc.write_text(".")
 
213
                        
 
214
            self.doc.end_paragraph()
 
215
        if self.standalone:
 
216
            self.doc.close()
 
217
 
 
218
 
 
219
#------------------------------------------------------------------------
 
220
#
 
221
 
222
#
 
223
#------------------------------------------------------------------------
 
224
class AncestorReportDialog(Report.TextReportDialog):
 
225
 
 
226
    report_options = {}
 
227
 
 
228
    def __init__(self,database,person):
 
229
        Report.TextReportDialog.__init__(self,database,person,self.report_options)
 
230
 
 
231
    #------------------------------------------------------------------------
 
232
    #
 
233
    # Customization hooks
 
234
    #
 
235
    #------------------------------------------------------------------------
 
236
    def get_title(self):
 
237
        """The window title for this dialog"""
 
238
        return "%s - %s - GRAMPS" % (_("Ahnentafel Report"),_("Text Reports"))
 
239
 
 
240
    def get_header(self, name):
 
241
        """The header line at the top of the dialog contents"""
 
242
        return _("Ahnentafel Report for %s") % name
 
243
 
 
244
    def get_target_browser_title(self):
 
245
        """The title of the window created when the 'browse' button is
 
246
        clicked in the 'Save As' frame."""
 
247
        return _("Save Ahnentafel Report")
 
248
 
 
249
    def get_stylesheet_savefile(self):
 
250
        """Where to save styles for this report."""
 
251
        return "ancestor_report.xml"
 
252
    
 
253
    def make_default_style(self):
 
254
        _make_default_style(self.default_style)
 
255
 
 
256
    def make_report(self):
 
257
        """Create the object that will produce the Ahnentafel Report.
 
258
        All user dialog has already been handled and the output file
 
259
        opened."""
 
260
        try:
 
261
            MyReport = AncestorReport(self.db, self.person,
 
262
                self.max_gen, self.pg_brk, self.doc, self.target_path)
 
263
            MyReport.write_report()
 
264
        except Errors.ReportError, msg:
 
265
            (m1,m2) = msg.messages()
 
266
            ErrorDialog(m1,m2)
 
267
        except Errors.FilterError, msg:
 
268
            (m1,m2) = msg.messages()
 
269
            ErrorDialog(m1,m2)
 
270
        except IOError, msg:
 
271
            ErrorDialog(_("Could not create %s" % self.target_path),msg)
 
272
        except:
 
273
            import DisplayTrace
 
274
            DisplayTrace.DisplayTrace()
 
275
 
 
276
#------------------------------------------------------------------------
 
277
#
 
278
# Standalone report function
 
279
#
 
280
#------------------------------------------------------------------------
 
281
def report(database,person):
 
282
    AncestorReportDialog(database,person)
 
283
 
 
284
 
 
285
#------------------------------------------------------------------------
 
286
#
 
287
# Set up sane defaults for the book_item
 
288
#
 
289
#------------------------------------------------------------------------
 
290
_style_file = "ancestor_report.xml"
 
291
_style_name = "default" 
 
292
 
 
293
_person_id = ""
 
294
_max_gen = 10
 
295
_pg_brk = 0
 
296
_options = ( _person_id, _max_gen, _pg_brk )
 
297
 
 
298
#------------------------------------------------------------------------
 
299
#
 
300
# Book Item Options dialog
 
301
#
 
302
#------------------------------------------------------------------------
 
303
class AncestorBareReportDialog(Report.BareReportDialog):
 
304
 
 
305
    def __init__(self,database,person,opt,stl):
 
306
 
 
307
        self.options = opt
 
308
        self.db = database
 
309
        if self.options[0]:
 
310
            self.person = self.db.getPerson(self.options[0])
 
311
        else:
 
312
            self.person = person
 
313
        self.style_name = stl
 
314
 
 
315
        Report.BareReportDialog.__init__(self,database,self.person)
 
316
 
 
317
        self.max_gen = int(self.options[1]) 
 
318
        self.pg_brk = int(self.options[2])
 
319
        self.new_person = None
 
320
 
 
321
        self.generations_spinbox.set_value(self.max_gen)
 
322
        self.pagebreak_checkbox.set_active(self.pg_brk)
 
323
        
 
324
        self.window.run()
 
325
 
 
326
    #------------------------------------------------------------------------
 
327
    #
 
328
    # Customization hooks
 
329
    #
 
330
    #------------------------------------------------------------------------
 
331
    def make_default_style(self):
 
332
        _make_default_style(self.default_style)
 
333
 
 
334
    def get_title(self):
 
335
        """The window title for this dialog"""
 
336
        return "%s - GRAMPS Book" % (_("Ahnentafel Report"))
 
337
 
 
338
    def get_header(self, name):
 
339
        """The header line at the top of the dialog contents"""
 
340
        return _("Ahnentafel Report for GRAMPS Book") 
 
341
 
 
342
    def get_stylesheet_savefile(self):
 
343
        """Where to save styles for this report."""
 
344
        return _style_file
 
345
    
 
346
    def on_cancel(self, obj):
 
347
        pass
 
348
 
 
349
    def on_ok_clicked(self, obj):
 
350
        """The user is satisfied with the dialog choices. Parse all options
 
351
        and close the window."""
 
352
 
 
353
        # Preparation
 
354
        self.parse_style_frame()
 
355
        self.parse_report_options_frame()
 
356
        
 
357
        if self.new_person:
 
358
            self.person = self.new_person
 
359
        self.options = ( self.person.getId(), self.max_gen, self.pg_brk )
 
360
        self.style_name = self.selected_style.get_name() 
 
361
 
 
362
#------------------------------------------------------------------------
 
363
#
 
364
# Function to write Book Item 
 
365
#
 
366
#------------------------------------------------------------------------
 
367
def write_book_item(database,person,doc,options,newpage=0):
 
368
    """Write the Ahnentafel Report using options set.
 
369
    All user dialog has already been handled and the output file opened."""
 
370
    try:
 
371
        if options[0]:
 
372
            person = database.getPerson(options[0])
 
373
        max_gen = int(options[1])
 
374
        pg_brk = int(options[2])
 
375
        return AncestorReport(database, person, max_gen, pg_brk, doc, None, newpage )
 
376
    except Errors.ReportError, msg:
 
377
        (m1,m2) = msg.messages()
 
378
        ErrorDialog(m1,m2)
 
379
    except Errors.FilterError, msg:
 
380
        (m1,m2) = msg.messages()
 
381
        ErrorDialog(m1,m2)
 
382
    except:
 
383
        import DisplayTrace
 
384
        DisplayTrace.DisplayTrace()
 
385
 
 
386
#------------------------------------------------------------------------
 
387
#
 
388
 
389
#
 
390
#------------------------------------------------------------------------
 
391
def _make_default_style(default_style):
 
392
    """Make the default output style for the Ahnentafel report."""
 
393
    font = BaseDoc.FontStyle()
 
394
    font.set(face=BaseDoc.FONT_SANS_SERIF,size=16,bold=1)
 
395
    para = BaseDoc.ParagraphStyle()
 
396
    para.set_font(font)
 
397
    para.set_header_level(1)
 
398
    para.set(pad=0.5)
 
399
    para.set_description(_('The style used for the title of the page.'))
 
400
    default_style.add_style("AHN-Title",para)
 
401
    
 
402
    font = BaseDoc.FontStyle()
 
403
    font.set(face=BaseDoc.FONT_SANS_SERIF,size=14,italic=1)
 
404
    para = BaseDoc.ParagraphStyle()
 
405
    para.set_font(font)
 
406
    para.set_header_level(2)
 
407
    para.set(pad=0.5)
 
408
    para.set_description(_('The style used for the generation header.'))
 
409
    default_style.add_style("AHN-Generation",para)
 
410
    
 
411
    para = BaseDoc.ParagraphStyle()
 
412
    para.set(first_indent=-1.0,lmargin=1.0,pad=0.25)
 
413
    para.set_description(_('The basic style used for the text display.'))
 
414
    default_style.add_style("AHN-Entry",para)
 
415
 
 
416
#------------------------------------------------------------------------
 
417
#
 
418
 
419
#
 
420
#------------------------------------------------------------------------
 
421
def get_xpm_image():
 
422
    return [
 
423
        "48 48 33 1",
 
424
        "       c None",
 
425
        ".      c #1A1A1A",
 
426
        "+      c #847B6E",
 
427
        "@      c #B7AC9C",
 
428
        "#      c #D1D1D0",
 
429
        "$      c #EEE2D0",
 
430
        "%      c #6A655C",
 
431
        "&      c #868686",
 
432
        "*      c #F1EADF",
 
433
        "=      c #5C5854",
 
434
        "-      c #B89C73",
 
435
        ";      c #E2C8A1",
 
436
        ">      c #55524C",
 
437
        ",      c #F5EEE6",
 
438
        "'      c #4F4E4C",
 
439
        ")      c #A19C95",
 
440
        "!      c #B3966E",
 
441
        "~      c #CDC8BF",
 
442
        "{      c #F6F2ED",
 
443
        "]      c #A6A5A4",
 
444
        "^      c #413F3F",
 
445
        "/      c #D8D1C5",
 
446
        "(      c #968977",
 
447
        "_      c #BAB9B6",
 
448
        ":      c #FAFAF9",
 
449
        "<      c #BEA27B",
 
450
        "[      c #E9DAC2",
 
451
        "}      c #9D9385",
 
452
        "|      c #E4E3E3",
 
453
        "1      c #7A7062",
 
454
        "2      c #E6D3B4",
 
455
        "3      c #BAA488",
 
456
        "4      c #322E2B",
 
457
        "                                                ",
 
458
        "                                                ",
 
459
        "             (+(+++++111%1%%%%===%1             ",
 
460
        "             +______________@_@)&==1            ",
 
461
        "             +_::::::::::::::*|#_&&}>           ",
 
462
        "             &_:::::::::::::::{|#]1~}^          ",
 
463
        "             +_::::::::::::::::{|#=|~&4         ",
 
464
        "             +_::::]]]]]]]]:::::|{':|~&4        ",
 
465
        "             +_::::::::::::::::::{'::|~&4       ",
 
466
        "             +_:::::::::::::::::::'*::|~&^      ",
 
467
        "             +_:::::::::::::::::::'|*::|~}>     ",
 
468
        "             1_::::]]]]]]]]]]]]:::'~|{::|_}%    ",
 
469
        "             1_:::::::::::::::::::'..4^'=1+%1   ",
 
470
        "             +_::::]]]]]]]]]]]]:::|__])&+%=^%   ",
 
471
        "             1_::::::::::::::::::::|#__)&&+'^   ",
 
472
        "             1_::::]]]]]]]]]::::::::|#~_])&%^   ",
 
473
        "             1_::::::::::::::::::::{||#~_])14   ",
 
474
        "             1_::::]]]]]]]]]]]]]]]]]]&}#~_]+4   ",
 
475
        "             1_::::::::::::::::::{{{{||#~~@&4   ",
 
476
        "             %_::::]]]]]]]]]]]]]]]])))}(~~~&4   ",
 
477
        "             %_:::::::::::::::::{{{{{*|#/~_(4   ",
 
478
        "             %_::::]]]]]]]]]]]]]]])))))}2;/}4   ",
 
479
        "             %_:::::::::::::::{{{{{***||[#~}4   ",
 
480
        "             %_::::]]]]]]]]]])]))))))))}2/;)4   ",
 
481
        "             %_::::::::::::::{{{{{**|$$[/2~!4   ",
 
482
        "             %_::::]]]]]]]]){{{{******$$[2/}4   ",
 
483
        "             %_::::::::::::{{{{****$$$$$[2/!4   ",
 
484
        "             =_::::]]]]]]])]))))))))})}}[2/!4   ",
 
485
        "             %_:::::::::{{{{{{**|$$$$$$[[2;)4   ",
 
486
        "             =_::::]]]])]]))))))))))}}}}[22!4   ",
 
487
        "             %_::::::::{{{{{|**|$$[$[[[[[22}4   ",
 
488
        "             =_::::]]])])))))))))}}}}}}}222-4   ",
 
489
        "             =_:::::{{{{{|{*|$$$$$[[[[22222!4   ",
 
490
        "             =_::::)]])))))))))}}}}}}(}(2;2-4   ",
 
491
        "             =_:::{{{{{{***|$$$$$[[[[22222;-4   ",
 
492
        "             =_:::{])))))))))}}}}}}}(}((2;;<4   ",
 
493
        "             >_:{{{{{{**|$$$$$[[[[22222;2;;-4   ",
 
494
        "             >_{{{{)))))))}}}}}}}(!(((((;;;-4   ",
 
495
        "             >_{{{{|**|*$$$$$[[[[22222;;;;;!4   ",
 
496
        "             '_{{{{****$$$$$2[[222222;2;;;;-4   ",
 
497
        "             '@{{****$$$$$[[[2[222;;2;;;;;;!4   ",
 
498
        "             >]{******$$$[$[2[[2222;;;;;;;;!4   ",
 
499
        "             '_****$$$$[$[[[[2222;2;;;;;;;;!4   ",
 
500
        "             '@__@@@@@@@33<3<<<<<<-<-!!!!!!!4   ",
 
501
        "             44444444444444444444444444444444   ",
 
502
        "                                                ",
 
503
        "                                                ",
 
504
        "                                                "]
 
505
 
 
506
#------------------------------------------------------------------------
 
507
#
 
508
 
509
#
 
510
#------------------------------------------------------------------------
 
511
from Plugins import register_report, register_book_item
 
512
 
 
513
register_report(
 
514
    report,
 
515
    _("Ahnentafel Report"),
 
516
    category=_("Text Reports"),
 
517
    status=(_("Beta")),
 
518
    description= _("Produces a textual ancestral report"),
 
519
    xpm=get_xpm_image(),
 
520
    author_name="Donald N. Allingham",
 
521
    author_email="dallingham@users.sourceforge.net"
 
522
    )
 
523
 
 
524
# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style)
 
525
register_book_item( 
 
526
    _("Ahnentafel Report"), 
 
527
    _("Text"),
 
528
    AncestorBareReportDialog,
 
529
    write_book_item,
 
530
    _options,
 
531
    _style_name,
 
532
    _style_file,
 
533
    _make_default_style
 
534
   )