Added David's birth order changing

svn: r470
This commit is contained in:
Don Allingham 2001-10-14 20:47:38 +00:00
parent 694886dfa8
commit bd0bcae0e4
6 changed files with 395 additions and 46 deletions

View File

@ -1,8 +1,44 @@
* Allow for multiple notes. A tabbed interface would be really useful,
since there are no titles for notes. Not all objects would necessarily
need multiple notes. Determine which ones should and shouldn't.
* Drag and drop inside a gallery to allow for reordering of media objects.
This would allow for the elimination of the rather lame "Make Primary"
option.
* Drag and drop should display the icon we are dragging instead of just
the default icon. Nautilus does this very effectively, and GTK has
support for this.
* Provide an "import" of a gramps package. Not too difficult to do this,
since there is already a ReadTarFile class which will unpackage the
file. Needs have an interface built around it.
* Catch uncaught exceptions at the top level, notifiy the user, and
store the results in a file that can be emailed. Have the start of
this with the gramps.err file, but most users don't realize that
this file has been created. Some type of notification is needed.
* Allow an image to be dropped onto the image box on the first tab of
the EditPerson dialog. This would make that image the first in the
photo list as well.
* Speed up the reading of the database. The python XML routines are not
as fast as I would like, and it can take a minute or so to read a
large database. This is way too slow.
* Progress report on the WebPage report generation. I've been told that
for large databases, this can take up to about 10 minutes. A progress
bar would give people an indication of where they are in the process,
and an indication that gramps has not locked up on them.
* GEDCOM import should use the GEDCOM ID values as the GRAMPS ids if the
current database is empty. This would help us in the future if we want
to do an incremental update. Having the GEDCOM ID and the gramps ID
match up would be a good indication that these are the same people.
For example, @F001@ would become F001.
* Completely revamp the merge utility.
* Finish the generic load of revision control interfaces to allow a
revision control plugin system. Most of the work is already done.
* Extend the gramps package exporting to export to a ISO-9660 CD-ROM
image. Thumbnails would need to be exported for this as well, since
the CD-ROM would be read-only after burning.
* Disable the save buttons if gramps database is marked read-only. Disable
the adding of media objects as well, since this will cause gramps to
try to create a thumbnail in a readonly database.
* Dates do not understand alternate calendars
* There are no sophisticated functions at all yet, such as merging of
databases or finding duplicate people.
* There are no logic rules yet, such as warning if a parent's birthday
is after a child's.
* OpenOffice zip file is not handled very gracefully. Uses the "system"
call to generate the zip file using the hard coded path of /usr/bin/zip.
Python 2.0 provides a zip interface, so this may need to hold off until

View File

@ -48,6 +48,7 @@ import Config
from RelLib import *
import RelImage
import ImageSelect
import sort
_ = intl.gettext
@ -618,6 +619,16 @@ class EditPerson:
if not self.person.getBirth().are_equal(self.birth):
self.person.setBirth(self.birth)
# Update each of the families child lists to reflect any
# change in ordering due to the new birth date
family = self.person.getMainFamily()
if (family):
new_order = reorder_child_list(self.person,family.getChildList())
family.setChildList(new_order)
for (family, rel1, rel2) in self.person.getAltFamilyList():
new_order = reorder_child_list(self.person,family.getChildList())
family.setChildList(new_order)
self.death.setDate(self.ddate.get_text())
dplace_obj = utils.get_place_from_list(self.dpcombo)
@ -795,3 +806,69 @@ def cancel_callback(a):
def src_changed(parent):
parent.lists_changed = 1
#-------------------------------------------------------------------------
#
# birth_dates_in_order
#
# Check any *valid* birthdates in the list to insure that they are in
# numerically increasing order.
#
#-------------------------------------------------------------------------
def birth_dates_in_order(list):
inorder = 1
prev_date = "00000000"
for i in range(len(list)):
child = list[i]
bday = child.getBirth().getDateObj()
child_date = sort.build_sort_birth(bday)
if (child_date == "99999999"):
continue
if (prev_date <= child_date): # <= allows for twins
prev_date = child_date
else:
inorder = 0
return inorder
#-------------------------------------------------------------------------
#
# reorder_child_list
#
# Reorder the child list to put the specified person in his/her
# correct birth orde. Only check *valid* birthdates. Move the person
# as short a distance as possible.
#
#-------------------------------------------------------------------------
def reorder_child_list(person, list):
if (birth_dates_in_order(list)):
return(list)
# Build the person's date string once
person_bday = sort.build_sort_birth(person.getBirth().getDateObj())
# First, see if the person needs to be moved forward in the list
index = list.index(person)
target = index
for i in range(index-1, -1, -1):
other_bday = sort.build_sort_birth(list[i].getBirth().getDateObj())
if (other_bday == "99999999"):
continue;
if (person_bday < other_bday):
target = i
# Now try moving to a later position in the list
if (target == index):
for i in range(index, len(list)):
other_bday = sort.build_sort_birth(list[i].getBirth().getDateObj())
if (other_bday == "99999999"):
continue;
if (person_bday > other_bday):
target = i
# Actually need to move? Do it now.
if (target != index):
list.remove(person)
list.insert(target,person)
return list

View File

@ -1204,6 +1204,10 @@ class Family:
"""returns the list of children"""
return self.Children
def setChildList(self, list):
"""sets the list of children"""
self.Children = list
def getMarriage(self):
"""returns the marriage event of the Family. Obsolete"""
for e in self.EventList:

View File

@ -1882,6 +1882,7 @@
<class>GtkCList</class>
<name>child_list</name>
<height>80</height>
<tooltip>Click column headers to sort. When sorted by birth date, drag and drop to reorder children.</tooltip>
<can_focus>True</can_focus>
<signal>
<name>select_row</name>
@ -1893,23 +1894,77 @@
<handler>on_child_list_button_press_event</handler>
<last_modification_time>Thu, 21 Dec 2000 20:47:47 GMT</last_modification_time>
</signal>
<columns>6</columns>
<column_widths>210,60,85,150,75,50</column_widths>
<signal>
<name>click_column</name>
<handler>on_child_list_click_column</handler>
<last_modification_time>Mon, 08 Oct 2001 20:29:49 GMT</last_modification_time>
</signal>
<signal>
<name>row_move</name>
<handler>on_child_list_row_move</handler>
<last_modification_time>Mon, 08 Oct 2001 20:31:41 GMT</last_modification_time>
</signal>
<columns>7</columns>
<column_widths>210,60,85,150,75,50,25</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<widget>
<class>GtkLabel</class>
<class>GtkHBox</class>
<child_name>CList:title</child_name>
<name>label13</name>
<label>Name</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<name>hbox34</name>
<homogeneous>True</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkHBox</class>
<name>hbox35</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label256</name>
<label>Name</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkArrow</class>
<name>cNameSort</name>
<width>10</width>
<height>10</height>
<visible>False</visible>
<arrow_type>GTK_ARROW_DOWN</arrow_type>
<shadow_type>GTK_SHADOW_OUT</shadow_type>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>5</padding>
<expand>False</expand>
<fill>True</fill>
</child>
</widget>
</widget>
</widget>
<widget>
@ -1939,16 +1994,59 @@
</widget>
<widget>
<class>GtkLabel</class>
<class>GtkHBox</class>
<child_name>CList:title</child_name>
<name>label15</name>
<label>Birth Date</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<name>hbox36</name>
<homogeneous>True</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkHBox</class>
<name>hbox37</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label257</name>
<label>Birth Date</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkArrow</class>
<name>cDateSort</name>
<width>10</width>
<height>10</height>
<arrow_type>GTK_ARROW_DOWN</arrow_type>
<shadow_type>GTK_SHADOW_OUT</shadow_type>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
<widget>
@ -1976,6 +2074,19 @@
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label15</name>
<label>Birth Order</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
</widget>

View File

@ -123,6 +123,9 @@ canvas = None
sort_column = 5
sort_direct = SORT_ASCENDING
DataFilter = Filter.Filter("")
c_birth_order = 6
c_sort_column = c_birth_order
c_sort_direct = SORT_ASCENDING
#-------------------------------------------------------------------------
#
@ -1930,9 +1933,129 @@ def on_spouse_list_select_row(obj,row,b,c):
#-------------------------------------------------------------------------
#
#
# on_child_list_click_column
#
# Called when the user selects a column header on the person_list window.
# Change the sort function (column 0 is the name column, and column 2 is
# the birthdate column), set the arrows on the labels to the correct
# orientation, and then call apply_filter to redraw the list
#
#-------------------------------------------------------------------------
def on_child_list_click_column(clist,column):
if column == 0:
child_change_sort(clist,0,gtop.get_widget("cNameSort"))
elif (column == 3) or (column == 6):
child_change_sort(clist,6,gtop.get_widget("cDateSort"))
else:
return
sort_child_list(clist)
if id2col.has_key(active_child):
row = clist.find_row_from_data(id2col[active_child])
clist.moveto(row)
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def child_change_sort(clist,column,arrow):
global c_sort_direct
global c_sort_column
cNameArrow.hide()
cDateArrow.hide()
arrow.show()
if c_sort_column == column:
if c_sort_direct == SORT_DESCENDING:
c_sort_direct = SORT_ASCENDING
arrow.set(GTK.ARROW_DOWN,2)
else:
c_sort_direct = SORT_DESCENDING
arrow.set(GTK.ARROW_UP,2)
else:
c_sort_direct = SORT_ASCENDING
c_sort_column = column
clist.set_sort_type(c_sort_direct)
clist.set_sort_column(c_sort_column)
clist.set_reorderable(c_sort_column == c_birth_order)
def sort_child_list(clist):
clist.freeze()
clist.sort()
clist.thaw()
#-------------------------------------------------------------------------
#
# on_child_list_row_move
#
# Validate whether or not this child can be moved within the clist.
# This routine is called in the middle of the clist's callbacks, so
# the state can be confusing. If the code is being debugged, the
# display at this point shows that the list has been reordered when in
# actuality it hasn't. All accesses to the clist data structure
# reference the state just prior to the "move".
#
# This routine must keep/compute its own list indices as the functions
# list.remove(), list.insert(), list.reverse() etc. do not affect the
# values returned from the list.index() routine.
#
#-------------------------------------------------------------------------
def on_child_list_row_move(clist,fm,to):
family = clist.get_data("f")
# Create a list based upon the current order of the clist
clist_order = []
for i in range(clist.rows):
clist_order = clist_order + [clist.get_row_data(i)]
child = clist_order[fm]
# This function deals with ascending order lists. Convert if
# necessary.
if (c_sort_direct == SORT_DESCENDING):
clist_order.reverse()
max_index = len(clist_order) - 1
fm = max_index - fm
to = max_index - to
# Create a new list to match the requested order
desired_order = clist_order[:fm] + clist_order[fm+1:]
desired_order = desired_order[:to] + [child] + desired_order[to:]
# Check birth date order in the new list
if (EditPerson.birth_dates_in_order(desired_order) == 0):
clist.emit_stop_by_name("row_move")
GnomeWarningDialog(_("Invalid move. Children must be ordered by birth date."))
return
# OK, this birth order works too. Update the family data structures.
family.setChildList(desired_order)
# Build a mapping of child item to list position. This would not
# be necessary if indices worked properly
i = 0
new_order = {}
for tmp in desired_order:
new_order[tmp] = i
i = i + 1
# Convert the original list back to whatever ordering is being
# used by the clist itself.
if (c_sort_direct == SORT_DESCENDING):
clist_order.reverse()
# Update the clist indices so any change of sorting works
i = 0
for tmp in clist_order:
clist.set_text(i, c_birth_order, "%2d"%new_order[tmp])
i = i + 1
# Need to save the changed order
utils.modified()
def on_open_activate(obj):
wFs = libglade.GladeXML(const.gladeFile, "dbopen")
wFs.signal_autoconnect({
@ -2875,6 +2998,10 @@ def display_marriage(family):
active_child = None
i = 0
clist.set_sort_type(c_sort_direct)
clist.set_sort_column(c_sort_column)
clist.set_reorderable(c_sort_column == c_birth_order)
if family != None:
if active_person.getGender() == Person.male:
active_spouse = family.getMother()
@ -2882,7 +3009,7 @@ def display_marriage(family):
active_spouse = family.getFather()
child_list = family.getChildList()
child_list.sort(sort.by_birthdate)
# List is already sorted by birth date
attr = ""
for child in child_list:
status = _("Unknown")
@ -2917,7 +3044,7 @@ def display_marriage(family):
attr = attr + "P"
clist.append([Config.nameof(child),child.getId(),\
gender,birthday(child),status,attr])
gender,birthday(child),status,attr,"%2d"%i])
clist.set_row_data(i,child)
i=i+1
if i != 0:
@ -2925,6 +3052,8 @@ def display_marriage(family):
clist.select_row(0,0)
else:
fv_prev.set_sensitive(0)
clist.set_data("f",family)
clist.sort()
else:
fv_prev.set_sensitive(0)
@ -3304,6 +3433,7 @@ def main(arg):
global person_list, source_list, place_list, canvas, media_list
global topWindow, preview
global nameArrow, dateArrow, deathArrow
global cNameArrow, cDateArrow
global mid, mtype, mdesc, mpath, mdetails
rc_parse(const.gtkrcFile)
@ -3345,6 +3475,8 @@ def main(arg):
('application/x-rootwin-drop',0,1)]
media_list.drag_source_set(GDK.BUTTON1_MASK|GDK.BUTTON3_MASK,t,GDK.ACTION_COPY)
media_list.drag_dest_set(DEST_DEFAULT_ALL,t,GDK.ACTION_COPY|GDK.ACTION_MOVE)
cNameArrow = gtop.get_widget("cNameSort")
cDateArrow = gtop.get_widget("cDateSort")
person_list.set_column_visibility(5,0)
person_list.set_column_visibility(6,0)
person_list.set_column_visibility(7,0)
@ -3377,6 +3509,8 @@ def main(arg):
"on_canvas1_event" : on_canvas1_event,
"on_child_list_button_press_event" : on_child_list_button_press_event,
"on_child_list_select_row" : on_child_list_select_row,
"on_child_list_click_column" : on_child_list_click_column,
"on_child_list_row_move" : on_child_list_row_move,
"on_choose_parents_clicked" : on_choose_parents_clicked,
"on_contents_activate" : on_contents_activate,
"on_default_person_activate" : on_default_person_activate,
@ -3436,7 +3570,10 @@ def main(arg):
person_list.set_column_visibility(1,Config.id_visible)
notebook.set_show_tabs(Config.usetabs)
gtop.get_widget("child_list").set_column_visibility(4,Config.show_detail)
child_list = gtop.get_widget("child_list")
child_list.set_column_visibility(4,Config.show_detail)
child_list.set_column_visibility(6,0)
child_list.set_column_visibility(7,0)
if arg != None:
read_file(arg)

View File

@ -46,7 +46,7 @@ def build_sort_birth(n):
d = n.start.day
if d == -1:
d = 99
return "%04d%2d%2d" % (y,m,d)
return "%04d%02d%02d" % (y,m,d)
#-------------------------------------------------------------------------
#
@ -63,7 +63,7 @@ def build_sort_death(n):
d = n.start.day
if d == -1:
d = 99
return "%04d%2d%2d" % (y,m,d)
return "%04d%02d%02d" % (y,m,d)
#-------------------------------------------------------------------------
#
@ -158,19 +158,3 @@ def by_last_name(first, second) :
#-------------------------------------------------------------------------
def by_last_name_backwards(first, second) :
return by_last_name(second,first)
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def by_birthdate(first, second) :
date1 = first.getBirth().getDateObj()
date2 = second.getBirth().getDateObj()
val = compare_dates(date1,date2)
if val == 0:
return by_last_name(first,second)
return val