Merge REP_OPT branch
svn: r3827
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
#
|
||||
# Copyright (C) 2003-2004 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,10 +20,8 @@
|
||||
|
||||
# $Id$
|
||||
|
||||
#
|
||||
# Written by Alex Roitman,
|
||||
# largely based on the BaseDoc classes by Don Allingham
|
||||
#
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -32,6 +29,7 @@
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import os
|
||||
from gettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -43,13 +41,6 @@ try:
|
||||
except:
|
||||
from _xmlplus.sax import make_parser,handler,SAXParseException
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# internationalization
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gettext import gettext as _
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
@@ -70,8 +61,9 @@ import ListModel
|
||||
import Plugins
|
||||
import Report
|
||||
import BaseDoc
|
||||
|
||||
from QuestionDialog import WarningDialog
|
||||
import ReportOptions
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Book Item class
|
||||
@@ -103,9 +95,8 @@ class BookItem:
|
||||
|
||||
self.name = ""
|
||||
self.category = ""
|
||||
self.dialog = None
|
||||
self.write_item = None
|
||||
self.options = []
|
||||
self.option_class = None
|
||||
self.style_file = ""
|
||||
self.style_name = "default"
|
||||
self.make_default_style = None
|
||||
@@ -122,12 +113,9 @@ class BookItem:
|
||||
if item[0] == name:
|
||||
self.name = item[0]
|
||||
self.category = item[1]
|
||||
self.dialog = item[2]
|
||||
self.write_item = item[3]
|
||||
self.options = list(item[4])
|
||||
self.style_name = item[5]
|
||||
self.style_file = item[6]
|
||||
self.make_default_style = item[7]
|
||||
self.write_item = item[2]
|
||||
self.item_name = item[4]
|
||||
self.option_class = item[3](self.item_name)
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
@@ -141,32 +129,12 @@ class BookItem:
|
||||
"""
|
||||
return self.category
|
||||
|
||||
def get_dialog(self):
|
||||
"""
|
||||
Returns the callable cofigurator dialog.
|
||||
"""
|
||||
return self.dialog
|
||||
|
||||
def get_write_item(self):
|
||||
"""
|
||||
Returns the report-writing function of the item.
|
||||
"""
|
||||
return self.write_item
|
||||
|
||||
def set_options(self,options):
|
||||
"""
|
||||
Sets the options for the item.
|
||||
|
||||
options: list of options to set.
|
||||
"""
|
||||
self.options = options
|
||||
|
||||
def get_options(self):
|
||||
"""
|
||||
Returns the list of options for the item.
|
||||
"""
|
||||
return self.options
|
||||
|
||||
def set_style_name(self,style_name):
|
||||
"""
|
||||
Sets the style name for the item.
|
||||
@@ -312,7 +280,7 @@ class BookList:
|
||||
BookList is loaded from a specified XML file if it exists.
|
||||
"""
|
||||
|
||||
def __init__(self,file):
|
||||
def __init__(self,filename):
|
||||
"""
|
||||
Creates a new BookList from the books that may be defined in the
|
||||
specified file.
|
||||
@@ -321,7 +289,7 @@ class BookList:
|
||||
"""
|
||||
|
||||
self.bookmap = {}
|
||||
self.file = os.path.expanduser("~/.gramps/" + file)
|
||||
self.file = os.path.expanduser("~/.gramps/" + filename)
|
||||
self.parse()
|
||||
|
||||
def delete_book(self,name):
|
||||
@@ -374,18 +342,23 @@ class BookList:
|
||||
f.write('<book name="%s" database="%s">\n' % (name,dbname) )
|
||||
for item in book.get_item_list():
|
||||
f.write(' <item name="%s">\n' % item.get_name() )
|
||||
options = item.get_options()
|
||||
for opt_index in range(len(options)):
|
||||
if type(options[opt_index]) == type([]):
|
||||
f.write(' <option number="%d" value="" length="%d">\n' % (
|
||||
opt_index, len(options[opt_index]) ) )
|
||||
for list_index in range(len(options[opt_index])):
|
||||
f.write(' <listitem number="%d" value="%s"/>\n' % (
|
||||
list_index, options[opt_index][list_index]) )
|
||||
option_handler = item.option_class.handler
|
||||
for option_name in option_handler.options_dict.keys():
|
||||
option_value = option_handler.options_dict[option_name]
|
||||
if type(option_value) in (list,tuple):
|
||||
f.write(' <option name="%s" length="%d">\n' % (
|
||||
option_name, len(option_value) ) )
|
||||
for list_index in range(len(option_value)):
|
||||
option_type = Utils.type_name(option_value[list_index])
|
||||
f.write(' <listitem number="%d" type="%s" value="%s"/>\n' % (
|
||||
list_index, option_type, option_value[list_index]) )
|
||||
f.write(' </option>\n')
|
||||
else:
|
||||
f.write(' <option number="%d" value="%s"/>\n' % (
|
||||
opt_index,options[opt_index]) )
|
||||
option_type = Utils.type_name(option_value)
|
||||
f.write(' <option name="%s" type="%s" value="%s"/>\n' % (
|
||||
option_name,option_type,option_value) )
|
||||
f.write(' <person gramps_id="%s"/>\n' %
|
||||
option_handler.get_person_id() )
|
||||
f.write(' <style name="%s"/>\n' % item.get_style_name() )
|
||||
f.write(' </item>\n')
|
||||
f.write('</book>\n')
|
||||
@@ -404,6 +377,7 @@ class BookList:
|
||||
except (IOError,OSError,SAXParseException):
|
||||
pass
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# BookParser
|
||||
@@ -425,8 +399,10 @@ class BookParser(handler.ContentHandler):
|
||||
self.b = None
|
||||
self.i = None
|
||||
self.o = None
|
||||
self.an_o = None
|
||||
self.an_o_name = None
|
||||
self.an_o_value = None
|
||||
self.s = None
|
||||
self.p = None
|
||||
self.bname = None
|
||||
self.iname = None
|
||||
|
||||
@@ -442,23 +418,29 @@ class BookParser(handler.ContentHandler):
|
||||
self.b.set_dbname(self.dbname)
|
||||
elif tag == "item":
|
||||
self.i = BookItem(attrs['name'])
|
||||
self.o = []
|
||||
self.o = {}
|
||||
elif tag == "option":
|
||||
self.an_o_name = attrs['name']
|
||||
if attrs.has_key('length'):
|
||||
self.an_o = []
|
||||
self.an_o_value = []
|
||||
else:
|
||||
self.an_o = attrs['value']
|
||||
converter = Utils.get_type_converter_by_name(attrs['type'])
|
||||
self.an_o_value = converter(attrs['value'])
|
||||
elif tag == "listitem":
|
||||
self.an_o.append(attrs['value'])
|
||||
converter = Utils.get_type_converter_by_name(attrs['type'])
|
||||
self.an_o_value.append(converter(attrs['value']))
|
||||
elif tag == "style":
|
||||
self.s = attrs['name']
|
||||
elif tag == "person":
|
||||
self.p = attrs['gramps_id']
|
||||
|
||||
def endElement(self,tag):
|
||||
"Overridden class that handles the end of a XML element"
|
||||
if tag == "option":
|
||||
self.o.append(self.an_o)
|
||||
self.o[self.an_o_name] = self.an_o_value
|
||||
elif tag == "item":
|
||||
self.i.set_options(self.o)
|
||||
self.i.option_class.handler.options_dict.update(self.o)
|
||||
self.i.option_class.handler.set_person_id(self.p)
|
||||
self.i.set_style_name(self.s)
|
||||
self.b.append_item(self.i)
|
||||
elif tag == "book":
|
||||
@@ -476,15 +458,17 @@ class BookListDisplay:
|
||||
Allows the user to select and/or delete a book from the list.
|
||||
"""
|
||||
|
||||
def __init__(self,booklist,nodelete=0):
|
||||
def __init__(self,booklist,nodelete=0,dosave=0):
|
||||
"""
|
||||
Creates a BookListDisplay object that displays the books in BookList.
|
||||
|
||||
booklist: books that are displayed
|
||||
nodelete: if not 0 then the Delete button is hidden
|
||||
dosave: if 1 then the book list is saved on hitting OK
|
||||
"""
|
||||
|
||||
self.booklist = booklist
|
||||
self.dosave = dosave
|
||||
base = os.path.dirname(__file__)
|
||||
glade_file = os.path.join(base,"book.glade")
|
||||
self.xml = gtk.glade.XML(glade_file,"booklist","gramps")
|
||||
@@ -531,7 +515,8 @@ class BookListDisplay:
|
||||
if iter:
|
||||
data = self.blist.get_data(iter,[0])
|
||||
self.selection = self.booklist.get_book(data[0])
|
||||
self.booklist.save()
|
||||
if self.dosave:
|
||||
self.booklist.save()
|
||||
|
||||
def on_booklist_delete_clicked(self,obj):
|
||||
"""
|
||||
@@ -550,6 +535,31 @@ class BookListDisplay:
|
||||
def on_booklist_cancel_clicked(self,obj):
|
||||
pass
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class BookOptions:
|
||||
|
||||
"""
|
||||
Defines options and provides handling interface.
|
||||
"""
|
||||
|
||||
def __init__(self,name,person_id=None):
|
||||
# Options specific for this report
|
||||
self.options_dict = {
|
||||
'bookname' : '',
|
||||
}
|
||||
self.options_help = {
|
||||
'bookname' : ("=name","Name of the book. MANDATORY",
|
||||
BookList('books.xml').get_book_names(),
|
||||
False),
|
||||
}
|
||||
|
||||
self.handler = ReportOptions.OptionHandler(name,
|
||||
self.options_dict,person_id)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Book creation dialog
|
||||
@@ -668,10 +678,11 @@ class BookReportSelector:
|
||||
for saved_item in book.get_item_list():
|
||||
name = saved_item.get_name()
|
||||
item = BookItem(name)
|
||||
options = saved_item.get_options()
|
||||
if not same_db or not options[0]:
|
||||
options[0] = self.person.get_handle()
|
||||
item.set_options(options)
|
||||
item.option_class = saved_item.option_class
|
||||
person_id = item.option_class.handler.get_person_id()
|
||||
if not same_db or not person_id:
|
||||
person_id = self.person.get_gramps_id()
|
||||
item.option_class.handler.set_person_id(person_id)
|
||||
item.set_style_name(saved_item.get_style_name())
|
||||
self.book.append_item(item)
|
||||
|
||||
@@ -679,7 +690,7 @@ class BookReportSelector:
|
||||
if data[1] == _("Title"):
|
||||
data.append(_("Not Applicable"))
|
||||
else:
|
||||
pname = self.db.get_person_from_handle(options[0])
|
||||
pname = self.db.get_person_from_gramps_id(person_id)
|
||||
data.append(pname.get_primary_name().get_regular_name())
|
||||
self.bk_model.add(data)
|
||||
|
||||
@@ -699,10 +710,10 @@ class BookReportSelector:
|
||||
data.append(self.person.get_primary_name().get_regular_name())
|
||||
self.bk_model.add(data)
|
||||
item = BookItem(data[0])
|
||||
options = item.get_options()
|
||||
if not options[0]:
|
||||
options[0] = self.person.get_handle()
|
||||
item.set_options(options)
|
||||
person_id = item.option_class.handler.get_person_id()
|
||||
if not person_id:
|
||||
person_id = self.person.get_gramps_id()
|
||||
item.option_class.handler.set_person_id(person_id)
|
||||
self.book.append_item(item)
|
||||
|
||||
def on_remove_clicked(self,obj):
|
||||
@@ -761,17 +772,14 @@ class BookReportSelector:
|
||||
data = self.bk_model.get_data(iter,range(self.bk_ncols))
|
||||
row = self.bk_model.get_selected_row()
|
||||
item = self.book.get_item(row)
|
||||
options_dialog = item.get_dialog()
|
||||
options = item.get_options()
|
||||
style_name = item.get_style_name()
|
||||
opt_dlg = options_dialog(self.db,self.person,options,style_name)
|
||||
opt_dlg.window.destroy()
|
||||
if opt_dlg.person and data[1] != _("Title"):
|
||||
option_class = item.option_class
|
||||
item_dialog = BookItemDialog(self.db,option_class,data[0])
|
||||
response = item_dialog.window.run()
|
||||
if response == True and item_dialog.person and data[1] != _("Title"):
|
||||
self.bk_model.model.set_value(iter,2,
|
||||
opt_dlg.person.get_primary_name().get_regular_name())
|
||||
item.set_options(opt_dlg.options)
|
||||
item.set_style_name(opt_dlg.style_name)
|
||||
self.book.set_item(row,item)
|
||||
item_dialog.person.get_primary_name().get_regular_name())
|
||||
self.book.set_item(row,item)
|
||||
item_dialog.window.destroy()
|
||||
|
||||
def bk_button_press(self,obj,event):
|
||||
"""
|
||||
@@ -852,7 +860,7 @@ class BookReportSelector:
|
||||
Run final BookReportDialog with the current book.
|
||||
"""
|
||||
if self.book.item_list:
|
||||
BookReportDialog(self.db,self.person,self.book)
|
||||
BookReportDialog(self.db,self.person,self.book,BookOptions)
|
||||
self.top.destroy()
|
||||
|
||||
def on_save_clicked(self,obj):
|
||||
@@ -871,20 +879,56 @@ class BookReportSelector:
|
||||
Run the BookListDisplay dialog to present the choice of books to open.
|
||||
"""
|
||||
self.book_list = BookList(self.file)
|
||||
booklistdisplay = BookListDisplay(self.book_list,1)
|
||||
booklistdisplay = BookListDisplay(self.book_list,1,0)
|
||||
booklistdisplay.top.destroy()
|
||||
book = booklistdisplay.selection
|
||||
if book:
|
||||
self.open_book(book)
|
||||
self.name_entry.set_text(book.get_name())
|
||||
|
||||
def on_edit_clicked(self,obj):
|
||||
"""
|
||||
Run the BookListDisplay dialog to present the choice of books to delete.
|
||||
"""
|
||||
self.book_list = BookList(self.file)
|
||||
booklistdisplay = BookListDisplay(self.book_list)
|
||||
booklistdisplay = BookListDisplay(self.book_list,0,1)
|
||||
booklistdisplay.top.destroy()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Book Item Options dialog
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class BookItemDialog(Report.BareReportDialog):
|
||||
|
||||
"""
|
||||
This class overrides the interface methods common for different reports
|
||||
in a way specific for this report. This is a book item dialog.
|
||||
"""
|
||||
|
||||
def __init__(self,database,option_class,name=''):
|
||||
|
||||
self.database = database
|
||||
self.option_class = option_class
|
||||
self.person = self.database.get_person_from_gramps_id(self.option_class.handler.get_person_id())
|
||||
self.new_person = None
|
||||
Report.BareReportDialog.__init__(self,database,self.person,option_class,name)
|
||||
|
||||
def on_ok_clicked(self, obj):
|
||||
"""The user is satisfied with the dialog choices. Parse all options
|
||||
and close the window."""
|
||||
|
||||
# Preparation
|
||||
self.parse_style_frame()
|
||||
self.parse_report_options_frame()
|
||||
self.parse_user_options()
|
||||
|
||||
if self.new_person:
|
||||
self.person = self.new_person
|
||||
|
||||
self.option_class.handler.set_person_id(self.person.get_gramps_id())
|
||||
self.options.handler.save_options()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# The final dialog - paper, format, target, etc.
|
||||
@@ -897,8 +941,9 @@ class BookReportDialog(Report.ReportDialog):
|
||||
Creates a dialog selecting target, format, and paper/HTML options.
|
||||
"""
|
||||
|
||||
def __init__(self,database,person,book):
|
||||
Report.BareReportDialog.__init__(self,database,person)
|
||||
def __init__(self,database,person,book,options):
|
||||
self.options = options
|
||||
Report.BareReportDialog.__init__(self,database,person,options,'book')
|
||||
self.book = book
|
||||
self.database = database
|
||||
self.person = person
|
||||
@@ -907,21 +952,29 @@ class BookReportDialog(Report.ReportDialog):
|
||||
for item in self.book.get_item_list():
|
||||
# Set up default style
|
||||
default_style = BaseDoc.StyleSheet()
|
||||
make_default_style = item.get_make_default_style()
|
||||
make_default_style = item.option_class.make_default_style
|
||||
make_default_style(default_style)
|
||||
|
||||
# Read all style sheets available for this item
|
||||
style_file = item.get_style_file()
|
||||
style_file = item.option_class.handler.get_stylesheet_savefile()
|
||||
style_list = BaseDoc.StyleSheetList(style_file,default_style)
|
||||
|
||||
# Get the selected stylesheet
|
||||
style_name = item.get_style_name()
|
||||
style_name = item.option_class.handler.get_default_stylesheet_name()
|
||||
style_sheet = style_list.get_style_sheet(style_name)
|
||||
|
||||
for this_style_name in style_sheet.get_names():
|
||||
self.selected_style.add_style(
|
||||
this_style_name,style_sheet.get_style(this_style_name))
|
||||
|
||||
response = self.window.run()
|
||||
if response == True:
|
||||
try:
|
||||
self.make_report()
|
||||
except (IOError,OSError),msg:
|
||||
ErrorDialog(str(msg))
|
||||
self.window.destroy()
|
||||
|
||||
def setup_style_frame(self): pass
|
||||
def setup_report_options_frame(self): pass
|
||||
def setup_other_frames(self): pass
|
||||
@@ -942,12 +995,12 @@ class BookReportDialog(Report.ReportDialog):
|
||||
"""Needed solely for forming sane filename for the output."""
|
||||
return "book.xml"
|
||||
|
||||
def make_doc_menu(self):
|
||||
def make_doc_menu(self,active=None):
|
||||
"""Build a menu of document types that are appropriate for
|
||||
this text report. This menu will be generated based upon
|
||||
whether the document requires table support, etc."""
|
||||
Plugins.get_book_menu(self.format_menu, self.doc_uses_tables(),
|
||||
self.doc_type_changed)
|
||||
self.doc_type_changed,None,active)
|
||||
|
||||
def make_document(self):
|
||||
"""Create a document of the type requested by the user."""
|
||||
@@ -957,13 +1010,13 @@ class BookReportDialog(Report.ReportDialog):
|
||||
self.rptlist = []
|
||||
newpage = 0
|
||||
for item in self.book.get_item_list():
|
||||
write_book_item = item.get_write_item()
|
||||
options = item.get_options()
|
||||
if write_book_item:
|
||||
obj = write_book_item(self.database,self.person,
|
||||
self.doc,options,newpage)
|
||||
self.rptlist.append(obj)
|
||||
newpage = 1
|
||||
item.option_class.handler.doc = self.doc
|
||||
item.option_class.handler.newpage = newpage
|
||||
report_class = item.get_write_item()
|
||||
obj = Report.write_book_item(self.database,self.person,
|
||||
report_class,item.option_class)
|
||||
self.rptlist.append(obj)
|
||||
newpage = 1
|
||||
self.doc.open(self.target_path)
|
||||
|
||||
def make_report(self):
|
||||
@@ -977,24 +1030,76 @@ class BookReportDialog(Report.ReportDialog):
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Function to register the overall book report
|
||||
# Function to write books from command line
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def report(database,person):
|
||||
BookReportSelector(database,person)
|
||||
|
||||
def cl_report(database,name,category,options_str_dict):
|
||||
|
||||
clr = Report.CommandLineReport(database,name,category,BookOptions,options_str_dict)
|
||||
|
||||
# Exit here if show option was given
|
||||
if clr.show:
|
||||
return
|
||||
|
||||
book_list = BookList('books.xml')
|
||||
book_name = clr.options_dict['bookname']
|
||||
book = book_list.get_book(book_name)
|
||||
selected_style = BaseDoc.StyleSheet()
|
||||
|
||||
for item in book.get_item_list():
|
||||
# Set up default style
|
||||
default_style = BaseDoc.StyleSheet()
|
||||
make_default_style = item.option_class.make_default_style
|
||||
make_default_style(default_style)
|
||||
|
||||
# Read all style sheets available for this item
|
||||
style_file = item.option_class.handler.get_stylesheet_savefile()
|
||||
style_list = BaseDoc.StyleSheetList(style_file,default_style)
|
||||
|
||||
# Get the selected stylesheet
|
||||
style_name = item.option_class.handler.get_default_stylesheet_name()
|
||||
style_sheet = style_list.get_style_sheet(style_name)
|
||||
|
||||
for this_style_name in style_sheet.get_names():
|
||||
selected_style.add_style(
|
||||
this_style_name,style_sheet.get_style(this_style_name))
|
||||
|
||||
# write report
|
||||
try:
|
||||
doc = clr.format(selected_style,clr.paper,clr.template_name,clr.orien)
|
||||
rptlist = []
|
||||
newpage = 0
|
||||
for item in book.get_item_list():
|
||||
item.option_class.handler.doc = doc
|
||||
item.option_class.handler.newpage = newpage
|
||||
report_class = item.get_write_item()
|
||||
obj = Report.write_book_item(database,clr.person,
|
||||
report_class,item.option_class)
|
||||
rptlist.append(obj)
|
||||
newpage = 1
|
||||
doc.open(clr.option_class.handler.output)
|
||||
doc.init()
|
||||
for item in rptlist:
|
||||
item.write_report()
|
||||
doc.close()
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
Plugins.register_report(
|
||||
report,
|
||||
_("Book Report"),
|
||||
category=_("Books"),
|
||||
status=(_("Unstable")),
|
||||
description=_("Creates a book containing several reports."),
|
||||
author_name="Alex Roitman",
|
||||
author_email="shura@alex.neuro.umn.edu"
|
||||
name = 'book',
|
||||
category = const.CATEGORY_BOOK,
|
||||
report_class = BookReportSelector,
|
||||
options_class = cl_report,
|
||||
modes = Report.MODE_GUI | Report.MODE_CLI,
|
||||
translated_name = _("Book Report"),
|
||||
status = _("Beta"),
|
||||
description = _("Creates a book containing several reports."),
|
||||
author_name = "Alex Roitman",
|
||||
author_email = "shura@alex.neuro.umn.edu"
|
||||
)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
import os
|
||||
import string
|
||||
import cStringIO
|
||||
from gettext import gettext as _
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -44,8 +45,17 @@ import BaseDoc
|
||||
import RelLib
|
||||
import Errors
|
||||
import Utils
|
||||
import ReportOptions
|
||||
from QuestionDialog import ErrorDialog
|
||||
from gettext import gettext as _
|
||||
import DateHandler
|
||||
import const
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
dd = DateHandler.create_display()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -54,16 +64,47 @@ from gettext import gettext as _
|
||||
#------------------------------------------------------------------------
|
||||
class FtmDescendantReport(Report.Report):
|
||||
|
||||
def __init__(self,database,person,max,pgbrk,doc,output,newpage=0):
|
||||
self.anc_map = {}
|
||||
self.gen_map = {}
|
||||
def __init__(self,database,person,options_class):
|
||||
"""
|
||||
Creates the Ftm-Style Descendant object that produces the report.
|
||||
|
||||
The arguments are:
|
||||
|
||||
database - the GRAMPS database instance
|
||||
person - currently selected person
|
||||
options_class - instance of the Options class for this report
|
||||
|
||||
This report needs the following parameters (class variables)
|
||||
that come in the options class.
|
||||
|
||||
max_gen - Maximum number of generations to include.
|
||||
pg_breaks - Whether to include page breaks between generations.
|
||||
document - BaseDoc instance for the output file. Any class derived
|
||||
from BaseDoc may be used
|
||||
output - name of the output file.
|
||||
None if report is not a standalone, in which case
|
||||
somebody must take care of opening and initializing report
|
||||
prior to writing.
|
||||
newpage - if True, newpage is made before writing a report
|
||||
|
||||
"""
|
||||
|
||||
self.database = database
|
||||
self.start = person
|
||||
self.max_generations = max
|
||||
self.pgbrk = pgbrk
|
||||
self.doc = doc
|
||||
self.options_class = options_class
|
||||
|
||||
self.anc_map = {}
|
||||
self.gen_map = {}
|
||||
|
||||
(self.max_generations,self.pgbrk) \
|
||||
= options_class.handler.get_report_generations()
|
||||
|
||||
self.doc = options_class.handler.doc
|
||||
output = options_class.handler.output
|
||||
self.newpage = options_class.handler.newpage
|
||||
|
||||
self.setup()
|
||||
self.newpage = newpage
|
||||
|
||||
if output:
|
||||
self.standalone = 1
|
||||
self.doc.open(output)
|
||||
@@ -482,7 +523,7 @@ class FtmDescendantReport(Report.Report):
|
||||
self.doc.write_text(base.get_title())
|
||||
|
||||
for item in [ base.get_author(), base.get_publication_info(), base.get_abbreviation(),
|
||||
srcref.get_date().get_date(),]:
|
||||
dd.display(srcref.get_date()),]:
|
||||
if item:
|
||||
self.doc.write_text('; %s' % item)
|
||||
|
||||
@@ -991,7 +1032,7 @@ class FtmDescendantReport(Report.Report):
|
||||
self.doc.end_row()
|
||||
|
||||
if not first:
|
||||
self.doc.end_table()
|
||||
self.doc.end_table()
|
||||
first = 1
|
||||
|
||||
|
||||
@@ -1448,244 +1489,89 @@ class FtmDescendantReport(Report.Report):
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def _make_default_style(default_style):
|
||||
"""Make the default output style for the FTM Style Descendant report."""
|
||||
font = BaseDoc.FontStyle()
|
||||
font.set(face=BaseDoc.FONT_SANS_SERIF,size=16,bold=1,italic=1)
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set_font(font)
|
||||
para.set_header_level(1)
|
||||
para.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
|
||||
para.set(pad=0.5)
|
||||
para.set_description(_('The style used for the title of the page.'))
|
||||
default_style.add_style("FTD-Title",para)
|
||||
class FtmDescendantOptions:
|
||||
|
||||
"""
|
||||
Defines options and provides handling interface.
|
||||
"""
|
||||
|
||||
def __init__(self,name,person_id=None):
|
||||
# Options specific for this report
|
||||
self.options_dict = {}
|
||||
self.options_help = {}
|
||||
|
||||
# Semi-common options that should be enabled for this report
|
||||
self.enable_dict = {
|
||||
'max_gen' : 10,
|
||||
'page_breaks' : 0,
|
||||
}
|
||||
|
||||
self.options_dict.update(self.enable_dict)
|
||||
self.handler = ReportOptions.OptionHandler(name,
|
||||
self.options_dict,person_id)
|
||||
|
||||
def make_default_style(self,default_style):
|
||||
"""Make the default output style for the FTM Style Descendant report."""
|
||||
font = BaseDoc.FontStyle()
|
||||
font.set(face=BaseDoc.FONT_SANS_SERIF,size=16,bold=1,italic=1)
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set_font(font)
|
||||
para.set_header_level(1)
|
||||
para.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
|
||||
para.set(pad=0.5)
|
||||
para.set_description(_('The style used for the title of the page.'))
|
||||
default_style.add_style("FTD-Title",para)
|
||||
|
||||
font = BaseDoc.FontStyle()
|
||||
font.set(face=BaseDoc.FONT_SANS_SERIF,size=14,italic=1)
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set_font(font)
|
||||
para.set_header_level(2)
|
||||
para.set(pad=0.5)
|
||||
para.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
|
||||
para.set_description(_('The style used for the generation header.'))
|
||||
default_style.add_style("FTD-Generation",para)
|
||||
font = BaseDoc.FontStyle()
|
||||
font.set(face=BaseDoc.FONT_SANS_SERIF,size=14,italic=1)
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set_font(font)
|
||||
para.set_header_level(2)
|
||||
para.set(pad=0.5)
|
||||
para.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
|
||||
para.set_description(_('The style used for the generation header.'))
|
||||
default_style.add_style("FTD-Generation",para)
|
||||
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(first_indent=-1.0,lmargin=1.0,pad=0.25)
|
||||
para.set_description(_('The basic style used for the text display.'))
|
||||
default_style.add_style("FTD-Entry",para)
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(first_indent=-1.0,lmargin=1.0,pad=0.25)
|
||||
para.set_description(_('The basic style used for the text display.'))
|
||||
default_style.add_style("FTD-Entry",para)
|
||||
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(lmargin=1.0,pad=0.05)
|
||||
para.set_description(_('The basic style used for the text display.'))
|
||||
default_style.add_style("FTD-Details",para)
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(lmargin=1.0,pad=0.05)
|
||||
para.set_description(_('The basic style used for the text display.'))
|
||||
default_style.add_style("FTD-Details",para)
|
||||
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(lmargin=0.0,pad=0.05)
|
||||
para.set_description(_('The style used for numbering children.'))
|
||||
default_style.add_style("FTD-Child-Num",para)
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(lmargin=0.0,pad=0.05)
|
||||
para.set_description(_('The style used for numbering children.'))
|
||||
default_style.add_style("FTD-Child-Num",para)
|
||||
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(lmargin=1.0,pad=0.25)
|
||||
para.set_description(_('The basic style used for the text display.'))
|
||||
default_style.add_style("FTD-SubEntry",para)
|
||||
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(pad=0.05)
|
||||
para.set_description(_('The basic style used for the text display.'))
|
||||
default_style.add_style("FTD-Endnotes",para)
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(lmargin=1.0,pad=0.25)
|
||||
para.set_description(_('The basic style used for the text display.'))
|
||||
default_style.add_style("FTD-SubEntry",para)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Dialog for a standalone report
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class FtmDescendantReportDialog(Report.TextReportDialog):
|
||||
|
||||
report_options = {}
|
||||
|
||||
def __init__(self,database,person):
|
||||
Report.TextReportDialog.__init__(self,database,person,self.report_options)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Customization hooks
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def get_title(self):
|
||||
"""The window title for this dialog"""
|
||||
return "%s - %s - GRAMPS" % (_("FTM Style Descendant Report"),_("Text Reports"))
|
||||
|
||||
def get_header(self, name):
|
||||
"""The header line at the top of the dialog contents"""
|
||||
return _("FTM Style Descendant Report for %s") % name
|
||||
|
||||
def get_target_browser_title(self):
|
||||
"""The title of the window created when the 'browse' button is
|
||||
clicked in the 'Save As' frame."""
|
||||
return _("Save FTM Style Descendant Report")
|
||||
|
||||
def get_stylesheet_savefile(self):
|
||||
"""Where to save styles for this report."""
|
||||
return "ftm_descendant_report.xml"
|
||||
|
||||
def make_default_style(self):
|
||||
_make_default_style(self.default_style)
|
||||
|
||||
def make_report(self):
|
||||
"""Create the object that will produce the FTM Style Descendant Report.
|
||||
All user dialog has already been handled and the output file
|
||||
opened."""
|
||||
try:
|
||||
MyReport = FtmDescendantReport(self.db, self.person,
|
||||
self.max_gen, self.pg_brk, self.doc, self.target_path)
|
||||
MyReport.write_report()
|
||||
except Errors.ReportError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except Errors.FilterError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Standalone report function
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def report(database,person):
|
||||
FtmDescendantReportDialog(database,person)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Set up sane defaults for the book_item
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
_style_file = "ftm_descendant_report.xml"
|
||||
_style_name = "default"
|
||||
|
||||
_person_handle = ""
|
||||
_max_gen = 10
|
||||
_pg_brk = 0
|
||||
_options = ( _person_handle, _max_gen, _pg_brk )
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Book Item Options dialog
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class FtmDescendantBareReportDialog(Report.BareReportDialog):
|
||||
|
||||
def __init__(self,database,person,opt,stl):
|
||||
|
||||
self.options = opt
|
||||
self.db = database
|
||||
if self.options[0]:
|
||||
self.person = self.db.get_person_from_handle(self.options[0])
|
||||
else:
|
||||
self.person = person
|
||||
self.style_name = stl
|
||||
|
||||
Report.BareReportDialog.__init__(self,database,self.person)
|
||||
|
||||
self.max_gen = int(self.options[1])
|
||||
self.pg_brk = int(self.options[2])
|
||||
self.new_person = None
|
||||
|
||||
self.generations_spinbox.set_value(self.max_gen)
|
||||
self.pagebreak_checkbox.set_active(self.pg_brk)
|
||||
|
||||
self.window.run()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Customization hooks
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def get_title(self):
|
||||
"""The window title for this dialog"""
|
||||
return "%s - GRAMPS Book" % (_("FTM Style Descendant Report"))
|
||||
|
||||
def get_header(self, name):
|
||||
"""The header line at the top of the dialog contents"""
|
||||
return _("FTM Style Descendant Report for GRAMPS Book")
|
||||
|
||||
def get_stylesheet_savefile(self):
|
||||
"""Where to save styles for this report."""
|
||||
return _style_file
|
||||
|
||||
def make_default_style(self):
|
||||
_make_default_style(self.default_style)
|
||||
|
||||
def on_cancel(self, obj):
|
||||
pass
|
||||
|
||||
def on_ok_clicked(self, obj):
|
||||
"""The user is satisfied with the dialog choices. Parse all options
|
||||
and close the window."""
|
||||
|
||||
# Preparation
|
||||
self.parse_style_frame()
|
||||
self.parse_report_options_frame()
|
||||
|
||||
if self.new_person:
|
||||
self.person = self.new_person
|
||||
self.options = ( self.person.get_handle(), self.max_gen, self.pg_brk )
|
||||
self.style_name = self.selected_style.get_name()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Function to write Book Item
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def write_book_item(database,person,doc,options,newpage=0):
|
||||
"""Write the FTM Style Descendant Report options set.
|
||||
All user dialog has already been handled and the output file opened."""
|
||||
try:
|
||||
if options[0]:
|
||||
person = database.get_person_from_handle(options[0])
|
||||
max_gen = int(options[1])
|
||||
pg_brk = int(options[2])
|
||||
return FtmDescendantReport(database, person, max_gen,
|
||||
pg_brk, doc, None, newpage )
|
||||
except Errors.ReportError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except Errors.FilterError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
para = BaseDoc.ParagraphStyle()
|
||||
para.set(pad=0.05)
|
||||
para.set_description(_('The basic style used for the text display.'))
|
||||
default_style.add_style("FTD-Endnotes",para)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from Plugins import register_report, register_book_item
|
||||
|
||||
from Plugins import register_report
|
||||
register_report(
|
||||
report,
|
||||
_("FTM Style Descendant Report"),
|
||||
category=_("Text Reports"),
|
||||
status=(_("Beta")),
|
||||
name = 'ftm_descendant_report',
|
||||
category = const.CATEGORY_TEXT,
|
||||
report_class = FtmDescendantReport,
|
||||
options_class = FtmDescendantOptions,
|
||||
modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI,
|
||||
translated_name = _("FTM Style Descendant Report"),
|
||||
status = _("Beta"),
|
||||
description= _("Produces a textual descendant report similar to Family Tree Maker."),
|
||||
author_name="Alex Roitman",
|
||||
author_email="shura@alex.neuro.umn.edu"
|
||||
)
|
||||
|
||||
# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style)
|
||||
register_book_item(
|
||||
_("FTM Style Descendant Report"),
|
||||
_("Text"),
|
||||
FtmDescendantBareReportDialog,
|
||||
write_book_item,
|
||||
_options,
|
||||
_style_name,
|
||||
_style_file,
|
||||
_make_default_style
|
||||
)
|
||||
|
||||
@@ -30,6 +30,7 @@ Timeline report
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
import os
|
||||
from gettext import gettext as _
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -50,9 +51,9 @@ import GenericFilter
|
||||
import Errors
|
||||
import Date
|
||||
import Sort
|
||||
import ReportOptions
|
||||
from QuestionDialog import ErrorDialog
|
||||
|
||||
from gettext import gettext as _
|
||||
import const
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@@ -61,31 +62,59 @@ from gettext import gettext as _
|
||||
#------------------------------------------------------------------------
|
||||
class TimeLine:
|
||||
|
||||
def __init__(self,database,person,filter,title,sort_func,document,output,newpage=0):
|
||||
def __init__(self,database,person,options_class):
|
||||
"""
|
||||
Creates the Timeline object that produces the report. This class
|
||||
is used by the TimelineDialog class. The arguments are:
|
||||
Creates the Timeline object that produces the report.
|
||||
|
||||
The arguments are:
|
||||
|
||||
database - the GRAMPS database instance
|
||||
person - currently selected person
|
||||
options_class - instance of the Options class for this report
|
||||
|
||||
This report needs the following parameters (class variables)
|
||||
that come in the options class.
|
||||
|
||||
filter - Filter to be applied to the people of the database.
|
||||
The option class carries its number, and the function
|
||||
returning the list of filters.
|
||||
title - Title of the report displayed on top
|
||||
sort_func - function used to sort entries, that returns -1/0/1
|
||||
when given two personal handles (like cmp).
|
||||
The option class carries its number, and the function
|
||||
returning the list of sort functions.
|
||||
document - BaseDoc instance for the output file. Any class derived
|
||||
from BaseDoc may be used
|
||||
output - name of the output file.
|
||||
None if report is not a standalone, in which case
|
||||
somebody must take care of opening and initializing report
|
||||
prior to writing.
|
||||
newpage - if True, newpage is made before writing a report
|
||||
|
||||
database - the GRAMPS database
|
||||
person - currently selected person
|
||||
output - name of the output file
|
||||
document - BaseDoc instance for the output file. Any class derived
|
||||
from BaseDoc may be used.
|
||||
filter - filtering function selected by the TimeLineDialog
|
||||
class.
|
||||
"""
|
||||
self.d = document
|
||||
self.filter = filter
|
||||
|
||||
self.db = database
|
||||
self.person = person
|
||||
self.output = output
|
||||
self.title = title
|
||||
self.sort_func = sort_func
|
||||
self.newpage = newpage
|
||||
self.options_class = options_class
|
||||
|
||||
filter_num = options_class.handler.get_filter_number()
|
||||
filters = options_class.get_report_filters(person)
|
||||
self.filter = filters[filter_num]
|
||||
|
||||
self.title = options_class.handler.options_dict['title']
|
||||
|
||||
sort_func_num = options_class.handler.options_dict['sortby']
|
||||
sort_functions = options_class.get_sort_functions(Sort.Sort(database))
|
||||
self.sort_func = sort_functions[sort_func_num][1]
|
||||
|
||||
self.d = options_class.handler.doc
|
||||
self.output = options_class.handler.output
|
||||
self.newpage = options_class.handler.newpage
|
||||
|
||||
self.setup()
|
||||
if output:
|
||||
if self.output:
|
||||
self.standalone = 1
|
||||
self.d.open(output)
|
||||
self.d.open(self.output)
|
||||
self.d.init()
|
||||
else:
|
||||
self.standalone = 0
|
||||
@@ -168,7 +197,7 @@ class TimeLine:
|
||||
|
||||
font = self.d.style_list['TLG-Name'].get_font()
|
||||
|
||||
incr = pt2cm(font.get_size())
|
||||
incr = Utils.pt2cm(font.get_size())
|
||||
pad = incr*.75
|
||||
|
||||
x1,x2,y1,y2 = (0,0,0,0)
|
||||
@@ -267,7 +296,7 @@ class TimeLine:
|
||||
|
||||
self.d.center_text('TLG-title',self.title,width/2.0,0)
|
||||
|
||||
label_y = self.header - (pt2cm(normal_font.get_size())*1.2)
|
||||
label_y = self.header - (Utils.pt2cm(normal_font.get_size())*1.2)
|
||||
top_y = self.header
|
||||
bottom_y = self.d.get_usable_height()
|
||||
|
||||
@@ -330,373 +359,156 @@ class TimeLine:
|
||||
p = self.db.get_person_from_handle(p_id)
|
||||
n = p.get_primary_name().get_name()
|
||||
size = max(self.d.string_width(font,n),size)
|
||||
return pt2cm(size)
|
||||
|
||||
return Utils.pt2cm(size)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def _make_default_style(default_style):
|
||||
"""Make the default output style for the Timeline report."""
|
||||
f = BaseDoc.FontStyle()
|
||||
f.set_size(10)
|
||||
f.set_type_face(BaseDoc.FONT_SANS_SERIF)
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
p.set_font(f)
|
||||
p.set_description(_("The style used for the person's name."))
|
||||
default_style.add_style("TLG-Name",p)
|
||||
class TimeLineOptions:
|
||||
|
||||
f = BaseDoc.FontStyle()
|
||||
f.set_size(8)
|
||||
f.set_type_face(BaseDoc.FONT_SANS_SERIF)
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
p.set_font(f)
|
||||
p.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
|
||||
p.set_description(_("The style used for the year labels."))
|
||||
default_style.add_style("TLG-Label",p)
|
||||
"""
|
||||
Defines options and provides handling interface.
|
||||
"""
|
||||
|
||||
f = BaseDoc.FontStyle()
|
||||
f.set_size(14)
|
||||
f.set_type_face(BaseDoc.FONT_SANS_SERIF)
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
p.set_font(f)
|
||||
p.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
|
||||
p.set_description(_("The style used for the title of the page."))
|
||||
default_style.add_style("TLG-Title",p)
|
||||
def __init__(self,name,person_id=None):
|
||||
# Options specific for this report
|
||||
self.options_dict = {
|
||||
'sortby' : 0,
|
||||
'title' : '',
|
||||
}
|
||||
self.options_help = {
|
||||
'sortby' : ("=num","Number of a sorting function",
|
||||
[item[0] for item in
|
||||
self.get_sort_functions(Sort.Sort(None))],
|
||||
True),
|
||||
'title' : ("=str","Title string for the report",
|
||||
"Whatever String You Wish"),
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Builds filter list for this report
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def _get_report_filters(person):
|
||||
"""Set up the list of possible content filters."""
|
||||
# Semi-common options that should be enabled for this report
|
||||
self.enable_dict = {
|
||||
'filter' : 0,
|
||||
}
|
||||
|
||||
name = person.get_primary_name().get_name()
|
||||
|
||||
all = GenericFilter.GenericFilter()
|
||||
all.set_name(_("Entire Database"))
|
||||
all.add_rule(GenericFilter.Everyone([]))
|
||||
self.options_dict.update(self.enable_dict)
|
||||
self.handler = ReportOptions.OptionHandler(name,
|
||||
self.options_dict,person_id)
|
||||
|
||||
des = GenericFilter.GenericFilter()
|
||||
des.set_name(_("Descendants of %s") % name)
|
||||
des.add_rule(GenericFilter.IsDescendantOf([person.get_handle(),1]))
|
||||
def make_default_style(self,default_style):
|
||||
"""Make the default output style for the Timeline report."""
|
||||
f = BaseDoc.FontStyle()
|
||||
f.set_size(10)
|
||||
f.set_type_face(BaseDoc.FONT_SANS_SERIF)
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
p.set_font(f)
|
||||
p.set_description(_("The style used for the person's name."))
|
||||
default_style.add_style("TLG-Name",p)
|
||||
|
||||
ans = GenericFilter.GenericFilter()
|
||||
ans.set_name(_("Ancestors of %s") % name)
|
||||
ans.add_rule(GenericFilter.IsAncestorOf([person.get_handle(),1]))
|
||||
f = BaseDoc.FontStyle()
|
||||
f.set_size(8)
|
||||
f.set_type_face(BaseDoc.FONT_SANS_SERIF)
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
p.set_font(f)
|
||||
p.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
|
||||
p.set_description(_("The style used for the year labels."))
|
||||
default_style.add_style("TLG-Label",p)
|
||||
|
||||
com = GenericFilter.GenericFilter()
|
||||
com.set_name(_("People with common ancestor with %s") % name)
|
||||
com.add_rule(GenericFilter.HasCommonAncestorWith([person.get_handle()]))
|
||||
|
||||
return [all,des,ans,com]
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Builds list of sorting functions for this report
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def _get_sort_functions(sort):
|
||||
return [
|
||||
(_("Birth Date"),sort.by_birthdate),
|
||||
(_("Name"),sort.by_last_name),
|
||||
]
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# TimeLineDialog
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class TimeLineDialog(Report.DrawReportDialog):
|
||||
|
||||
report_options = {}
|
||||
|
||||
def __init__(self,database,person):
|
||||
self.database = database
|
||||
Report.DrawReportDialog.__init__(self,database,person,self.report_options)
|
||||
|
||||
def get_title(self):
|
||||
"""The window title for this dialog"""
|
||||
return "%s - %s - GRAMPS" % (_("Timeline Graph"),
|
||||
_("Graphical Reports"))
|
||||
|
||||
def get_header(self, name):
|
||||
"""The header line at the top of the dialog contents."""
|
||||
return _("Timeline Graph for %s") % name
|
||||
|
||||
def get_stylesheet_savefile(self):
|
||||
"""Where to save user defined styles for this report."""
|
||||
return _style_file
|
||||
|
||||
def get_target_browser_title(self):
|
||||
"""The title of the window created when the 'browse' button is
|
||||
clicked in the 'Save As' frame."""
|
||||
return _("Timeline File")
|
||||
|
||||
def get_report_generations(self):
|
||||
"""No generation options."""
|
||||
return (0, 0)
|
||||
f = BaseDoc.FontStyle()
|
||||
f.set_size(14)
|
||||
f.set_type_face(BaseDoc.FONT_SANS_SERIF)
|
||||
p = BaseDoc.ParagraphStyle()
|
||||
p.set_font(f)
|
||||
p.set_alignment(BaseDoc.PARA_ALIGN_CENTER)
|
||||
p.set_description(_("The style used for the title of the page."))
|
||||
default_style.add_style("TLG-Title",p)
|
||||
|
||||
def add_user_options(self):
|
||||
"""
|
||||
Override the base class add_user_options task to add a menu that allows
|
||||
the user to select the sort method.
|
||||
"""
|
||||
|
||||
self.sort_style = gtk.OptionMenu()
|
||||
self.sort_menu = gtk.Menu()
|
||||
|
||||
sort_functions = _get_sort_functions(Sort.Sort(self.database))
|
||||
for item in sort_functions:
|
||||
menuitem = gtk.MenuItem(item[0])
|
||||
menuitem.set_data('sort',item[1])
|
||||
menuitem.show()
|
||||
self.sort_menu.append(menuitem)
|
||||
|
||||
self.sort_style.set_menu(self.sort_menu)
|
||||
self.add_option(_('Sort by'),self.sort_style)
|
||||
|
||||
self.title_box = gtk.Entry()
|
||||
self.title_box.set_text(self.get_header(self.person.get_primary_name().get_name()))
|
||||
self.title_box.show()
|
||||
self.add_option(_('Title'),self.title_box)
|
||||
|
||||
def get_report_filters(self):
|
||||
return _get_report_filters(self.person)
|
||||
|
||||
def make_default_style(self):
|
||||
_make_default_style(self.default_style)
|
||||
|
||||
def make_report(self):
|
||||
|
||||
title = unicode(self.title_box.get_text())
|
||||
sort_func = self.sort_menu.get_active().get_data('sort')
|
||||
|
||||
try:
|
||||
MyReport = TimeLine(self.db, self.person,
|
||||
self.filter, title, sort_func, self.doc, self.target_path)
|
||||
MyReport.write_report()
|
||||
except Errors.FilterError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except Errors.ReportError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# point to centimeter convertion
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def pt2cm(val):
|
||||
return (float(val)/28.3465)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# entry point
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def report(database,person):
|
||||
"""
|
||||
report - task starts the report. The plugin system requires that the
|
||||
task be in the format of task that takes a database and a person as
|
||||
its arguments.
|
||||
"""
|
||||
TimeLineDialog(database,person)
|
||||
|
||||
def get_description():
|
||||
"""
|
||||
get_description - returns a descriptive name for the report. The plugin
|
||||
system uses this to provide a description in the report selector.
|
||||
"""
|
||||
return _("Generates a timeline graph.")
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Set up sane defaults for the book_item
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
_style_file = "timeline.xml"
|
||||
_style_name = "default"
|
||||
|
||||
_person_handle = ""
|
||||
_filter_num = 0
|
||||
_sort_func_num = 0
|
||||
_title_str = ""
|
||||
_options = ( _person_handle, _filter_num, _sort_func_num, _title_str )
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Book Item Options dialog
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
class TimeLineBareDialog(Report.BareReportDialog):
|
||||
|
||||
def __init__(self,database,person,opt,stl):
|
||||
|
||||
self.options = opt
|
||||
self.db = database
|
||||
if self.options[0]:
|
||||
self.person = self.db.get_person_from_handle(self.options[0])
|
||||
def get_report_filters(self,person):
|
||||
"""Set up the list of possible content filters."""
|
||||
if person:
|
||||
name = person.get_primary_name().get_name()
|
||||
handle = person.get_handle()
|
||||
else:
|
||||
self.person = person
|
||||
self.style_name = stl
|
||||
name = 'PERSON'
|
||||
handle = ''
|
||||
|
||||
Report.BareReportDialog.__init__(self,database,self.person)
|
||||
all = GenericFilter.GenericFilter()
|
||||
all.set_name(_("Entire Database"))
|
||||
all.add_rule(GenericFilter.Everyone([]))
|
||||
|
||||
self.filter_num = int(self.options[1])
|
||||
self.sort_func_num = int(self.options[2])
|
||||
self.title_str = self.options[3]
|
||||
self.new_person = None
|
||||
des = GenericFilter.GenericFilter()
|
||||
des.set_name(_("Descendants of %s") % name)
|
||||
des.add_rule(GenericFilter.IsDescendantOf([handle,1]))
|
||||
|
||||
self.filter_combo.set_history(self.filter_num)
|
||||
self.sort_style.set_history(self.sort_func_num)
|
||||
self.title_box.set_text(self.title_str)
|
||||
ans = GenericFilter.GenericFilter()
|
||||
ans.set_name(_("Ancestors of %s") % name)
|
||||
ans.add_rule(GenericFilter.IsAncestorOf([handle,1]))
|
||||
|
||||
self.window.run()
|
||||
com = GenericFilter.GenericFilter()
|
||||
com.set_name(_("People with common ancestor with %s") % name)
|
||||
com.add_rule(GenericFilter.HasCommonAncestorWith([handle]))
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Customization hooks
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def get_title(self):
|
||||
"""The window title for this dialog"""
|
||||
return "%s - GRAMPS Book" % (_("Timeline Graph"))
|
||||
return [all,des,ans,com]
|
||||
|
||||
def get_header(self, name):
|
||||
"""The header line at the top of the dialog contents"""
|
||||
return _("Timeline Graph for GRAMPS Book")
|
||||
def get_sort_functions(self,sort):
|
||||
return [
|
||||
(_("Birth Date"),sort.by_birthdate),
|
||||
(_("Name"),sort.by_last_name),
|
||||
]
|
||||
|
||||
def get_stylesheet_savefile(self):
|
||||
"""Where to save styles for this report."""
|
||||
return _style_file
|
||||
|
||||
def get_report_generations(self):
|
||||
"""No generations, no page breaks."""
|
||||
return (0, 0)
|
||||
|
||||
def add_user_options(self):
|
||||
def add_user_options(self,dialog):
|
||||
"""
|
||||
Override the base class add_user_options task to add a menu that allows
|
||||
the user to select the sort method.
|
||||
"""
|
||||
|
||||
self.sort_style = gtk.OptionMenu()
|
||||
sort_style = gtk.OptionMenu()
|
||||
self.sort_menu = gtk.Menu()
|
||||
|
||||
sort_functions = _get_sort_functions(Sort.Sort(self.db))
|
||||
for item in sort_functions:
|
||||
sort_functions = self.get_sort_functions(Sort.Sort(dialog.db))
|
||||
for item_index in range(len(sort_functions)):
|
||||
item = sort_functions[item_index]
|
||||
menuitem = gtk.MenuItem(item[0])
|
||||
menuitem.set_data('sort',item[1])
|
||||
menuitem.set_data('index',item_index)
|
||||
menuitem.show()
|
||||
self.sort_menu.append(menuitem)
|
||||
|
||||
self.sort_style.set_menu(self.sort_menu)
|
||||
self.add_option(_('Sort by'),self.sort_style)
|
||||
sort_style.set_menu(self.sort_menu)
|
||||
sort_style.set_history(self.options_dict['sortby'])
|
||||
|
||||
dialog.add_option(_('Sort by'),sort_style)
|
||||
|
||||
self.title_box = gtk.Entry()
|
||||
if self.options_dict['title']:
|
||||
self.title_box.set_text(self.options_dict['title'])
|
||||
else:
|
||||
self.title_box.set_text(dialog.get_header(dialog.person.get_primary_name().get_name()))
|
||||
self.title_box.show()
|
||||
self.add_option(_('Title'),self.title_box)
|
||||
dialog.add_option(_('Title'),self.title_box)
|
||||
|
||||
def make_default_style(self):
|
||||
_make_default_style(self.default_style)
|
||||
|
||||
def get_report_filters(self):
|
||||
return _get_report_filters(self.person)
|
||||
|
||||
def on_cancel(self, obj):
|
||||
pass
|
||||
|
||||
def on_ok_clicked(self, obj):
|
||||
"""The user is satisfied with the dialog choices. Parse all options
|
||||
and close the window."""
|
||||
|
||||
# Preparation
|
||||
self.parse_style_frame()
|
||||
|
||||
if self.new_person:
|
||||
self.person = self.new_person
|
||||
self.filter_num = self.filter_combo.get_history()
|
||||
self.sort_func_num = self.sort_style.get_history()
|
||||
self.title_str = unicode(self.title_box.get_text())
|
||||
|
||||
self.options = ( self.person.get_handle(), self.filter_num,
|
||||
self.sort_func_num, self.title_str )
|
||||
self.style_name = self.selected_style.get_name()
|
||||
def parse_user_options(self,dialog):
|
||||
"""
|
||||
Parses the custom options that we have added.
|
||||
"""
|
||||
self.options_dict['title'] = unicode(self.title_box.get_text())
|
||||
self.options_dict['sortby'] = self.sort_menu.get_active().get_data('index')
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Function to write Book Item
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
def write_book_item(database,person,doc,options,newpage=0):
|
||||
"""Write the Timeline Graph using options set.
|
||||
All user dialog has already been handled and the output file opened."""
|
||||
try:
|
||||
if options[0]:
|
||||
person = database.get_person_from_handle(options[0])
|
||||
filter_num = int(options[1])
|
||||
filters = _get_report_filters(person)
|
||||
afilter = filters[filter_num]
|
||||
sort_func_num = int(options[2])
|
||||
sort_functions = _get_sort_functions(Sort.Sort(database))
|
||||
sort_func = sort_functions[sort_func_num][1]
|
||||
title_str = options[3]
|
||||
return TimeLine(database, person,
|
||||
afilter, title_str, sort_func, doc, None, newpage )
|
||||
except Errors.ReportError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except Errors.FilterError, msg:
|
||||
(m1,m2) = msg.messages()
|
||||
ErrorDialog(m1,m2)
|
||||
except:
|
||||
import DisplayTrace
|
||||
DisplayTrace.DisplayTrace()
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Register the TimeLine report with the plugin system. The register_report
|
||||
# task of the Plugins module takes the following arguments.
|
||||
#
|
||||
# task - function that starts the task
|
||||
# name - Name of the report
|
||||
# status - alpha/beta/production
|
||||
# category - Category entry in the menu system.
|
||||
# author_name - Name of the author
|
||||
# author_email - Author's email address
|
||||
# description - function that returns the description of the report
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
from Plugins import register_report, register_book_item
|
||||
|
||||
from Plugins import register_report
|
||||
register_report(
|
||||
task=report,
|
||||
name=_("Timeline Graph"),
|
||||
status=(_("Beta")),
|
||||
category=_("Graphical Reports"),
|
||||
author_name="Donald N. Allingham",
|
||||
author_email="dallingham@users.sourceforge.net",
|
||||
description=get_description()
|
||||
)
|
||||
|
||||
# (name,category,options_dialog,write_book_item,options,style_name,style_file,make_default_style)
|
||||
register_book_item(
|
||||
_("Timeline Graph"),
|
||||
_("Graphics"),
|
||||
TimeLineBareDialog,
|
||||
write_book_item,
|
||||
_options,
|
||||
_style_name,
|
||||
_style_file,
|
||||
_make_default_style
|
||||
name = 'timeline',
|
||||
category = const.CATEGORY_DRAW,
|
||||
report_class = TimeLine,
|
||||
options_class = TimeLineOptions,
|
||||
modes = Report.MODE_GUI | Report.MODE_BKI | Report.MODE_CLI,
|
||||
translated_name = _("Timeline Graph"),
|
||||
status = _("Beta"),
|
||||
author_name = "Donald N. Allingham",
|
||||
author_email = "dallingham@users.sourceforge.net",
|
||||
description = _("Generates a timeline graph.")
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user