GEDCOM improvements, Find improvements
svn: r621
This commit is contained in:
parent
a2faca3f16
commit
fc8c83168d
@ -17,7 +17,15 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
"""
|
||||
Provides a TextDoc based interface to the AbiWord document format.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Imported Modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import os
|
||||
import base64
|
||||
|
||||
@ -25,26 +33,40 @@ from TextDoc import *
|
||||
from latin_utf8 import latin_to_utf8
|
||||
import const
|
||||
import string
|
||||
import utils
|
||||
cnv = utils.fl2txt
|
||||
from utils import fl2txt
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Attemp to import the Python Imaging Library
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
try:
|
||||
import PIL.Image
|
||||
no_pil = 0
|
||||
except:
|
||||
no_pil = 1
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Class Definitions
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class AbiWordDoc(TextDoc):
|
||||
"""AbiWord document generator. Inherits from the TextDoc generic
|
||||
document interface class."""
|
||||
|
||||
def __init__(self,styles,type,orientation):
|
||||
"""Initializes the AbiWordDoc class, calling the __init__ routine
|
||||
of the parent TextDoc class"""
|
||||
TextDoc.__init__(self,styles,type,orientation)
|
||||
self.f = None
|
||||
self.level = 0
|
||||
self.new_page = 0
|
||||
|
||||
def open(self,filename):
|
||||
|
||||
"""Opens the document, writing the necessary header information.
|
||||
AbiWord uses an XML format, so the document format is pretty easy
|
||||
to understand"""
|
||||
if filename[-4:] != ".abw":
|
||||
self.filename = "%s.abw" % filename
|
||||
else:
|
||||
@ -59,19 +81,20 @@ class AbiWordDoc(TextDoc):
|
||||
self.f.write('orientation="portrait" ')
|
||||
else:
|
||||
self.f.write('orientation="landscape" ')
|
||||
self.f.write('width="%s" ' % cnv("%.4f",self.width/2.54))
|
||||
self.f.write('height="%s" ' % cnv("%.4f",self.height/2.54))
|
||||
self.f.write('width="%s" ' % fl2txt("%.4f",self.width/2.54))
|
||||
self.f.write('height="%s" ' % fl2txt("%.4f",self.height/2.54))
|
||||
self.f.write('units="inch" page-scale="1.000000"/>\n')
|
||||
self.f.write('<section ')
|
||||
rmargin = float(self.rmargin)/2.54
|
||||
lmargin = float(self.lmargin)/2.54
|
||||
self.f.write('props="page-margin-right:%sin; ' % \
|
||||
cnv("%.4f",rmargin))
|
||||
fl2txt("%.4f",rmargin))
|
||||
self.f.write('page-margin-left:%sin"' % \
|
||||
cnv("%.4f",lmargin))
|
||||
fl2txt("%.4f",lmargin))
|
||||
self.f.write('>\n')
|
||||
|
||||
def close(self):
|
||||
"""Write the trailing information and closes the file"""
|
||||
self.f.write('</section>\n')
|
||||
if len(self.photo_list) > 0:
|
||||
self.f.write('<data>\n')
|
||||
@ -119,8 +142,8 @@ class AbiWordDoc(TextDoc):
|
||||
|
||||
self.f.write('<image dataid="')
|
||||
self.f.write(tag)
|
||||
width = cnv("%.3f",act_width)
|
||||
height = cnv("%.3f",act_height)
|
||||
width = fl2txt("%.3f",act_width)
|
||||
height = fl2txt("%.3f",act_height)
|
||||
self.f.write('" props="width:%sin; ' % width)
|
||||
self.f.write('height:%sin"/>' % height)
|
||||
|
||||
@ -136,9 +159,9 @@ class AbiWordDoc(TextDoc):
|
||||
self.f.write('text-align:center;')
|
||||
else:
|
||||
self.f.write('text-align:justify;')
|
||||
rmargin = cnv("%.4f",float(style.get_right_margin())/2.54)
|
||||
lmargin = cnv("%.4f",float(style.get_left_margin())/2.54)
|
||||
indent = cnv("%.4f",float(style.get_first_indent())/2.54)
|
||||
rmargin = fl2txt("%.4f",float(style.get_right_margin())/2.54)
|
||||
lmargin = fl2txt("%.4f",float(style.get_left_margin())/2.54)
|
||||
indent = fl2txt("%.4f",float(style.get_first_indent())/2.54)
|
||||
self.f.write(' margin-right:%sin;' % rmargin)
|
||||
self.f.write(' margin-left:%sin;' % lmargin)
|
||||
self.f.write(' tabstops:%sin/L;' % lmargin)
|
||||
@ -193,7 +216,7 @@ class AbiWordDoc(TextDoc):
|
||||
self.f.write('; font-style:italic')
|
||||
color = font.get_color()
|
||||
if color != (0,0,0):
|
||||
self.f.write('; color:%2x%2x%2x' % color)
|
||||
self.f.write('; color:%02x%02x%02x' % color)
|
||||
if font.get_underline():
|
||||
self.f.write('; text-decoration:underline')
|
||||
self.f.write('">')
|
||||
@ -212,7 +235,7 @@ class AbiWordDoc(TextDoc):
|
||||
self.f.write('; font-style:italic')
|
||||
color = font.get_color()
|
||||
if color != (0,0,0):
|
||||
self.f.write('; color:%2x%2x%2x' % color)
|
||||
self.f.write('; color:%02x%02x%02x' % color)
|
||||
if font.get_underline():
|
||||
self.f.write('; text-decoration:underline')
|
||||
self.f.write('">')
|
||||
|
@ -18,6 +18,10 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Provides the interface to allow a person to add a media object to the database.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
@ -124,7 +128,6 @@ class AddMediaObject:
|
||||
see if the file exists. If it does, the imgae is loaded into
|
||||
the preview window.
|
||||
"""
|
||||
|
||||
filename = self.file_text.get_text()
|
||||
basename = os.path.basename(filename)
|
||||
(root,ext) = os.path.splitext(basename)
|
||||
|
@ -17,6 +17,10 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
"""
|
||||
The AddSpouse module provides the AddSpouse class that allows the user to
|
||||
add a new spouse to the active person.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -17,6 +17,10 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
"""
|
||||
The AddrEdit module provides the AddressEditor class. This provides a
|
||||
mechanism for the user to edit address information.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -33,6 +37,7 @@ import libglade
|
||||
import const
|
||||
import utils
|
||||
import Date
|
||||
import RelLib
|
||||
|
||||
from intl import gettext
|
||||
_ = gettext
|
||||
@ -44,7 +49,7 @@ _ = gettext
|
||||
#-------------------------------------------------------------------------
|
||||
class AddressEditor:
|
||||
"""
|
||||
Displays a dialog that allows the user to edit a address.
|
||||
Displays a dialog that allows the user to edit an address.
|
||||
"""
|
||||
def __init__(self,parent,addr):
|
||||
"""
|
||||
@ -110,7 +115,7 @@ class AddressEditor:
|
||||
def ok_clicked(self,obj):
|
||||
"""
|
||||
Called when the OK button is pressed. Gets data from the
|
||||
form and updates the Address data structure
|
||||
form and updates the Address data structure.
|
||||
"""
|
||||
date = self.addr_start.get_text()
|
||||
street = self.street.get_text()
|
||||
@ -122,7 +127,7 @@ class AddressEditor:
|
||||
priv = self.priv.get_active()
|
||||
|
||||
if self.addr == None:
|
||||
self.addr = Address()
|
||||
self.addr = RelLib.Address()
|
||||
self.addr.setSourceRefList(self.srcreflist)
|
||||
self.parent.plist.append(self.addr)
|
||||
|
||||
@ -154,27 +159,7 @@ class AddressEditor:
|
||||
self.check(self.addr.getNote,self.addr.setNote,note)
|
||||
self.check(self.addr.getPrivacy,self.addr.setPrivacy,priv)
|
||||
|
||||
# if self.addr.getState() != state:
|
||||
# self.addr.setState(state)
|
||||
# self.parent.lists_changed = 1
|
||||
# if self.addr.getStreet() != street:
|
||||
# self.addr.setStreet(street)
|
||||
# self.parent.lists_changed = 1
|
||||
# if self.addr.getCountry() != country:
|
||||
# self.addr.setCountry(country)
|
||||
# self.parent.lists_changed = 1
|
||||
# if self.addr.getCity() != city:
|
||||
# self.addr.setCity(city)
|
||||
# self.parent.lists_changed = 1
|
||||
# if self.addr.getPostal() != postal:
|
||||
# self.addr.setPostal(postal)
|
||||
# self.parent.lists_changed = 1
|
||||
# if self.addr.getNote() != note:
|
||||
# self.addr.setNote(note)
|
||||
# self.parent.lists_changed = 1
|
||||
# if self.addr.getPrivacy() != priv:
|
||||
# self.addr.setPrivacy(priv)
|
||||
# self.parent.lists_changed = 1
|
||||
|
||||
def src_changed(parent):
|
||||
"""Sets the lists_changed flag of the parent object. Used as a callback
|
||||
to the source editor, so the source editor can indicate a change."""
|
||||
parent.lists_changed = 1
|
||||
|
@ -17,6 +17,10 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
"""
|
||||
The AttrEdit module provides the AddressEditor class. This provides a
|
||||
mechanism for the user to edit address information.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -44,8 +48,18 @@ _ = gettext
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class AttributeEditor:
|
||||
|
||||
"""
|
||||
Displays a dialog that allows the user to edit an attribute.
|
||||
"""
|
||||
def __init__(self,parent,attrib,title,list):
|
||||
"""
|
||||
Displays the dialog box.
|
||||
|
||||
parent - The class that called the Address editor.
|
||||
attrib - The attribute that is to be edited
|
||||
title - The title of the dialog box
|
||||
list - list of options for the pop down menu
|
||||
"""
|
||||
self.parent = parent
|
||||
self.attrib = attrib
|
||||
self.top = libglade.GladeXML(const.dialogFile, "attr_edit")
|
||||
@ -84,16 +98,20 @@ class AttributeEditor:
|
||||
self.window.set_data("o",self)
|
||||
self.top.signal_autoconnect({
|
||||
"destroy_passed_object" : utils.destroy_passed_object,
|
||||
"on_attr_edit_ok_clicked" : self.on_attrib_edit_ok_clicked,
|
||||
"on_attr_edit_ok_clicked" : self.on_ok_clicked,
|
||||
"on_combo_insert_text" : utils.combo_insert_text,
|
||||
"on_source_clicked" : self.on_attrib_source_clicked
|
||||
"on_source_clicked" : self.on_source_clicked
|
||||
})
|
||||
|
||||
def on_attrib_source_clicked(self,obj):
|
||||
def on_source_clicked(self,obj):
|
||||
"""Displays the SourceSelector, allowing sources to be edited"""
|
||||
Sources.SourceSelector(self.srcreflist,self.parent,src_changed)
|
||||
|
||||
def on_attrib_edit_ok_clicked(self,obj):
|
||||
|
||||
def on_ok_clicked(self,obj):
|
||||
"""
|
||||
Called when the OK button is pressed. Gets data from the
|
||||
form and updates the Attribute data structure.
|
||||
"""
|
||||
type = self.type_field.get_text()
|
||||
value = self.value_field.get_text()
|
||||
note = self.note_field.get_chars(0,-1)
|
||||
@ -104,28 +122,27 @@ class AttributeEditor:
|
||||
self.attrib.setSourceRefList(self.srcreflist)
|
||||
self.parent.alist.append(self.attrib)
|
||||
|
||||
self.update_attrib(type,value,note,priv)
|
||||
self.update(type,value,note,priv)
|
||||
|
||||
self.parent.redraw_attr_list()
|
||||
utils.destroy_passed_object(obj)
|
||||
|
||||
def update_attrib(self,type,value,note,priv):
|
||||
|
||||
if self.attrib.getType() != const.save_pattr(type):
|
||||
self.attrib.setType(const.save_pattr(type))
|
||||
self.parent.lists_changed = 1
|
||||
|
||||
if self.attrib.getValue() != value:
|
||||
self.attrib.setValue(value)
|
||||
self.parent.lists_changed = 1
|
||||
|
||||
if self.attrib.getNote() != note:
|
||||
self.attrib.setNote(note)
|
||||
self.parent.lists_changed = 1
|
||||
|
||||
if self.attrib.getPrivacy() != priv:
|
||||
self.attrib.setPrivacy(priv)
|
||||
def check(self,get,set,data):
|
||||
"""Compares a data item, updates if necessary, and sets the
|
||||
parents lists_changed flag"""
|
||||
if get() != data:
|
||||
set(data)
|
||||
self.parent.lists_changed = 1
|
||||
|
||||
def update(self,type,value,note,priv):
|
||||
"""Compares the data items, and updates if necessary"""
|
||||
ntype = const.save_pattr(type)
|
||||
self.check(self.attrib.getType,self.attrib.setType,ntype)
|
||||
self.check(self.attrib.getValue,self.attrib.setValue,value)
|
||||
self.check(self.attrib.getNote,self.attrib.setNote,note)
|
||||
self.check(self.attrib.getPrivacy,self.attrib.setPrivacy,priv)
|
||||
|
||||
def src_changed(parent):
|
||||
"""Sets the lists_changed flag of the parent object. Used as a callback
|
||||
to the source editor, so the source editor can indicate a change."""
|
||||
parent.lists_changed = 1
|
||||
|
@ -61,7 +61,7 @@ _AM9_32_43 = ((15 * _HALAKIM_PER_HOUR) + 589)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# Conversion tables
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
monthsPerYear = [
|
||||
@ -76,7 +76,7 @@ yearOffset = [
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# Tasks
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -99,6 +99,7 @@ def sdn_to_french(sdn):
|
||||
|
||||
|
||||
def sdn_to_gregorian(sdn):
|
||||
"""Converts an SDN number to a gregorial date"""
|
||||
if sdn <= 0:
|
||||
return (0,0,0)
|
||||
|
||||
@ -133,7 +134,7 @@ def sdn_to_gregorian(sdn):
|
||||
return (year,month,day)
|
||||
|
||||
def gregorian_to_sdn(iyear,imonth,iday):
|
||||
|
||||
"""Converts a gregorian date to an SDN number"""
|
||||
# check for invalid dates
|
||||
if iyear==0 or iyear<-4714 or imonth<=0 or imonth>12 or iday<=0 or iday>31:
|
||||
return 0
|
||||
@ -164,6 +165,7 @@ def gregorian_to_sdn(iyear,imonth,iday):
|
||||
|
||||
|
||||
def sdn_to_julian(sdn):
|
||||
"""Converts an SDN number to a Julian date"""
|
||||
if sdn <= 0 :
|
||||
return (0,0,0)
|
||||
|
||||
@ -193,6 +195,7 @@ def sdn_to_julian(sdn):
|
||||
return (year,month,day)
|
||||
|
||||
def julian_to_sdn(iyear,imonth,iday):
|
||||
"""Converts a Julian calendar date to an SDN number"""
|
||||
|
||||
# check for invalid dates
|
||||
if iyear==0 or iyear<-4713 or imonth<=0 or imonth>12 or iday<=0 or iday>31:
|
||||
@ -329,6 +332,7 @@ def FindStartOfYear(year):
|
||||
return (pMetonicCycle, pMetonicYear, pMoladDay, pMoladHalakim, pTishri1)
|
||||
|
||||
def sdn_to_jewish(sdn):
|
||||
"""Converts an SDN number to a Julian calendar date"""
|
||||
|
||||
if sdn <= _H_SDN_OFFSET :
|
||||
return (0,0,0)
|
||||
@ -439,6 +443,7 @@ def sdn_to_jewish(sdn):
|
||||
|
||||
|
||||
def jewish_to_sdn(year, month, day):
|
||||
"""Converts a Jewish calendar date to an SDN number"""
|
||||
if year <= 0 or day <= 0 or day > 30 :
|
||||
return 0
|
||||
|
||||
|
@ -461,12 +461,18 @@ class SingleDate:
|
||||
retval = str(self.year)
|
||||
elif self.year == UNDEF:
|
||||
retval = _mname[self.month]
|
||||
else:
|
||||
retval = "%s %d" % (_mname[self.month],self.year)
|
||||
else:
|
||||
try:
|
||||
retval = "%s %d" % (_mname[self.month],self.year)
|
||||
except:
|
||||
retval = "**** %d %d %d ****" % (self.year,self.month,self.day)
|
||||
elif self.month == UNDEF:
|
||||
retval = str(self.year)
|
||||
else:
|
||||
month = _mname[self.month]
|
||||
try:
|
||||
month = _mname[self.month]
|
||||
except:
|
||||
month = "<ILLEGAL MONTH>"
|
||||
if self.year == UNDEF:
|
||||
retval = "%s %d, ????" % (month,self.day)
|
||||
else:
|
||||
@ -830,6 +836,8 @@ class SingleDate:
|
||||
else:
|
||||
self.setMonthVal(matches[1])
|
||||
self.setYearVal(matches[2])
|
||||
if self.getMonth() > 13:
|
||||
raise Date.Error
|
||||
return 1
|
||||
|
||||
match = SingleDate.fmt3.match(text)
|
||||
|
@ -1222,7 +1222,7 @@ def birth_dates_in_order(list):
|
||||
for i in range(len(list)):
|
||||
child = list[i]
|
||||
bday = child.getBirth().getDateObj()
|
||||
child_date = sort.build_sort_event(bday)
|
||||
child_date = sort.build_sort_date(bday)
|
||||
if (child_date == "99999999"):
|
||||
continue
|
||||
if (prev_date <= child_date): # <= allows for twins
|
||||
@ -1246,13 +1246,13 @@ def reorder_child_list(person, list):
|
||||
return(list)
|
||||
|
||||
# Build the person's date string once
|
||||
person_bday = sort.build_sort_event(person.getBirth().getDateObj())
|
||||
person_bday = sort.build_sort_date(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_event(list[i].getBirth().getDateObj())
|
||||
other_bday = sort.build_sort_date(list[i].getBirth().getDateObj())
|
||||
if (other_bday == "99999999"):
|
||||
continue;
|
||||
if (person_bday < other_bday):
|
||||
@ -1261,7 +1261,7 @@ def reorder_child_list(person, list):
|
||||
# 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_event(list[i].getBirth().getDateObj())
|
||||
other_bday = sort.build_sort_date(list[i].getBirth().getDateObj())
|
||||
if (other_bday == "99999999"):
|
||||
continue;
|
||||
if (person_bday > other_bday):
|
||||
|
@ -50,17 +50,17 @@ class Find:
|
||||
})
|
||||
|
||||
self.top = self.xml.get_widget("find")
|
||||
self.entry = self.xml.get_widget("entry1")
|
||||
self.combo = self.xml.get_widget("combo")
|
||||
self.entry = self.xml.get_widget("entry")
|
||||
if Config.autocomp:
|
||||
self.entry.connect_object("insert-text",utils.combo_insert_text,self.combo)
|
||||
self.combo.disable_activate()
|
||||
self.nlist = [("","")]
|
||||
for n in plist:
|
||||
n1 = n.getPrimaryName().getName()
|
||||
n2 = string.lower(n1)
|
||||
self.nlist.append((n2,n1))
|
||||
self.nlist.sort()
|
||||
self.entry.connect("insert-text",self.insert_text)
|
||||
|
||||
self.next = self.xml.get_widget("next")
|
||||
nlist = [""]
|
||||
for n in plist:
|
||||
nlist.append(n.getPrimaryName().getName())
|
||||
nlist.sort()
|
||||
self.combo.set_popdown_strings(nlist)
|
||||
self.top.editable_enters(self.entry)
|
||||
|
||||
def find_next(self):
|
||||
@ -133,3 +133,84 @@ class Find:
|
||||
def on_prev_clicked(self,obj):
|
||||
"""Callback for dialog box that causes the previous person to be found"""
|
||||
self.find_prev()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Sets up a delayed (0.005 sec) handler for text completion. Text
|
||||
# completion cannot be handled directly in this routine because, for
|
||||
# some reason, the select_region() function doesn't work when called
|
||||
# from signal handlers. Go figure.
|
||||
#
|
||||
# Thanks to iain@nodata.demon.co.uk (in mail from 1999) for the idea
|
||||
# to use a timer to get away from the problems with signal handlers
|
||||
# and the select_region function.
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def insert_text(self,entry,new_text,new_text_len,i_dont_care):
|
||||
# One time setup to clear selected region when user moves on
|
||||
if (not entry.get_data("signal_set")):
|
||||
entry.set_data("signal_set",1)
|
||||
entry.signal_connect("focus_out_event", self.lost_focus, entry)
|
||||
|
||||
# Nuke the current timer if the user types fast enough
|
||||
timer = entry.get_data("timer");
|
||||
if (timer):
|
||||
gtk.timeout_remove(timer)
|
||||
|
||||
# Setup a callback timer so we can operate outside of a signal handler
|
||||
timer = gtk.timeout_add(5, self.timer_callback, entry)
|
||||
entry.set_data("timer", timer);
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# The entry box entry field lost focus. Go clear any selection. Why
|
||||
# this form of a select_region() call works in a signal handler and
|
||||
# the other form doesn't is a mystery.
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def lost_focus(self,entry,a,b):
|
||||
entry.select_region(0, 0)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# The workhorse routine of file completion. This routine grabs the
|
||||
# current text of the entry box, and grubs through the list item
|
||||
# looking for any case insensitive matches. This routine relies on
|
||||
# public knowledge of the GtkEntry data structure, not on any private
|
||||
# data.
|
||||
#
|
||||
# These three completion routines have only one gramps specific hook,
|
||||
# and can be easily ported to any program.
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def timer_callback(self,entry):
|
||||
# Clear any timer
|
||||
timer = entry.get_data("timer");
|
||||
if (timer):
|
||||
gtk.timeout_remove(timer)
|
||||
|
||||
# Get the user's text
|
||||
typed = entry.get_text()
|
||||
if (not typed):
|
||||
return
|
||||
typed_lc = string.lower(typed)
|
||||
|
||||
# Walk the GtkList in the entry box
|
||||
for nl,n in self.nlist:
|
||||
if (not nl):
|
||||
continue
|
||||
|
||||
# If equal, no need to add any text
|
||||
if (typed_lc == nl):
|
||||
return
|
||||
|
||||
# If typed text is a substring of the label text, then fill in
|
||||
# the entry field with the full text (and correcting
|
||||
# capitalization), and then select all the characters that
|
||||
# don't match. With the user's enxt keystroke these will be
|
||||
# replaced if they are incorrect.
|
||||
if (string.find(nl,typed_lc) == 0):
|
||||
entry.set_text(n)
|
||||
entry.set_position(len(typed))
|
||||
entry.select_region(len(typed), -1)
|
||||
return
|
||||
|
@ -328,7 +328,8 @@ class MediaView:
|
||||
oref.setReference(photo)
|
||||
try:
|
||||
id = photo.getId()
|
||||
name = RelImage.import_media_object(tfile,self.path,id)
|
||||
path = self.db.getSavePath()
|
||||
name = RelImage.import_media_object(tfile,path,id)
|
||||
if name != None and name != "":
|
||||
photo.setPath(name)
|
||||
except:
|
||||
|
@ -149,7 +149,6 @@ class PlaceView:
|
||||
|
||||
for a in self.sort_arrow:
|
||||
a.hide()
|
||||
arrow = self.sort_arrow[column]
|
||||
if self.sort_col == column:
|
||||
if self.sort_direct == GTK.SORT_DESCENDING:
|
||||
self.sort_direct = GTK.SORT_ASCENDING
|
||||
|
@ -2656,7 +2656,7 @@ information.</text>
|
||||
<title_color>125,104,74</title_color>
|
||||
<text_color>0,0,0</text_color>
|
||||
<background_color>225,219,197</background_color>
|
||||
<logo_background_color>191,191,191</logo_background_color>
|
||||
<logo_background_color>225,220,197</logo_background_color>
|
||||
<textbox_color>255,255,255</textbox_color>
|
||||
<logo_image>gramps.png</logo_image>
|
||||
<watermark_image>splash.jpg</watermark_image>
|
||||
@ -2674,7 +2674,7 @@ information.</text>
|
||||
<title>Researcher Information</title>
|
||||
<title_color>125,104,74</title_color>
|
||||
<background_color>225,220,197</background_color>
|
||||
<logo_background_color>191,191,191</logo_background_color>
|
||||
<logo_background_color>225,220,197</logo_background_color>
|
||||
<logo_image>gramps.png</logo_image>
|
||||
|
||||
<widget>
|
||||
@ -3200,7 +3200,7 @@ contribute.
|
||||
|
||||
Please enjoy using GRAMPS.</text>
|
||||
<background_color>225,220,197</background_color>
|
||||
<logo_background_color>191,191,191</logo_background_color>
|
||||
<logo_background_color>225,220,197</logo_background_color>
|
||||
<textbox_color>255,255,255</textbox_color>
|
||||
<text_color>0,0,0</text_color>
|
||||
<title_color>125,104,74</title_color>
|
||||
|
@ -152,45 +152,19 @@
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>Placeholder</class>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>GtkCombo</class>
|
||||
<name>combo</name>
|
||||
<value_in_list>False</value_in_list>
|
||||
<ok_if_empty>True</ok_if_empty>
|
||||
<case_sensitive>False</case_sensitive>
|
||||
<use_arrows>True</use_arrows>
|
||||
<use_arrows_always>False</use_arrows_always>
|
||||
<items></items>
|
||||
<class>GtkEntry</class>
|
||||
<name>entry</name>
|
||||
<can_focus>True</can_focus>
|
||||
<has_focus>True</has_focus>
|
||||
<editable>True</editable>
|
||||
<text_visible>True</text_visible>
|
||||
<text_max_length>0</text_max_length>
|
||||
<text></text>
|
||||
<child>
|
||||
<padding>10</padding>
|
||||
<expand>True</expand>
|
||||
<fill>True</fill>
|
||||
</child>
|
||||
|
||||
<widget>
|
||||
<class>GtkEntry</class>
|
||||
<child_name>GtkCombo:entry</child_name>
|
||||
<name>entry1</name>
|
||||
<can_focus>True</can_focus>
|
||||
<has_focus>True</has_focus>
|
||||
<signal>
|
||||
<name>insert_text</name>
|
||||
<handler>on_combo_insert_text</handler>
|
||||
<object>combo</object>
|
||||
<last_modification_time>Wed, 12 Dec 2001 01:27:32 GMT</last_modification_time>
|
||||
</signal>
|
||||
<editable>True</editable>
|
||||
<text_visible>True</text_visible>
|
||||
<text_max_length>0</text_max_length>
|
||||
<text></text>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
<widget>
|
||||
<class>Placeholder</class>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -1,5 +1,5 @@
|
||||
[Desktop Entry]
|
||||
Name=Gramps
|
||||
Name=Genealogy (Gramps)
|
||||
Name[sv]=Gramps
|
||||
Comment=Genealogy Program
|
||||
Comment[sv]=Ett släktforskningsprogram
|
||||
|
Binary file not shown.
@ -1289,8 +1289,8 @@ def redisplay_person_list(person):
|
||||
gender,bday.getQuoteDate(),
|
||||
dday.getQuoteDate(),
|
||||
sort.build_sort_name(name),
|
||||
sort.build_sort_event(bday),
|
||||
sort.build_sort_event(dday)])
|
||||
sort.build_sort_date(bday),
|
||||
sort.build_sort_date(dday)])
|
||||
|
||||
person_list.set_row_data(0,pos)
|
||||
|
||||
@ -1302,8 +1302,8 @@ def redisplay_person_list(person):
|
||||
gender,bday.getQuoteDate(),
|
||||
dday.getQuoteDate(),
|
||||
sort.build_sort_name(name),
|
||||
sort.build_sort_event(bday),
|
||||
sort.build_sort_event(dday)])
|
||||
sort.build_sort_date(bday),
|
||||
sort.build_sort_date(dday)])
|
||||
|
||||
person_list.set_row_data(0,pos2)
|
||||
|
||||
@ -1720,8 +1720,8 @@ def apply_filter():
|
||||
|
||||
bday = person.getBirth().getDateObj()
|
||||
dday = person.getDeath().getDateObj()
|
||||
sort_bday = sort.build_sort_event(bday)
|
||||
sort_dday = sort.build_sort_event(dday)
|
||||
sort_bday = sort.build_sort_date(bday)
|
||||
sort_dday = sort.build_sort_date(dday)
|
||||
qbday = bday.getQuoteDate()
|
||||
qdday = dday.getQuoteDate()
|
||||
pid = person.getId()
|
||||
|
@ -48,6 +48,7 @@ active_person = None
|
||||
db = None
|
||||
styles = StyleSheet()
|
||||
style_sheet_list = None
|
||||
topDialog = None
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -48,6 +48,7 @@ active_person = None
|
||||
db = None
|
||||
styles = StyleSheet()
|
||||
style_sheet_list = None
|
||||
topDialog = None
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@ -277,7 +278,6 @@ def report(database,person):
|
||||
|
||||
global active_person
|
||||
global topDialog
|
||||
global glade_file
|
||||
global db
|
||||
global style_sheet_list
|
||||
|
||||
|
@ -45,6 +45,7 @@ active_person = None
|
||||
db = None
|
||||
styles = StyleSheet()
|
||||
style_sheet_list = None
|
||||
topDialog = None
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -78,29 +78,6 @@ fromtoRegexp = re.compile(r"\s*FROM\s+@#D([^@]+)@\s*(.*)\s+TO\s+@#D([^@]+)@\s*(.
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def find_file(fullname,altpath):
|
||||
if os.path.isfile(fullname):
|
||||
type = utils.get_mime_type(fullname)
|
||||
if type[0:6] != "image/":
|
||||
return ""
|
||||
else:
|
||||
return fullname
|
||||
other = altpath + os.sep + os.path.basename(fullname)
|
||||
if os.path.isfile(other):
|
||||
type = utils.get_mime_type(other)
|
||||
if type[0:6] != "image/":
|
||||
return ""
|
||||
else:
|
||||
return other
|
||||
else:
|
||||
return ""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
def importData(database, filename):
|
||||
|
||||
global callback
|
||||
@ -199,6 +176,41 @@ class GedcomParser:
|
||||
|
||||
self.update(self.file_obj,file)
|
||||
self.code = 0
|
||||
self.search_paths = []
|
||||
|
||||
try:
|
||||
f = open("/etc/fstab","r")
|
||||
|
||||
for line in f.readlines():
|
||||
paths = string.split(line)
|
||||
if len(paths) < 3:
|
||||
continue
|
||||
first = string.strip(paths[0])
|
||||
if first[0] == '#':
|
||||
continue
|
||||
if string.upper(paths[2]) in ["VFAT","FAT","NTFS"]:
|
||||
self.search_paths.append(paths[1])
|
||||
f.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
def find_file(self,fullname,altpath):
|
||||
fullname = string.replace(fullname,'\\','/')
|
||||
if os.path.isfile(fullname):
|
||||
return fullname
|
||||
other = os.path.join(altpath,os.path.basename(fullname))
|
||||
if os.path.isfile(other):
|
||||
return other
|
||||
if len(fullname) > 3:
|
||||
if fullname[1] == ':':
|
||||
fullname = fullname[2:]
|
||||
for path in self.search_paths:
|
||||
other = os.path.join(path,os.path.basename(fullname))
|
||||
if os.path.isfile(other):
|
||||
return other
|
||||
return ""
|
||||
else:
|
||||
return ""
|
||||
|
||||
def update(self,field,text):
|
||||
field.set_text(text)
|
||||
@ -311,7 +323,6 @@ class GedcomParser:
|
||||
def parse_record(self):
|
||||
while 1:
|
||||
matches = self.get_next()
|
||||
|
||||
if matches[2] == "FAM":
|
||||
if self.fam_count % 10 == 0:
|
||||
self.update(self.families_obj,str(self.fam_count))
|
||||
@ -333,9 +344,9 @@ class GedcomParser:
|
||||
self.indi_count = self.indi_count + 1
|
||||
self.person = self.db.findPerson(matches[1],self.pmap)
|
||||
self.parse_individual()
|
||||
elif matches[2] == "SUBM":
|
||||
elif matches[2] in ["SUBM","SUBN"]:
|
||||
self.ignore_sub_junk(1)
|
||||
elif matches[1] == "SUBM":
|
||||
elif matches[1] in ["SUBM","SUBN"]:
|
||||
self.ignore_sub_junk(1)
|
||||
elif matches[2] == "SOUR":
|
||||
self.parse_source(matches[1],1)
|
||||
@ -354,13 +365,36 @@ class GedcomParser:
|
||||
noteobj.set(text + self.parse_continue_data())
|
||||
self.parse_note_data(1)
|
||||
elif matches[2] == "OBJE":
|
||||
self.ignore_sub_junk(2)
|
||||
self.ignore_sub_junk(1)
|
||||
elif matches[1] == "TRLR":
|
||||
self.backup()
|
||||
return
|
||||
else:
|
||||
self.barf(1)
|
||||
|
||||
def parse_cause(self,event,level):
|
||||
while 1:
|
||||
matches = self.get_next()
|
||||
if int(matches[0]) < level:
|
||||
self.backup()
|
||||
return
|
||||
elif matches[1] == "SOUR":
|
||||
source_ref = SourceRef()
|
||||
if matches[2] and matches[2][0] != "@":
|
||||
self.localref = self.localref + 1
|
||||
ref = "gsr%d" % self.localref
|
||||
s = self.db.findSource(ref,self.smap)
|
||||
source_ref.setBase(s)
|
||||
s.setTitle('Imported Source #%d' % self.localref)
|
||||
s.setNote(matches[2] + self.parse_continue_data())
|
||||
self.ignore_sub_junk(2)
|
||||
else:
|
||||
source_ref.setBase(self.db.findSource(matches[2],self.smap))
|
||||
self.parse_source_reference(source_ref,level+1)
|
||||
event.addSourceRef(source_ref)
|
||||
else:
|
||||
self.barf(1)
|
||||
|
||||
def parse_note_data(self,level):
|
||||
while 1:
|
||||
matches = self.get_next()
|
||||
@ -507,13 +541,17 @@ class GedcomParser:
|
||||
self.person.setPafUid(matches[2])
|
||||
elif matches[1] == "ALIA":
|
||||
aka = Name()
|
||||
names = nameRegexp.match(matches[2]).groups()
|
||||
if names[0]:
|
||||
aka.setFirstName(names[0])
|
||||
if names[1]:
|
||||
aka.setSurname(names[1])
|
||||
if names[2]:
|
||||
aka.setSuffix(names[2])
|
||||
match = nameRegexp.match(matches[2])
|
||||
if match:
|
||||
names = match.groups()
|
||||
if names[0]:
|
||||
aka.setFirstName(names[0])
|
||||
if names[1]:
|
||||
aka.setSurname(names[1])
|
||||
if names[2]:
|
||||
aka.setSuffix(names[2])
|
||||
else:
|
||||
aka.setFirstName(matches[2])
|
||||
self.person.addAlternateName(aka)
|
||||
elif matches[1] == "OBJE":
|
||||
if matches[2] and matches[2][0] == '@':
|
||||
@ -621,7 +659,7 @@ class GedcomParser:
|
||||
self.person.addAttribute(attr)
|
||||
else:
|
||||
self.person.addEvent(event)
|
||||
elif matches[1] in ["AFN","CHAN","REFN","SOUR"]:
|
||||
elif matches[1] in ["AFN","CHAN","REFN","SOUR","ASSO"]:
|
||||
self.ignore_sub_junk(2)
|
||||
elif matches[1] in ["ANCI","DESI","RIN","RFN"]:
|
||||
pass
|
||||
@ -716,11 +754,10 @@ class GedcomParser:
|
||||
url.set_path(file)
|
||||
url.set_description(title)
|
||||
self.person.addUrl(url)
|
||||
elif form in photo_types:
|
||||
path = find_file(file,self.dir_path)
|
||||
else:
|
||||
path = self.find_file(file,self.dir_path)
|
||||
if path == "":
|
||||
self.warn(_("Could not import %s: either the file could not be found, or it was not a valid image")\
|
||||
% file + "\n")
|
||||
self.warn(_("Could not import %s") % file + "\n")
|
||||
else:
|
||||
photo = Photo()
|
||||
photo.setPath(path)
|
||||
@ -730,9 +767,6 @@ class GedcomParser:
|
||||
oref = ObjectRef()
|
||||
oref.setReference(photo)
|
||||
self.person.addPhoto(oref)
|
||||
else:
|
||||
self.warn(_("Could not import %s: currently an unknown file type") % \
|
||||
file + "\n")
|
||||
|
||||
def parse_source_object(self,source,level):
|
||||
form = ""
|
||||
@ -755,11 +789,10 @@ class GedcomParser:
|
||||
else:
|
||||
self.barf(level+1)
|
||||
|
||||
if form in photo_types:
|
||||
path = find_file(file,self.dir_path)
|
||||
if form:
|
||||
path = self.find_file(file,self.dir_path)
|
||||
if path == "":
|
||||
self.warn(_("Could not import %s: either the file could not be found, or it was not a valid image")\
|
||||
% file + "\n")
|
||||
self.warn(_("Could not import %s") % file + "\n")
|
||||
else:
|
||||
photo = Photo()
|
||||
photo.setPath(path)
|
||||
@ -769,9 +802,6 @@ class GedcomParser:
|
||||
oref = ObjectRef()
|
||||
oref.setReference(photo)
|
||||
source.addPhoto(oref)
|
||||
else:
|
||||
self.warn(_("Could not import %s: currently an unknown file type") % \
|
||||
file + "\n")
|
||||
|
||||
def parse_family_object(self,level):
|
||||
form = ""
|
||||
@ -794,10 +824,10 @@ class GedcomParser:
|
||||
else:
|
||||
self.barf(level+1)
|
||||
|
||||
if form in photo_types:
|
||||
path = find_file(file,self.dir_path)
|
||||
if form:
|
||||
path = self.find_file(file,self.dir_path)
|
||||
if path == "":
|
||||
self.warn("Could not import %s: the file could not be found\n" % file)
|
||||
self.warn(_("Could not import %s") % file)
|
||||
else:
|
||||
photo = Photo()
|
||||
photo.setPath(path)
|
||||
@ -807,8 +837,6 @@ class GedcomParser:
|
||||
oref = ObjectRef()
|
||||
oref.setReference(photo)
|
||||
self.family.addPhoto(photo)
|
||||
else:
|
||||
self.warn("Could not import %s: current an unknown file type\n" % file)
|
||||
|
||||
def parse_residence(self,address,level):
|
||||
while 1:
|
||||
@ -888,7 +916,7 @@ class GedcomParser:
|
||||
ord.setDateObj(self.extract_date(matches[2]))
|
||||
elif matches[1] == "FAMC":
|
||||
ord.setFamily(self.db.findFamily(matches[2],self.fmap))
|
||||
elif matches[1] == ["PLAC", "STAT", "SOUR", "NOTE" ]:
|
||||
elif matches[1] in ["PLAC", "STAT", "SOUR", "NOTE" ]:
|
||||
self.ignore_sub_junk(level+1)
|
||||
else:
|
||||
self.barf(level+1)
|
||||
@ -914,9 +942,8 @@ class GedcomParser:
|
||||
name = matches[2]
|
||||
event.setName(name)
|
||||
elif matches[1] == "DATE":
|
||||
foo = self.extract_date(matches[2])
|
||||
event.setDateObj(foo)
|
||||
elif matches[1] == ["TIME","ADDR","AGE","AGNC","STAT","TEMP","OBJE"]:
|
||||
event.setDateObj(self.extract_date(matches[2]))
|
||||
elif matches[1] in ["TIME","ADDR","AGE","AGNC","STAT","TEMP","OBJE"]:
|
||||
self.ignore_sub_junk(level+1)
|
||||
elif matches[1] == "SOUR":
|
||||
source_ref = SourceRef()
|
||||
@ -951,6 +978,7 @@ class GedcomParser:
|
||||
elif matches[1] == "CAUS":
|
||||
info = matches[2] + self.parse_continue_data()
|
||||
event.setCause(info)
|
||||
self.parse_cause(event,level+1)
|
||||
elif matches[1] == "NOTE":
|
||||
info = matches[2] + self.parse_continue_data()
|
||||
if note == "":
|
||||
@ -979,7 +1007,7 @@ class GedcomParser:
|
||||
break
|
||||
elif matches[1] == "DATE":
|
||||
event.setDateObj(self.extract_date(matches[2]))
|
||||
elif matches[1] == ["TIME","ADDR","AGE","AGNC","STAT","TEMP","OBJE"]:
|
||||
elif matches[1] in ["TIME","ADDR","AGE","AGNC","STAT","TEMP","OBJE"]:
|
||||
self.ignore_sub_junk(level+1)
|
||||
elif matches[1] == "SOUR":
|
||||
source_ref = SourceRef()
|
||||
@ -1017,9 +1045,13 @@ class GedcomParser:
|
||||
self.placemap[val] = place
|
||||
event.setPlace(place)
|
||||
self.ignore_sub_junk(level+1)
|
||||
elif matches[1] == "TYPE":
|
||||
# eventually do something intelligent here
|
||||
pass
|
||||
elif matches[1] == "CAUS":
|
||||
info = matches[2] + self.parse_continue_data()
|
||||
event.setCause(info)
|
||||
self.parse_cause(event,level+1)
|
||||
elif matches[1] == "NOTE":
|
||||
info = matches[2] + self.parse_continue_data()
|
||||
if note == "":
|
||||
@ -1072,7 +1104,7 @@ class GedcomParser:
|
||||
else:
|
||||
name = matches[2]
|
||||
attr.setName(name)
|
||||
elif matches[1] == ["CAUS", "DATE","TIME","ADDR","AGE","AGNC","STAT","TEMP","OBJE"]:
|
||||
elif matches[1] in ["CAUS", "DATE","TIME","ADDR","AGE","AGNC","STAT","TEMP","OBJE"]:
|
||||
self.ignore_sub_junk(level+1)
|
||||
elif matches[1] == "SOUR":
|
||||
source_ref = SourceRef()
|
||||
@ -1127,7 +1159,11 @@ class GedcomParser:
|
||||
event.setName(matches[2])
|
||||
elif matches[1] == "DATE":
|
||||
event.setDateObj(self.extract_date(matches[2]))
|
||||
elif matches[1] == ["TIME","AGE","AGNC","CAUS","ADDR","STAT","TEMP","HUSB","WIFE","OBJE"]:
|
||||
elif matches[1] == "CAUS":
|
||||
info = matches[2] + self.parse_continue_data()
|
||||
event.setCause(info)
|
||||
self.parse_cause(event,level+1)
|
||||
elif matches[1] in ["TIME","AGE","AGNC","ADDR","STAT","TEMP","HUSB","WIFE","OBJE"]:
|
||||
self.ignore_sub_junk(level+1)
|
||||
elif matches[1] == "SOUR":
|
||||
source_ref = SourceRef()
|
||||
@ -1318,22 +1354,12 @@ class GedcomParser:
|
||||
self.update(self.created_obj,matches[2])
|
||||
elif matches[1] == "VERS":
|
||||
self.update(self.version_obj,matches[2])
|
||||
elif matches[1] == "CORP":
|
||||
elif matches[1] in ["CORP","DATA","SUBM","SUBN","COPR","FILE","LANG"]:
|
||||
self.ignore_sub_junk(2)
|
||||
elif matches[1] == "DATA":
|
||||
self.ignore_sub_junk(2)
|
||||
elif matches[1] == "SUBM":
|
||||
pass
|
||||
elif matches[1] == "SUBN":
|
||||
pass
|
||||
elif matches[1] == "DEST":
|
||||
if genby == "GRAMPS":
|
||||
self.gedsource = self.gedmap.get_from_source_tag(matches[2])
|
||||
self.broken_conc = self.gedsource.get_conc()
|
||||
elif matches[1] == "FILE":
|
||||
self.ignore_sub_junk(2)
|
||||
elif matches[1] == "COPR":
|
||||
pass
|
||||
elif matches[1] == "CHAR":
|
||||
if matches[2] == "UNICODE" or matches[2] == "UTF-8" or \
|
||||
matches[2] == "UTF8":
|
||||
@ -1348,8 +1374,6 @@ class GedcomParser:
|
||||
self.ignore_sub_junk(2)
|
||||
elif matches[1] == "_SCHEMA":
|
||||
self.parse_ftw_schema(2)
|
||||
elif matches[1] == "LANG":
|
||||
pass
|
||||
elif matches[1] == "PLAC":
|
||||
self.parse_place_form(2)
|
||||
elif matches[1] == "DATE":
|
||||
@ -1496,6 +1520,7 @@ class GedcomParser:
|
||||
dateobj.set(data)
|
||||
else:
|
||||
dateobj.set(text)
|
||||
|
||||
return dateobj
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,25 +17,39 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
"""
|
||||
Provides sorting routines for use in GRAMPS. Since these functions are
|
||||
intended to provide fast sorting, they tend to bypass access methods,
|
||||
and directly use class members. For this reason, care needs to be taken
|
||||
to make sure these remain in sync with the rest of the design.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Imported Modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import string
|
||||
from Date import compare_dates, UNDEF
|
||||
import Date
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
def build_sort_name(n):
|
||||
"""Builds a name from a RelLib.Name instance that is suitable for
|
||||
use as a sort key in a GtkCList. The name is converted to upper case
|
||||
to provide for case-insenstive sorting"""
|
||||
return "%-25s%-30s%s" % \
|
||||
(string.upper(n.Surname),string.upper(n.FirstName),string.upper(n.Suffix))
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def build_sort_event(n):
|
||||
def build_sort_date(n):
|
||||
"""Builds a date from a Date.Date instance that is suitable for
|
||||
use as a sort key in a GtkCList. The resultant string is in the format
|
||||
of YYYYMMDD. Unknown values are given as all nines, so that the
|
||||
appear at the end"""
|
||||
y = n.start.year
|
||||
if y < 0:
|
||||
y = 9999
|
||||
@ -47,110 +61,32 @@ def build_sort_event(n):
|
||||
d = 99
|
||||
return "%04d%02d%02d" % (y,m,d)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def fast_name_sort(list):
|
||||
nlist = map(build_sort_name,list)
|
||||
nlist.sort()
|
||||
return map(lambda(key,x): x, nlist)
|
||||
def by_last_name(first, second):
|
||||
"""Sort routine for comparing two last names. If last names are equal,
|
||||
uses the given name and suffix"""
|
||||
u = string.upper
|
||||
name1 = first.PrimaryName
|
||||
name2 = second.PrimaryName
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def reverse_name_sort(list):
|
||||
nlist = map(build_sort_name,list)
|
||||
nlist.sort()
|
||||
nlist.reverse()
|
||||
return map(lambda(key,x): x, nlist)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def fast_birth_sort(list):
|
||||
nlist = map(build_sort_event,list)
|
||||
nlist.sort()
|
||||
return map(lambda(key,x): x, nlist)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def reverse_birth_sort(list):
|
||||
nlist = map(build_sort_event,list)
|
||||
nlist.sort()
|
||||
nlist.reverse()
|
||||
return map(lambda(key,x): x, nlist)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def fast_death_sort(list):
|
||||
nlist = map(build_sort_event,list)
|
||||
nlist.sort()
|
||||
return map(lambda(key,x): x, nlist)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def reverse_death_sort(list):
|
||||
nlist = map(build_sort_event,list)
|
||||
nlist.sort()
|
||||
nlist.reverse()
|
||||
return map(lambda(key,x): x, nlist)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def by_last_name(first, second) :
|
||||
|
||||
name1 = first.getPrimaryName()
|
||||
name2 = second.getPrimaryName()
|
||||
|
||||
fsn = string.upper(name1.getSurname())
|
||||
ssn = string.upper(name2.getSurname())
|
||||
fsn = u(name1.Surname)
|
||||
ssn = u(name2.Surname)
|
||||
|
||||
if fsn == ssn :
|
||||
ffn = string.upper(name1.getFirstName())
|
||||
sfn = string.upper(name2.getFirstName())
|
||||
ffn = u(name1.FirstName)
|
||||
sfn = u(name2.FirstName)
|
||||
if ffn == sfn :
|
||||
return cmp(string.upper(name1.getSuffix()), string.upper(name2.getSuffix()))
|
||||
return cmp(u(name1.Suffix), u(name2.Suffix))
|
||||
else :
|
||||
return cmp(ffn, sfn)
|
||||
else :
|
||||
return cmp(fsn, ssn)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def by_last_name_backwards(first, second) :
|
||||
return by_last_name(second,first)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def by_birthdate(first, second) :
|
||||
|
||||
"""Sort routine for comparing two people by birth dates. If the birth dates
|
||||
are equal, sorts by name"""
|
||||
date1 = first.getBirth().getDateObj()
|
||||
date2 = second.getBirth().getDateObj()
|
||||
val = compare_dates(date1,date2)
|
||||
val = Date.compare_dates(date1,date2)
|
||||
if val == 0:
|
||||
return by_last_name(first,second)
|
||||
return val
|
||||
|
Loading…
Reference in New Issue
Block a user