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:
		| @@ -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> | ||||
| 	* src/Selectors/_SelectPerson.py: the select person dialog now allows a | ||||
| 	person to be selected by using the keyboard. This dialog really needs an | ||||
|   | ||||
| @@ -59,7 +59,8 @@ import gtk | ||||
| from PluginUtils import Plugins | ||||
| from ReportBase  import CATEGORY_QR_PERSON, CATEGORY_QR_FAMILY,\ | ||||
|                         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) : | ||||
|   | ||||
| @@ -71,3 +71,5 @@ CATEGORY_QR_EVENT      = 2 | ||||
| CATEGORY_QR_SOURCE     = 3 | ||||
| CATEGORY_QR_PLACE      = 4 | ||||
| CATEGORY_QR_REPOSITORY = 5 | ||||
| CATEGORY_QR_NOTE       = 6 | ||||
| CATEGORY_QR_DATE       = 7 | ||||
|   | ||||
| @@ -54,11 +54,13 @@ class SimpleTable: | ||||
|         Set the 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): | ||||
|         """ | ||||
|         Handle events on tables. obj is a treeview | ||||
|         """ | ||||
|         from QuickReports import run_quick_report_by_name | ||||
|         from Editors import (EditPerson, EditEvent, EditFamily, EditSource, | ||||
|                              EditPlace, EditRepository) | ||||
|         selection = obj.get_selection() | ||||
| @@ -140,11 +142,16 @@ class SimpleTable: | ||||
|                 return True | ||||
|         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): | ||||
|         """ | ||||
|         Add a row of data. | ||||
|         """ | ||||
|         from QuickReports import run_quick_report_by_name | ||||
|         retval = []  | ||||
|         link   = None | ||||
|         for item in data: | ||||
| @@ -256,19 +263,30 @@ class SimpleTable: | ||||
|             treeview.connect('cursor-changed', self.on_table_click) | ||||
|             renderer = gtk.CellRendererText() | ||||
|             types = [int] # index | ||||
|             cnt = 0 | ||||
|             sort_data = [] | ||||
|             sort_data_types = [] | ||||
|             for col in self.__columns: | ||||
|                 types.append(type(col)) | ||||
|                 column = gtk.TreeViewColumn(col,renderer,text=model_index) | ||||
|                 column.set_sort_column_id(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) | ||||
|                 treeview.append_column(column) | ||||
|                 #if model_index == sort_index: | ||||
|                 # FIXME: what to set here?     | ||||
|                 model_index += 1 | ||||
|                 cnt += 1 | ||||
|             if self.title: | ||||
|                 self.simpledoc.paragraph(self.title) | ||||
|             # Make a GUI to put the tree view in | ||||
|             frame = gtk.Frame() | ||||
|             frame.add(treeview) | ||||
|             types += sort_data_types | ||||
|             model = gtk.ListStore(*types) | ||||
|             treeview.set_model(model) | ||||
|             iter = buffer.get_end_iter() | ||||
| @@ -276,7 +294,7 @@ class SimpleTable: | ||||
|             text_view.add_child_at_anchor(frame, anchor) | ||||
|             count = 0 | ||||
|             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 | ||||
|             frame.show_all() | ||||
|             self.simpledoc.paragraph("") | ||||
|   | ||||
| @@ -259,18 +259,34 @@ class Date: | ||||
|             days = d1[2] - d2[2] | ||||
|             months = d1[1] - d2[1] | ||||
|             years = d1[0] - d2[0] | ||||
|             if months < 0: | ||||
|             while days < 0: | ||||
|                 months -= 1 | ||||
|                 days = 30 + days | ||||
|             while months < 0: | ||||
|                 years -= 1 | ||||
|                 months = 12 + months | ||||
|             if days < 0: | ||||
|                 months -= 1 | ||||
|                 days = 31 + days | ||||
|             if days > 31: | ||||
|                 months += days / 31 | ||||
|                 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) | ||||
|         elif type(other) in [tuple, list]: | ||||
|             return self.copy_offset_ymd(*map(lambda x: -x, other)) | ||||
|         else: | ||||
|             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): | ||||
|         """ | ||||
|         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 | ||||
|         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",  | ||||
|          name= "Top Surnames Gadget",  | ||||
| @@ -621,3 +659,11 @@ register(type="gadget", | ||||
|          title=_("News"), | ||||
|          ) | ||||
|  | ||||
| register(type="gadget",  | ||||
|          name="Age on Date Gadget",  | ||||
|          tname=_("Age on Date Gadget"),  | ||||
|          height=200, | ||||
|          content = AgeOnDateGadget, | ||||
|          title=_("Age on Date"), | ||||
|          ) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user