2008-01-03 Douglas S. Blank <dblank@cs.brynmawr.edu>
* src/ReportBase/_Constants.py: added QR_NOTE, QR_DATE * src/gen/lib/date.py: working on date math * src/plugins/AgeOnDate.py: new Quick View for age on date * src/plugins/DefaultGadgets.py: added Age on Date gadget * src/QuickReports.py: new constants * src/Simple/_SimpleTable.py: handle sort columns svn: r9698
This commit is contained in:
parent
73bf8719b8
commit
1e3ce27007
@ -1,3 +1,11 @@
|
|||||||
|
2008-01-03 Douglas S. Blank <dblank@cs.brynmawr.edu>
|
||||||
|
* src/ReportBase/_Constants.py: added QR_NOTE, QR_DATE
|
||||||
|
* src/gen/lib/date.py: working on date math
|
||||||
|
* src/plugins/AgeOnDate.py: new Quick View for age on date
|
||||||
|
* src/plugins/DefaultGadgets.py: added Age on Date gadget
|
||||||
|
* src/QuickReports.py: new constants
|
||||||
|
* src/Simple/_SimpleTable.py: handle sort columns
|
||||||
|
|
||||||
2008-01-03 Gary Burton <gary.burton@zen.co.uk>
|
2008-01-03 Gary Burton <gary.burton@zen.co.uk>
|
||||||
* src/Selectors/_SelectPerson.py: the select person dialog now allows a
|
* src/Selectors/_SelectPerson.py: the select person dialog now allows a
|
||||||
person to be selected by using the keyboard. This dialog really needs an
|
person to be selected by using the keyboard. This dialog really needs an
|
||||||
|
@ -59,7 +59,8 @@ import gtk
|
|||||||
from PluginUtils import Plugins
|
from PluginUtils import Plugins
|
||||||
from ReportBase import CATEGORY_QR_PERSON, CATEGORY_QR_FAMILY,\
|
from ReportBase import CATEGORY_QR_PERSON, CATEGORY_QR_FAMILY,\
|
||||||
CATEGORY_QR_EVENT, CATEGORY_QR_SOURCE,\
|
CATEGORY_QR_EVENT, CATEGORY_QR_SOURCE,\
|
||||||
CATEGORY_QR_PLACE, CATEGORY_QR_REPOSITORY
|
CATEGORY_QR_PLACE, CATEGORY_QR_REPOSITORY, \
|
||||||
|
CATEGORY_QR_NOTE, CATEGORY_QR_DATE
|
||||||
|
|
||||||
|
|
||||||
def create_quickreport_menu(category,dbstate,uistate,handle) :
|
def create_quickreport_menu(category,dbstate,uistate,handle) :
|
||||||
|
@ -71,3 +71,5 @@ CATEGORY_QR_EVENT = 2
|
|||||||
CATEGORY_QR_SOURCE = 3
|
CATEGORY_QR_SOURCE = 3
|
||||||
CATEGORY_QR_PLACE = 4
|
CATEGORY_QR_PLACE = 4
|
||||||
CATEGORY_QR_REPOSITORY = 5
|
CATEGORY_QR_REPOSITORY = 5
|
||||||
|
CATEGORY_QR_NOTE = 6
|
||||||
|
CATEGORY_QR_DATE = 7
|
||||||
|
@ -54,11 +54,13 @@ class SimpleTable:
|
|||||||
Set the columns
|
Set the columns
|
||||||
"""
|
"""
|
||||||
self.__columns = list(copy.copy(columns))
|
self.__columns = list(copy.copy(columns))
|
||||||
|
self.__sort_vals = [[] for i in range(len(self.__columns))]
|
||||||
|
|
||||||
def on_table_doubleclick(self, obj, path, view_column):
|
def on_table_doubleclick(self, obj, path, view_column):
|
||||||
"""
|
"""
|
||||||
Handle events on tables. obj is a treeview
|
Handle events on tables. obj is a treeview
|
||||||
"""
|
"""
|
||||||
|
from QuickReports import run_quick_report_by_name
|
||||||
from Editors import (EditPerson, EditEvent, EditFamily, EditSource,
|
from Editors import (EditPerson, EditEvent, EditFamily, EditSource,
|
||||||
EditPlace, EditRepository)
|
EditPlace, EditRepository)
|
||||||
selection = obj.get_selection()
|
selection = obj.get_selection()
|
||||||
@ -140,11 +142,16 @@ class SimpleTable:
|
|||||||
return True
|
return True
|
||||||
return False # didn't handle event
|
return False # didn't handle event
|
||||||
|
|
||||||
|
def row_sort_val(self, col, val):
|
||||||
|
"""
|
||||||
|
Adds a row of data to sort by.
|
||||||
|
"""
|
||||||
|
self.__sort_vals[col].append(val)
|
||||||
|
|
||||||
def row(self, *data):
|
def row(self, *data):
|
||||||
"""
|
"""
|
||||||
Add a row of data.
|
Add a row of data.
|
||||||
"""
|
"""
|
||||||
from QuickReports import run_quick_report_by_name
|
|
||||||
retval = []
|
retval = []
|
||||||
link = None
|
link = None
|
||||||
for item in data:
|
for item in data:
|
||||||
@ -256,19 +263,30 @@ class SimpleTable:
|
|||||||
treeview.connect('cursor-changed', self.on_table_click)
|
treeview.connect('cursor-changed', self.on_table_click)
|
||||||
renderer = gtk.CellRendererText()
|
renderer = gtk.CellRendererText()
|
||||||
types = [int] # index
|
types = [int] # index
|
||||||
|
cnt = 0
|
||||||
|
sort_data = []
|
||||||
|
sort_data_types = []
|
||||||
for col in self.__columns:
|
for col in self.__columns:
|
||||||
types.append(type(col))
|
types.append(type(col))
|
||||||
column = gtk.TreeViewColumn(col,renderer,text=model_index)
|
column = gtk.TreeViewColumn(col,renderer,text=model_index)
|
||||||
|
if self.__sort_vals[cnt] != []:
|
||||||
|
sort_data.append(self.__sort_vals[cnt])
|
||||||
|
column.set_sort_column_id(len(self.__columns) +
|
||||||
|
len(sort_data))
|
||||||
|
sort_data_types.append(int)
|
||||||
|
else:
|
||||||
column.set_sort_column_id(model_index)
|
column.set_sort_column_id(model_index)
|
||||||
treeview.append_column(column)
|
treeview.append_column(column)
|
||||||
#if model_index == sort_index:
|
#if model_index == sort_index:
|
||||||
# FIXME: what to set here?
|
# FIXME: what to set here?
|
||||||
model_index += 1
|
model_index += 1
|
||||||
|
cnt += 1
|
||||||
if self.title:
|
if self.title:
|
||||||
self.simpledoc.paragraph(self.title)
|
self.simpledoc.paragraph(self.title)
|
||||||
# Make a GUI to put the tree view in
|
# Make a GUI to put the tree view in
|
||||||
frame = gtk.Frame()
|
frame = gtk.Frame()
|
||||||
frame.add(treeview)
|
frame.add(treeview)
|
||||||
|
types += sort_data_types
|
||||||
model = gtk.ListStore(*types)
|
model = gtk.ListStore(*types)
|
||||||
treeview.set_model(model)
|
treeview.set_model(model)
|
||||||
iter = buffer.get_end_iter()
|
iter = buffer.get_end_iter()
|
||||||
@ -276,7 +294,7 @@ class SimpleTable:
|
|||||||
text_view.add_child_at_anchor(frame, anchor)
|
text_view.add_child_at_anchor(frame, anchor)
|
||||||
count = 0
|
count = 0
|
||||||
for data in self.__rows:
|
for data in self.__rows:
|
||||||
model.append(row=([count] + list(data)))
|
model.append(row=([count] + list(data) + [col[count] for col in sort_data]))
|
||||||
count += 1
|
count += 1
|
||||||
frame.show_all()
|
frame.show_all()
|
||||||
self.simpledoc.paragraph("")
|
self.simpledoc.paragraph("")
|
||||||
|
@ -259,18 +259,34 @@ class Date:
|
|||||||
days = d1[2] - d2[2]
|
days = d1[2] - d2[2]
|
||||||
months = d1[1] - d2[1]
|
months = d1[1] - d2[1]
|
||||||
years = d1[0] - d2[0]
|
years = d1[0] - d2[0]
|
||||||
if months < 0:
|
while days < 0:
|
||||||
|
months -= 1
|
||||||
|
days = 30 + days
|
||||||
|
while months < 0:
|
||||||
years -= 1
|
years -= 1
|
||||||
months = 12 + months
|
months = 12 + months
|
||||||
if days < 0:
|
if days > 31:
|
||||||
months -= 1
|
months += days / 31
|
||||||
days = 31 + days
|
days = days % 31
|
||||||
|
if months > 11:
|
||||||
|
years += months / 12
|
||||||
|
months = months % 12
|
||||||
|
if years < 0: # can happen with 0 based months/days
|
||||||
|
years = 0
|
||||||
|
months = 12 - months
|
||||||
|
days = 31 - days
|
||||||
return (years, months, days)
|
return (years, months, days)
|
||||||
elif type(other) in [tuple, list]:
|
elif type(other) in [tuple, list]:
|
||||||
return self.copy_offset_ymd(*map(lambda x: -x, other))
|
return self.copy_offset_ymd(*map(lambda x: -x, other))
|
||||||
else:
|
else:
|
||||||
raise AttributeError, "unknown date sub type: %s " % type(other)
|
raise AttributeError, "unknown date sub type: %s " % type(other)
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
return self.sortval < other.sortval
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
return self.sortval > other.sortval
|
||||||
|
|
||||||
def is_equal(self, other):
|
def is_equal(self, other):
|
||||||
"""
|
"""
|
||||||
Return 1 if the given Date instance is the same as the present
|
Return 1 if the given Date instance is the same as the present
|
||||||
|
104
src/plugins/AgeOnDate.py
Normal file
104
src/plugins/AgeOnDate.py
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#
|
||||||
|
# Gramps - a GTK+/GNOME based genealogy program
|
||||||
|
#
|
||||||
|
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||||
|
# Copyright (C) 2007-2008 Brian G. Matherly
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Display references for any object
|
||||||
|
"""
|
||||||
|
|
||||||
|
from Simple import SimpleAccess, SimpleDoc, SimpleTable
|
||||||
|
from gettext import gettext as _
|
||||||
|
from PluginUtils import register_quick_report
|
||||||
|
from ReportBase import CATEGORY_QR_DATE
|
||||||
|
import DateHandler
|
||||||
|
import gen.lib
|
||||||
|
import Config
|
||||||
|
|
||||||
|
def run(database, document, date):
|
||||||
|
"""
|
||||||
|
Display people probably alive and their ages on a particular date.
|
||||||
|
"""
|
||||||
|
# setup the simple access functions
|
||||||
|
sdb = SimpleAccess(database)
|
||||||
|
sdoc = SimpleDoc(document)
|
||||||
|
stab = SimpleTable(sdb, sdoc)
|
||||||
|
if not date.get_valid():
|
||||||
|
sdoc.paragraph("Date is not a valid date.")
|
||||||
|
return
|
||||||
|
# display the title
|
||||||
|
sdoc.title(_("People probably alive and their ages on %s") %
|
||||||
|
DateHandler.displayer.display(date))
|
||||||
|
sdoc.paragraph("\n")
|
||||||
|
stab.columns(_("Person"), _("Age")) # Actual Date makes column unicode
|
||||||
|
for person in sdb.all_people():
|
||||||
|
birth_date = None
|
||||||
|
birth_str = ""
|
||||||
|
birth_sort = 0
|
||||||
|
birth_ref = gen.lib.Person.get_birth_ref(person)
|
||||||
|
birth_date = get_event_date_from_ref(database, birth_ref)
|
||||||
|
death_ref = gen.lib.Person.get_death_ref(person)
|
||||||
|
death_date = get_event_date_from_ref(database, death_ref)
|
||||||
|
if birth_date:
|
||||||
|
if (birth_date.get_valid() and birth_date < date and
|
||||||
|
birth_date.get_year() != 0 and
|
||||||
|
((death_date == None) or (death_date > date))):
|
||||||
|
diff_tuple = (date - birth_date)
|
||||||
|
if ((death_date != None) or
|
||||||
|
(death_date == None and
|
||||||
|
diff_tuple[0] <= Config.get(Config.MAX_AGE_PROB_ALIVE))):
|
||||||
|
if diff_tuple[1] != 0:
|
||||||
|
birth_str = ((_("%d years") % diff_tuple[0])+ ", " +
|
||||||
|
(_("%d months") % diff_tuple[1]))
|
||||||
|
else:
|
||||||
|
birth_str = (_("%d years") % diff_tuple[0])
|
||||||
|
birth_sort = int(diff_tuple[0] * 12 + diff_tuple[1]) # months
|
||||||
|
if birth_str != "":
|
||||||
|
stab.row(person, birth_str)
|
||||||
|
stab.row_sort_val(1, birth_sort)
|
||||||
|
stab.write()
|
||||||
|
sdoc.paragraph("")
|
||||||
|
|
||||||
|
def get_event_date_from_ref(database, ref):
|
||||||
|
date = None
|
||||||
|
if ref:
|
||||||
|
handle = ref.get_reference_handle()
|
||||||
|
if handle:
|
||||||
|
event = database.get_event_from_handle(handle)
|
||||||
|
if event:
|
||||||
|
date = event.get_date_object()
|
||||||
|
return date
|
||||||
|
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Register the report
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------
|
||||||
|
|
||||||
|
register_quick_report(
|
||||||
|
name = 'ageondate',
|
||||||
|
category = CATEGORY_QR_DATE,
|
||||||
|
run_func = run,
|
||||||
|
translated_name = _("Age on Date"),
|
||||||
|
status = _("Stable"),
|
||||||
|
description= _("Display people and ages on a particular date"),
|
||||||
|
author_name="Douglas Blank",
|
||||||
|
author_email="dblank@cs.brynmawr.edu"
|
||||||
|
)
|
@ -551,6 +551,44 @@ class NewsGadget(Gadget):
|
|||||||
#print " after:", text
|
#print " after:", text
|
||||||
yield False, text
|
yield False, text
|
||||||
|
|
||||||
|
class AgeOnDateGadget(Gadget):
|
||||||
|
def init(self):
|
||||||
|
import gtk
|
||||||
|
# GUI setup:
|
||||||
|
self.tooltip = _("Enter a date, click Run")
|
||||||
|
vbox = gtk.VBox()
|
||||||
|
hbox = gtk.HBox()
|
||||||
|
# label, entry
|
||||||
|
description = gtk.TextView()
|
||||||
|
description.set_wrap_mode(gtk.WRAP_WORD)
|
||||||
|
buffer = description.get_buffer()
|
||||||
|
buffer.set_text(_("Enter a date in the entry below and click Run."
|
||||||
|
" This will compute the ages for everyone in your"
|
||||||
|
" Family Tree on that date. You can then sort by"
|
||||||
|
" the age column, and double-click the row to view"
|
||||||
|
" or edit."))
|
||||||
|
label = gtk.Label()
|
||||||
|
label.set_text(_("Date") + ":")
|
||||||
|
self.entry = gtk.Entry()
|
||||||
|
button = gtk.Button(_("Run"))
|
||||||
|
button.connect("clicked", self.run)
|
||||||
|
hbox.pack_start(label, False)
|
||||||
|
hbox.pack_start(self.entry, True)
|
||||||
|
vbox.pack_start(description, True)
|
||||||
|
vbox.pack_start(hbox, False)
|
||||||
|
vbox.pack_start(button, False)
|
||||||
|
self.gui.scrolledwindow.remove(self.gui.textview)
|
||||||
|
self.gui.scrolledwindow.add_with_viewport(vbox)
|
||||||
|
vbox.show_all()
|
||||||
|
|
||||||
|
def run(self, obj):
|
||||||
|
text = self.entry.get_text()
|
||||||
|
date = DateHandler.parser.parse(text)
|
||||||
|
run_quick_report_by_name(self.gui.dbstate,
|
||||||
|
self.gui.uistate,
|
||||||
|
'ageondate',
|
||||||
|
date)
|
||||||
|
|
||||||
|
|
||||||
register(type="gadget",
|
register(type="gadget",
|
||||||
name= "Top Surnames Gadget",
|
name= "Top Surnames Gadget",
|
||||||
@ -621,3 +659,11 @@ register(type="gadget",
|
|||||||
title=_("News"),
|
title=_("News"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register(type="gadget",
|
||||||
|
name="Age on Date Gadget",
|
||||||
|
tname=_("Age on Date Gadget"),
|
||||||
|
height=200,
|
||||||
|
content = AgeOnDateGadget,
|
||||||
|
title=_("Age on Date"),
|
||||||
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user