2002-10-20 19:55:16 +05:30
#
# Gramps - a GTK+/GNOME based genealogy program
#
2005-01-12 04:11:15 +05:30
# Copyright (C) 2000-2005 Donald N. Allingham
2002-10-20 19:55:16 +05:30
#
# 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
#
2003-11-07 21:59:27 +05:30
# $Id$
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# Standard python modules
#
#-------------------------------------------------------------------------
import os
2003-06-15 05:35:43 +05:30
import locale
2005-05-31 02:11:43 +05:30
from gettext import gettext as _
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# GNOME/GTK
#
#-------------------------------------------------------------------------
import gtk
2005-05-26 10:34:36 +05:30
import gtk . gdk
2004-05-14 04:15:51 +05:30
import gnome
2002-10-20 19:55:16 +05:30
2005-01-27 08:48:21 +05:30
try :
from gnomevfs import get_mime_type , mime_get_description
except :
from gnome . vfs import get_mime_type , mime_get_description
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
import const
2004-04-04 10:09:52 +05:30
import GrampsMime
2005-01-01 09:57:15 +05:30
import NameDisplay
2004-10-11 04:52:12 +05:30
import Date
2005-05-31 02:11:43 +05:30
import RelLib
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
2005-05-31 02:11:43 +05:30
# Integer to String mappings for constants
2002-10-20 19:55:16 +05:30
#
#-------------------------------------------------------------------------
2005-05-31 02:11:43 +05:30
gender = {
RelLib . Person . MALE : _ ( " male " ) ,
RelLib . Person . FEMALE : _ ( " female " ) ,
RelLib . Person . UNKNOWN : _ ( " unknown " ) ,
}
child_relations = {
RelLib . Person . CHILD_NONE : _ ( " None " ) ,
RelLib . Person . CHILD_BIRTH : _ ( " Birth " ) ,
RelLib . Person . CHILD_ADOPTED : _ ( " Adopted " ) ,
RelLib . Person . CHILD_STEPCHILD : _ ( " Stepchild " ) ,
RelLib . Person . CHILD_SPONSORED : _ ( " Sponsored " ) ,
RelLib . Person . CHILD_FOSTER : _ ( " Foster " ) ,
RelLib . Person . CHILD_UNKNOWN : _ ( " Unknown " ) ,
RelLib . Person . CHILD_CUSTOM : _ ( " Custom " ) ,
}
confidence = {
RelLib . SourceRef . CONF_VERY_HIGH : _ ( " Very High " ) ,
RelLib . SourceRef . CONF_HIGH : _ ( " High " ) ,
RelLib . SourceRef . CONF_NORMAL : _ ( " Normal " ) ,
RelLib . SourceRef . CONF_LOW : _ ( " Low " ) ,
RelLib . SourceRef . CONF_VERY_LOW : _ ( " Very Low " ) ,
}
family_events = {
RelLib . Event . UNKNOWN : _ ( " Unknown " ) ,
RelLib . Event . CUSTOM : _ ( " Custom " ) ,
RelLib . Event . MARRIAGE : _ ( " Marriage " ) ,
RelLib . Event . MARR_SETTL : _ ( " Marriage Settlement " ) ,
RelLib . Event . MARR_LIC : _ ( " Marriage License " ) ,
RelLib . Event . MARR_CONTR : _ ( " Marriage Contract " ) ,
RelLib . Event . MARR_BANNS : _ ( " Marriage Banns " ) ,
RelLib . Event . ENGAGEMENT : _ ( " Engagement " ) ,
RelLib . Event . DIVORCE : _ ( " Divorce " ) ,
RelLib . Event . DIV_FILING : _ ( " Divorce Filing " ) ,
RelLib . Event . ANNULMENT : _ ( " Annulment " ) ,
RelLib . Event . MARR_ALT : _ ( " Alternate Marriage " ) ,
}
personal_events = {
RelLib . Event . UNKNOWN : _ ( " Unknown " ) ,
RelLib . Event . CUSTOM : _ ( " Custom " ) ,
RelLib . Event . ADOPT : _ ( " Adopted " ) ,
RelLib . Event . BIRTH : _ ( " Birth " ) ,
RelLib . Event . DEATH : _ ( " Death " ) ,
RelLib . Event . ADULT_CHRISTEN : _ ( " Adult Christening " ) ,
RelLib . Event . BAPTISM : _ ( " Baptism " ) ,
RelLib . Event . BAR_MITZVAH : _ ( " Bar Mitzvah " ) ,
RelLib . Event . BAS_MITZVAH : _ ( " Bas Mitzvah " ) ,
RelLib . Event . BLESS : _ ( " Blessing " ) ,
RelLib . Event . BURIAL : _ ( " Burial " ) ,
RelLib . Event . CAUSE_DEATH : _ ( " Cause Of Death " ) ,
RelLib . Event . CENSUS : _ ( " Census " ) ,
RelLib . Event . CHRISTEN : _ ( " Christening " ) ,
RelLib . Event . CONFIRMATION : _ ( " Confirmation " ) ,
RelLib . Event . CREMATION : _ ( " Cremation " ) ,
RelLib . Event . DEGREE : _ ( " Degree " ) ,
RelLib . Event . DIV_FILING : _ ( " Divorce Filing " ) ,
RelLib . Event . EDUCATION : _ ( " Education " ) ,
RelLib . Event . ELECTED : _ ( " Elected " ) ,
RelLib . Event . EMIGRATION : _ ( " Emigration " ) ,
RelLib . Event . FIRST_COMMUN : _ ( " First Communion " ) ,
RelLib . Event . IMMIGRATION : _ ( " Immigration " ) ,
RelLib . Event . GRADUATION : _ ( " Graduation " ) ,
RelLib . Event . MED_INFO : _ ( " Medical Information " ) ,
RelLib . Event . MILITARY_SERV : _ ( " Military Service " ) ,
RelLib . Event . NATURALIZATION : _ ( " Naturalization " ) ,
RelLib . Event . NOB_TITLE : _ ( " Nobility Title " ) ,
RelLib . Event . NUM_MARRIAGES : _ ( " Number of Marriages " ) ,
RelLib . Event . OCCUPATION : _ ( " Occupation " ) ,
RelLib . Event . ORDINATION : _ ( " Ordination " ) ,
RelLib . Event . PROBATE : _ ( " Probate " ) ,
RelLib . Event . PROPERTY : _ ( " Property " ) ,
RelLib . Event . RELIGION : _ ( " Religion " ) ,
RelLib . Event . RESIDENCE : _ ( " Residence " ) ,
RelLib . Event . RETIREMENT : _ ( " Retirement " ) ,
RelLib . Event . WILL : _ ( " Will " )
}
personal_attributes = {
RelLib . Attribute . UNKNOWN : _ ( " Unknown " ) ,
RelLib . Attribute . CUSTOM : _ ( " Custom " ) ,
RelLib . Attribute . CASTE : _ ( " Caste " ) ,
RelLib . Attribute . DESCRIPTION : _ ( " Description " ) ,
RelLib . Attribute . ID : _ ( " Identification Number " ) ,
RelLib . Attribute . NATIONAL : _ ( " National Origin " ) ,
RelLib . Attribute . NUM_CHILD : _ ( " Number of Children " ) ,
RelLib . Attribute . SSN : _ ( " Social Security Number " ) ,
}
family_attributes = {
RelLib . Attribute . UNKNOWN : _ ( " Unknown " ) ,
RelLib . Attribute . CUSTOM : _ ( " Custom " ) ,
2005-06-09 02:47:18 +05:30
RelLib . Attribute . NUM_CHILD : _ ( " Number of Children " ) ,
2005-05-31 02:11:43 +05:30
}
family_relations = {
RelLib . Family . MARRIED : _ ( " Married " ) ,
RelLib . Family . UNMARRIED : _ ( " Unmarried " ) ,
RelLib . Family . CIVIL_UNION : _ ( " Civil Union " ) ,
RelLib . Family . UNKNOWN : _ ( " Unknown " ) ,
RelLib . Family . CUSTOM : _ ( " Other " ) ,
}
family_rel_descriptions = {
RelLib . Family . MARRIED : _ ( " A legal or common-law relationship "
" between a husband and wife " ) ,
RelLib . Family . UNMARRIED : _ ( " No legal or common-law relationship "
" between man and woman " ) ,
RelLib . Family . CIVIL_UNION : _ ( " An established relationship between "
" members of the same sex " ) ,
RelLib . Family . UNKNOWN : _ ( " Unknown relationship between a man "
" and woman " ) ,
RelLib . Family . CUSTOM : _ ( " An unspecified relationship "
" a man and woman " ) ,
}
name_types = {
RelLib . Name . UNKNOWN : _ ( " Unknown " ) ,
RelLib . Name . CUSTOM : _ ( " Custom " ) ,
RelLib . Name . AKA : _ ( " Also Known As " ) ,
RelLib . Name . BIRTH : _ ( " Birth Name " ) ,
RelLib . Name . MARRIED : _ ( " Married Name " ) ,
}
source_media_types = {
RelLib . RepoRef . UNKNOWN : _ ( " Unknown " ) ,
RelLib . RepoRef . CUSTOM : _ ( " Custom " ) ,
RelLib . RepoRef . AUDIO : _ ( " Audio " ) ,
RelLib . RepoRef . BOOK : _ ( " Book " ) ,
RelLib . RepoRef . CARD : _ ( " Card " ) ,
RelLib . RepoRef . ELECTRONIC : _ ( " Electronic " ) ,
RelLib . RepoRef . FICHE : _ ( " Fiche " ) ,
RelLib . RepoRef . FILM : _ ( " Film " ) ,
RelLib . RepoRef . MAGAZINE : _ ( " Magazine " ) ,
RelLib . RepoRef . MANUSCRIPT : _ ( " Manuscript " ) ,
RelLib . RepoRef . MAP : _ ( " Map " ) ,
RelLib . RepoRef . NEWSPAPER : _ ( " Newspaper " ) ,
RelLib . RepoRef . PHOTO : _ ( " Photo " ) ,
RelLib . RepoRef . THOMBSTOBE : _ ( " Thombstone " ) ,
RelLib . RepoRef . VIDEO : _ ( " Video " ) ,
}
2005-06-01 18:44:29 +05:30
event_roles = {
RelLib . EventRef . UNKNOWN : _ ( " Unknown " ) ,
RelLib . EventRef . CUSTOM : _ ( " Custom " ) ,
RelLib . EventRef . PRIMARY : _ ( " Primary " ) ,
RelLib . EventRef . CLERGY : _ ( " Clergy " ) ,
RelLib . EventRef . CELEBRANT : _ ( " Celebrant " ) ,
RelLib . EventRef . AIDE : _ ( " Aide " ) ,
RelLib . EventRef . BRIDE : _ ( " Bride " ) ,
RelLib . EventRef . GROOM : _ ( " Groom " ) ,
RelLib . EventRef . WITNESS : _ ( " Witness " ) ,
}
2005-06-02 10:00:04 +05:30
2005-06-09 00:17:55 +05:30
family_event_roles = {
RelLib . EventRef . UNKNOWN : _ ( " Unknown " ) ,
RelLib . EventRef . CUSTOM : _ ( " Custom " ) ,
RelLib . EventRef . FAMILY : _ ( " Family " ) ,
}
2005-06-02 10:00:04 +05:30
repository_types = {
RelLib . Repository . UNKNOWN : _ ( " Unknown " ) ,
RelLib . Repository . CUSTOM : _ ( " Custom " ) ,
RelLib . Repository . LIBRARY : _ ( " Library " ) ,
RelLib . Repository . CEMETERY : _ ( " Cemetery " ) ,
RelLib . Repository . CHURCH : _ ( " Church " ) ,
RelLib . Repository . ARCHIVE : _ ( " Archive " ) ,
RelLib . Repository . ALBUM : _ ( " Album " ) ,
RelLib . Repository . WEBSITE : _ ( " Web site " ) ,
RelLib . Repository . BOOKSTORE : _ ( " Bookstore " ) ,
RelLib . Repository . COLLECTION : _ ( " Collection " ) ,
RelLib . Repository . SAFE : _ ( " Safe " ) ,
}
2005-05-31 02:11:43 +05:30
#-------------------------------------------------------------------------
#
# Integer to GEDCOM tag mappings for constants
#
#-------------------------------------------------------------------------
familyConstantEvents = {
RelLib . Event . ANNULMENT : " ANUL " ,
RelLib . Event . DIV_FILING : " DIVF " ,
RelLib . Event . DIVORCE : " DIV " ,
RelLib . Event . ENGAGEMENT : " ENGA " ,
RelLib . Event . MARR_BANNS : " MARB " ,
RelLib . Event . MARR_CONTR : " MARC " ,
RelLib . Event . MARR_LIC : " MARL " ,
RelLib . Event . MARR_SETTL : " MARS " ,
RelLib . Event . MARRIAGE : " MARR "
}
personalConstantEvents = {
RelLib . Event . ADOPT : " ADOP " ,
RelLib . Event . ADULT_CHRISTEN : " CHRA " ,
RelLib . Event . BIRTH : " BIRT " ,
RelLib . Event . DEATH : " DEAT " ,
RelLib . Event . BAPTISM : " BAPM " ,
RelLib . Event . BAR_MITZVAH : " BARM " ,
RelLib . Event . BAS_MITZVAH : " BASM " ,
RelLib . Event . BLESS : " BLES " ,
RelLib . Event . BURIAL : " BURI " ,
RelLib . Event . CAUSE_DEATH : " CAUS " ,
RelLib . Event . ORDINATION : " ORDI " ,
RelLib . Event . CENSUS : " CENS " ,
RelLib . Event . CHRISTEN : " CHR " ,
RelLib . Event . CONFIRMATION : " CONF " ,
RelLib . Event . CREMATION : " CREM " ,
RelLib . Event . DEGREE : " " ,
RelLib . Event . DIV_FILING : " DIVF " ,
RelLib . Event . EDUCATION : " EDUC " ,
RelLib . Event . ELECTED : " " ,
RelLib . Event . ELECTED : " EMIG " ,
RelLib . Event . FIRST_COMMUN : " FCOM " ,
RelLib . Event . GRADUATION : " GRAD " ,
RelLib . Event . MED_INFO : " " ,
RelLib . Event . MILITARY_SERV : " " ,
RelLib . Event . NATURALIZATION : " NATU " ,
RelLib . Event . NOB_TITLE : " TITL " ,
RelLib . Event . NUM_MARRIAGES : " NMR " ,
RelLib . Event . IMMIGRATION : " IMMI " ,
RelLib . Event . OCCUPATION : " OCCU " ,
RelLib . Event . PROBATE : " PROB " ,
RelLib . Event . PROPERTY : " PROP " ,
RelLib . Event . RELIGION : " RELI " ,
RelLib . Event . RESIDENCE : " RESI " ,
RelLib . Event . RETIREMENT : " RETI " ,
RelLib . Event . WILL : " WILL " ,
}
familyConstantAttributes = {
RelLib . Attribute . NUM_CHILD : " NCHI " ,
}
personalConstantAttributes = {
RelLib . Attribute . CASTE : " CAST " ,
RelLib . Attribute . DESCRIPTION : " DSCR " ,
RelLib . Attribute . ID : " IDNO " ,
RelLib . Attribute . NATIONAL : " NATI " ,
RelLib . Attribute . NUM_CHILD : " NCHI " ,
RelLib . Attribute . SSN : " SSN " ,
}
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# modified flag
#
#-------------------------------------------------------------------------
2003-11-07 21:59:27 +05:30
_history_brokenFlag = 0
2002-10-20 19:55:16 +05:30
2003-11-07 21:59:27 +05:30
def history_broken ( ) :
global _history_brokenFlag
_history_brokenFlag = 1
2005-03-12 06:14:11 +05:30
data_recover_msg = _ ( ' The data can only be recovered by Undo operation '
' or by quitting with abandoning changes. ' )
2003-04-04 11:18:25 +05:30
#-------------------------------------------------------------------------
#
# force_unicode
#
#-------------------------------------------------------------------------
def force_unicode ( n ) :
2005-01-09 07:48:49 +05:30
if type ( n ) != unicode :
2003-04-04 11:18:25 +05:30
return ( unicode ( n ) . lower ( ) , unicode ( n ) )
else :
return ( n . lower ( ) , n )
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# Clears the modified flag. Should be called after data is saved.
#
#-------------------------------------------------------------------------
2003-11-07 21:59:27 +05:30
def clearHistory_broken ( ) :
global _history_brokenFlag
_history_brokenFlag = 0
def wasHistory_broken ( ) :
return _history_brokenFlag
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
# Short hand function to return either the person's name, or an empty
# string if the person is None
#
#-------------------------------------------------------------------------
2003-10-12 09:56:00 +05:30
2004-02-23 10:11:37 +05:30
def family_name ( family , db ) :
2002-10-20 19:55:16 +05:30
""" Builds a name for the family from the parents names """
2004-07-28 07:59:07 +05:30
father_handle = family . get_father_handle ( )
mother_handle = family . get_mother_handle ( )
2004-08-07 10:46:57 +05:30
father = db . get_person_from_handle ( father_handle )
mother = db . get_person_from_handle ( mother_handle )
2002-10-20 19:55:16 +05:30
if father and mother :
2005-01-01 09:57:15 +05:30
fname = NameDisplay . displayer . display ( father )
mname = NameDisplay . displayer . display ( mother )
2005-03-12 02:35:46 +05:30
name = _ ( " %(father)s and %(mother)s " ) % {
" father " : fname ,
" mother " : mname }
2002-10-20 19:55:16 +05:30
elif father :
2005-01-01 09:57:15 +05:30
name = NameDisplay . displayer . display ( father )
2005-03-14 03:40:40 +05:30
elif mother :
2005-01-01 09:57:15 +05:30
name = NameDisplay . displayer . display ( mother )
2005-03-14 03:40:40 +05:30
else :
name = _ ( " unknown " )
2002-10-20 19:55:16 +05:30
return name
2004-02-23 10:11:37 +05:30
def family_upper_name ( family , db ) :
2003-10-12 09:56:00 +05:30
""" Builds a name for the family from the parents names """
2004-07-28 07:59:07 +05:30
father_handle = family . get_father_handle ( )
mother_handle = family . get_mother_handle ( )
2004-08-07 10:46:57 +05:30
father = db . get_person_from_handle ( father_handle )
mother = db . get_person_from_handle ( mother_handle )
2003-10-12 09:56:00 +05:30
if father and mother :
2004-02-14 11:10:30 +05:30
fname = father . get_primary_name ( ) . get_upper_name ( )
mname = mother . get_primary_name ( ) . get_upper_name ( )
2003-10-12 09:56:00 +05:30
name = _ ( " %s and %s " ) % ( fname , mname )
elif father :
2004-02-14 11:10:30 +05:30
name = father . get_primary_name ( ) . get_upper_name ( )
2002-10-20 19:55:16 +05:30
else :
2004-02-14 11:10:30 +05:30
name = mother . get_primary_name ( ) . get_upper_name ( )
2003-10-12 09:56:00 +05:30
return name
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def destroy_passed_object ( obj ) :
obj . destroy ( )
while gtk . events_pending ( ) :
2004-04-28 09:36:25 +05:30
gtk . main_iteration ( )
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def get_detail_text ( obj , priv = 1 ) :
2004-02-14 11:10:30 +05:30
if obj . get_note ( ) != " " :
2002-10-20 19:55:16 +05:30
details = " %s " % _ ( " Note " )
else :
details = " "
2004-02-14 11:10:30 +05:30
if len ( obj . get_source_references ( ) ) > 0 :
2002-10-20 19:55:16 +05:30
if details == " " :
details = _ ( " Source " )
else :
details = " %s , %s " % ( details , _ ( " Source " ) )
2004-02-14 11:10:30 +05:30
if priv and obj . get_privacy ( ) == 1 :
2002-10-20 19:55:16 +05:30
if details == " " :
details = _ ( " Private " )
else :
details = " %s , %s " % ( details , _ ( " Private " ) )
return details
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def redraw_list ( dlist , clist , func ) :
clist . clear ( )
index = 0
2004-08-23 04:46:57 +05:30
for obj in dlist :
2002-10-20 19:55:16 +05:30
col = 0
2004-08-23 04:46:57 +05:30
node = clist . append ( )
for data in func ( obj ) :
clist . set_value ( node , col , data )
2002-10-20 19:55:16 +05:30
col = col + 1
index = index + 1
return index
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def delete_selected ( obj , list ) :
sel = obj . get_selection ( )
2004-08-23 04:46:57 +05:30
model , node = sel . get_selected ( )
if node :
index = model . get_path ( node ) [ 0 ]
2002-10-20 19:55:16 +05:30
del list [ index ]
return 1
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def add_menuitem ( menu , msg , obj , func ) :
item = gtk . MenuItem ( msg )
2004-05-14 04:15:51 +05:30
item . set_data ( ' o ' , obj )
2002-10-20 19:55:16 +05:30
item . connect ( " activate " , func )
item . show ( )
menu . append ( item )
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def view_photo ( photo ) :
2004-08-23 04:46:57 +05:30
mime_type = photo . get_mime_type ( )
2004-04-04 10:09:52 +05:30
try :
2004-08-23 04:46:57 +05:30
data = GrampsMime . get_application ( mime_type )
2004-04-04 10:09:52 +05:30
prog = data [ 0 ]
except :
2002-11-03 02:49:58 +05:30
return
2002-10-20 19:55:16 +05:30
2004-10-29 06:19:40 +05:30
args = prog . split ( )
2004-02-14 11:10:30 +05:30
args . append ( photo . get_path ( ) )
2002-10-20 19:55:16 +05:30
if os . fork ( ) == 0 :
os . execvp ( args [ 0 ] , args )
2005-02-24 05:55:34 +05:30
_icon_theme = gtk . icon_theme_get_default ( )
2002-10-20 19:55:16 +05:30
2005-02-24 05:55:34 +05:30
def find_mime_type_pixbuf ( mime_type ) :
icontmp = mime_type . replace ( ' / ' , ' - ' )
try :
newicon = " gnome-mime- %s " % icontmp
try :
return _icon_theme . load_icon ( newicon , 48 , 0 )
except :
icontmp = mime_type . split ( ' / ' ) [ 0 ]
try :
newicon = " gnome-mime- %s " % icontmp
return _icon_theme . load_icon ( newicon , 48 , 0 )
except :
return gtk . gdk . pixbuf_new_from_file ( const . icon )
except :
return gtk . gdk . pixbuf_new_from_file ( const . icon )
2004-08-23 04:46:57 +05:30
def get_mime_description ( mime_type ) :
2004-04-04 10:09:52 +05:30
try :
2005-01-27 08:48:21 +05:30
value = mime_get_description ( mime_type )
2004-04-04 10:09:52 +05:30
if value :
return value
else :
return ' '
except :
return ' '
2002-10-20 19:55:16 +05:30
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def build_string_optmenu ( mapping , start_val ) :
index = 0
start_index = 0
keys = mapping . keys ( )
keys . sort ( )
myMenu = gtk . Menu ( )
for key in keys :
if key == " default " :
menuitem = gtk . MenuItem ( _ ( " default " ) )
else :
menuitem = gtk . MenuItem ( key )
menuitem . set_data ( " d " , mapping [ key ] )
2003-10-31 06:50:58 +05:30
menuitem . set_data ( " l " , key )
2002-10-20 19:55:16 +05:30
menuitem . show ( )
myMenu . append ( menuitem )
if key == start_val :
start_index = index
index = index + 1
if start_index :
myMenu . set_active ( start_index )
return myMenu
2002-10-25 10:22:51 +05:30
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def build_columns ( tree , list ) :
cnum = 0
for name in list :
renderer = gtk . CellRendererText ( )
2003-07-27 09:20:57 +05:30
renderer . set_fixed_height_from_font ( 1 )
2002-10-25 10:22:51 +05:30
column = gtk . TreeViewColumn ( name [ 0 ] , renderer , text = cnum )
column . set_min_width ( name [ 1 ] )
if name [ 2 ] > = 0 :
column . set_sort_column_id ( name [ 2 ] )
if name [ 0 ] == ' ' :
2005-02-24 05:55:34 +05:30
column . set_clickable ( True )
column . set_visible ( False )
2002-10-25 10:22:51 +05:30
cnum = cnum + 1
tree . append_column ( column )
2003-01-10 10:51:32 +05:30
#-------------------------------------------------------------------------
#
# Iterate over ancestors.
#
#-------------------------------------------------------------------------
2005-01-12 04:11:15 +05:30
def for_each_ancestor ( db , start , func , data ) :
2003-01-10 10:51:32 +05:30
"""
Recursively iterate ( breadth - first ) over ancestors of
people listed in start .
Call func ( data , pid ) for the Id of each person encountered .
Exit and return 1 , as soon as func returns true .
Return 0 otherwise .
"""
todo = start
doneIds = { }
while len ( todo ) :
2005-01-12 04:11:15 +05:30
p_handle = todo . pop ( )
p = db . get_person_from_handle ( p_handle )
# Don't process the same handle twice. This can happen
2003-01-10 10:51:32 +05:30
# if there is a cycle in the database, or if the
# initial list contains X and some of X's ancestors.
2005-01-12 04:11:15 +05:30
if doneIds . has_key ( p_handle ) :
2003-01-10 10:51:32 +05:30
continue
2005-01-12 04:11:15 +05:30
doneIds [ p_handle ] = 1
if func ( data , p_handle ) :
2003-01-10 10:51:32 +05:30
return 1
2005-01-12 04:11:15 +05:30
for fam_handle , mrel , frel in p . get_parent_family_handle_list ( ) :
fam = db . get_family_from_handle ( fam_handle )
if fam :
f_handle = fam . get_father_handle ( )
m_handle = fam . get_mother_handle ( )
if f_handle : todo . append ( f_handle )
if m_handle : todo . append ( m_handle )
2003-01-10 10:51:32 +05:30
return 0
2003-03-05 11:31:31 +05:30
def title ( n ) :
return ' <span weight= " bold " size= " larger " > %s </span> ' % n
def set_title_label ( xmlobj , t ) :
title_label = xmlobj . get_widget ( ' title ' )
title_label . set_text ( ' <span weight= " bold " size= " larger " > %s </span> ' % t )
2005-02-24 05:55:34 +05:30
title_label . set_use_markup ( True )
2003-03-06 11:42:51 +05:30
def set_titles ( window , title , t , msg = None ) :
title . set_text ( ' <span weight= " bold " size= " larger " > %s </span> ' % t )
2005-02-24 05:55:34 +05:30
title . set_use_markup ( True )
2003-03-06 11:42:51 +05:30
if msg :
window . set_title ( ' %s - GRAMPS ' % msg )
else :
window . set_title ( ' %s - GRAMPS ' % t )
2003-05-10 11:47:07 +05:30
2003-06-14 22:41:11 +05:30
def gfloat ( val ) :
2003-06-15 05:35:43 +05:30
""" Converts to floating number, taking care of possible locale differences.
Useful for reading float values from text entry fields
while under non - English locale .
"""
2003-06-14 22:41:11 +05:30
try :
return float ( val )
except :
try :
2003-06-14 22:44:46 +05:30
return float ( val . replace ( ' . ' , ' , ' ) )
2003-06-14 22:41:11 +05:30
except :
2003-06-14 22:44:46 +05:30
return float ( val . replace ( ' , ' , ' . ' ) )
2003-06-14 22:41:11 +05:30
return 0.0
2003-06-15 05:35:43 +05:30
def gformat ( val ) :
""" Performs ( " %.3f " % val) formatting with the resulting string always
using dot ( ' . ' ) as a decimal point .
Useful for writing float values into XML when under non - English locale .
"""
decimal_point = locale . localeconv ( ) [ ' decimal_point ' ]
return_val = " %.3f " % val
return return_val . replace ( decimal_point , ' . ' )
2003-11-25 23:15:34 +05:30
def search_for ( name ) :
for i in os . environ [ ' PATH ' ] . split ( ' : ' ) :
fname = os . path . join ( i , name )
2003-11-26 03:04:39 +05:30
if os . access ( fname , os . X_OK ) and not os . path . isdir ( fname ) :
2003-11-25 23:15:34 +05:30
return 1
return 0
2003-06-14 22:41:11 +05:30
2003-11-13 00:15:07 +05:30
#-------------------------------------------------------------------------
#
# Change label apperance
#
#-------------------------------------------------------------------------
2005-05-26 10:34:36 +05:30
def bold_label ( label , widget = None ) :
clist = label . get_children ( )
text = unicode ( clist [ 1 ] . get_text ( ) )
text = text . replace ( ' <i> ' , ' ' )
text = text . replace ( ' </i> ' , ' ' )
clist [ 0 ] . show ( )
clist [ 1 ] . set_text ( " <b> %s </b> " % text )
clist [ 1 ] . set_use_markup ( True )
if widget :
widget . window . set_cursor ( None )
def unbold_label ( label , widget = None ) :
clist = label . get_children ( )
text = unicode ( clist [ 1 ] . get_text ( ) )
text = text . replace ( ' <b> ' , ' ' )
text = text . replace ( ' </b> ' , ' ' )
text = text . replace ( ' <i> ' , ' ' )
text = text . replace ( ' </i> ' , ' ' )
clist [ 0 ] . hide ( )
clist [ 1 ] . set_text ( text )
clist [ 1 ] . set_use_markup ( False )
if widget :
widget . window . set_cursor ( None )
def temp_label ( label , widget = None ) :
clist = label . get_children ( )
text = unicode ( clist [ 1 ] . get_text ( ) )
text = text . replace ( ' <b> ' , ' ' )
text = text . replace ( ' </b> ' , ' ' )
clist [ 0 ] . hide ( )
clist [ 1 ] . set_text ( " <i> %s </i> " % text )
clist [ 1 ] . set_use_markup ( True )
if widget :
widget . window . set_cursor ( gtk . gdk . Cursor ( gtk . gdk . WATCH ) )
2004-04-25 10:18:02 +05:30
2004-06-30 09:36:10 +05:30
#-------------------------------------------------------------------------
#
# create_id
#
#-------------------------------------------------------------------------
import random
import time
2005-04-29 03:51:20 +05:30
from sys import maxint
2004-06-30 09:36:10 +05:30
rand = random . Random ( time . time ( ) )
2004-06-27 08:40:06 +05:30
def create_id ( ) :
2005-04-29 03:51:20 +05:30
return " %08x %08x " % ( int ( time . time ( ) * 10000 ) ,
rand . randint ( 0 , maxint ) )
2004-10-08 09:29:55 +05:30
2005-04-06 21:22:52 +05:30
def probably_alive ( person , db , current_year = None ) :
2005-04-08 13:39:18 +05:30
""" Returns true if the person may be alive.
This works by a process of emlimination . If we can ' t find a good
reason to believe that someone is dead then we assume they must
be alive .
"""
if not current_year :
time_struct = time . localtime ( time . time ( ) )
current_year = time_struct [ 0 ]
2005-04-08 15:10:15 +05:30
death_year = None
2005-04-08 13:39:18 +05:30
# If the recorded death year is before current year then
# things are simple.
2004-10-08 09:29:55 +05:30
if person . death_handle :
2005-04-08 13:39:18 +05:30
death = db . get_event_from_handle ( person . death_handle )
if death . get_date_object ( ) . get_start_date ( ) != Date . EMPTY :
2005-04-08 15:10:15 +05:30
death_year = death . get_date_object ( ) . get_year ( )
2005-04-08 13:39:18 +05:30
if death . get_date_object ( ) . get_year ( ) < current_year :
2005-04-07 02:26:24 +05:30
return False
2004-10-08 09:29:55 +05:30
# Look for Cause Of Death, Burial or Cremation events.
# These are fairly good indications that someone's not alive.
for ev_handle in person . event_list :
ev = db . get_event_from_handle ( ev_handle )
2004-12-09 04:24:26 +05:30
if ev and ev . name in [ " Cause Of Death " , " Burial " , " Cremation " ] :
2005-04-08 15:10:15 +05:30
if not death_year :
death_year = ev . get_date_object ( ) . get_year ( )
2005-04-07 02:26:24 +05:30
if ev . get_date_object ( ) . get_start_date ( ) != Date . EMPTY :
2005-04-08 13:39:18 +05:30
if ev . get_date_object ( ) . get_year ( ) < current_year :
2005-04-07 02:26:24 +05:30
return False
2004-10-08 09:29:55 +05:30
2005-04-08 15:10:15 +05:30
birth_year = None
2005-04-08 13:39:18 +05:30
# If they were born within 100 years before current year then
# assume they are alive (we already know they are not dead).
2004-10-08 09:29:55 +05:30
if person . birth_handle :
birth = db . get_event_from_handle ( person . birth_handle )
if birth . get_date_object ( ) . get_start_date ( ) != Date . EMPTY :
2005-04-08 15:10:15 +05:30
if not birth_year :
birth_year = birth . get_date_object ( ) . get_year ( )
if birth . get_date_object ( ) . get_year ( ) > current_year :
# person is not yet born
return False
2005-04-08 13:39:18 +05:30
r = not_too_old ( birth . get_date_object ( ) , current_year )
if r :
#print person.get_primary_name().get_name(), " is alive because they were born late enough."
return True
2005-04-08 15:10:15 +05:30
if not birth_year and death_year :
if death_year > current_year + 110 :
# person died more tha 110 after current year
return False
2005-04-08 13:39:18 +05:30
2004-10-08 09:29:55 +05:30
# Neither birth nor death events are available. Try looking
# for descendants that were born more than a lifespan ago.
min_generation = 13
max_generation = 60
max_age_difference = 60
def descendants_too_old ( person , years ) :
for family_handle in person . get_family_handle_list ( ) :
family = db . get_family_from_handle ( family_handle )
2005-04-08 13:39:18 +05:30
family_list = family . get_child_handle_list ( )
2004-10-08 09:29:55 +05:30
for child_handle in family . get_child_handle_list ( ) :
child = db . get_person_from_handle ( child_handle )
if child . birth_handle :
child_birth = db . get_event_from_handle ( child . birth_handle )
dobj = child_birth . get_date_object ( )
if dobj . get_start_date ( ) != Date . EMPTY :
2004-10-29 06:19:40 +05:30
d = Date . Date ( dobj )
val = d . get_start_date ( )
2004-12-09 04:24:26 +05:30
val = d . get_year ( ) - years
2004-10-29 06:19:40 +05:30
d . set_year ( val )
2005-04-06 21:22:52 +05:30
if not not_too_old ( d , current_year ) :
2004-10-08 09:29:55 +05:30
return True
if child . death_handle :
child_death = db . get_event_from_handle ( child . death_handle )
dobj = child_death . get_date_object ( )
2004-10-29 06:19:40 +05:30
if dobj . get_start_date ( ) != Date . EMPTY :
2005-04-06 21:22:52 +05:30
if not not_too_old ( dobj , current_year ) :
2004-10-08 09:29:55 +05:30
return True
if descendants_too_old ( child , years + min_generation ) :
return True
2005-04-08 13:39:18 +05:30
return False
2004-10-08 09:29:55 +05:30
2005-04-08 13:39:18 +05:30
# If there are descendants that are too old for the person to have
# been alive in the current year then they must be dead.
2004-10-08 09:29:55 +05:30
if descendants_too_old ( person , min_generation ) :
2005-04-08 13:39:18 +05:30
#print person.get_primary_name().get_name(), " is dead because descendants are too old."
return False
average_generation_gap = 20
def ancestors_too_old ( person , year ) :
family_handle = person . get_main_parents_family_handle ( )
if family_handle :
family = db . get_family_from_handle ( family_handle )
father_handle = family . get_father_handle ( )
if father_handle :
father = db . get_person_from_handle ( father_handle )
if father . birth_handle :
father_birth = db . get_event_from_handle ( father . birth_handle )
dobj = father_birth . get_date_object ( )
if dobj . get_start_date ( ) != Date . EMPTY :
if not not_too_old ( dobj , year - average_generation_gap ) :
#print father.get_primary_name().get_name(), " father of ", person.get_primary_name().get_name(), " is too old by birth. birth year ", dobj.get_year(), " test year ", year - average_generation_gap
return True
#else:
#print father.get_primary_name().get_name(), " father of ", person.get_primary_name().get_name(), " is NOT too old by birth. birth year ", dobj.get_year(), " test year ", year - average_generation_gap
if father . death_handle :
father_death = db . get_event_from_handle ( father . death_handle )
dobj = father_death . get_date_object ( )
if dobj . get_start_date ( ) != Date . EMPTY :
if dobj . get_year ( ) < year - average_generation_gap :
#print father.get_primary_name().get_name(), " father of ", person.get_primary_name().get_name(), " is too old by death."
return True
if ancestors_too_old ( father , year - average_generation_gap ) :
return True
mother_handle = family . get_mother_handle ( )
if mother_handle :
mother = db . get_person_from_handle ( mother_handle )
if mother . birth_handle :
mother_birth = db . get_event_from_handle ( mother . birth_handle )
dobj = mother_birth . get_date_object ( )
if dobj . get_start_date ( ) != Date . EMPTY :
if not not_too_old ( dobj , year - average_generation_gap ) :
#print mother.get_primary_name().get_name(), " mother of ", person.get_primary_name().get_name(), " is too old by birth. birth year ", dobj.get_year(), " test year ", year - average_generation_gap
return True
#else:
#print mother.get_primary_name().get_name(), " mother of ", person.get_primary_name().get_name(), " is NOT too old by birth. birth year ", dobj.get_year(), " test year ", year - average_generation_gap
if mother . death_handle :
mother_death = db . get_event_from_handle ( mother . death_handle )
dobj = mother_death . get_date_object ( )
if dobj . get_start_date ( ) != Date . EMPTY :
if dobj . get_year ( ) < year - average_generation_gap :
#print mother.get_primary_name().get_name(), " mother of ", person.get_primary_name().get_name(), " is too old by death."
return True
if ancestors_too_old ( mother , year - average_generation_gap ) :
return True
2004-10-08 09:29:55 +05:30
return False
2005-04-08 13:39:18 +05:30
# If there are ancestors that would be too old in the current year
# then assume our person must be dead too.
if ancestors_too_old ( person , current_year ) :
#print person.get_primary_name().get_name(), " is dead because ancestors are too old."
return False
# If we can't find any reason to believe that they are dead we
# must assume they are alive.
#print person.get_primary_name().get_name(), " is probably alive."
return True
2004-10-08 09:29:55 +05:30
2005-04-06 21:22:52 +05:30
def not_too_old ( date , current_year = None ) :
if not current_year :
time_struct = time . localtime ( time . time ( ) )
current_year = time_struct [ 0 ]
2004-10-11 04:52:12 +05:30
year = date . get_year ( )
2005-04-07 02:26:24 +05:30
if year > current_year :
return False
2004-10-11 04:52:12 +05:30
return not ( year != 0 and current_year - year > 110 )
2005-03-12 02:35:46 +05:30
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def get_source_referents ( source_handle , db ) :
"""
Find objects that refer the source .
This function finds all primary objects that refer ( directly or through
secondary child - objects ) to a given source handle in a given database .
"""
# Persons
person_list = [ handle \
for handle in db . get_person_handles ( sort_handles = False ) \
if db . get_person_from_handle ( handle ) . has_source_reference ( source_handle )
]
# Families
family_list = [ handle for handle in db . get_family_handles ( ) \
if db . get_family_from_handle ( handle ) . has_source_reference ( source_handle )
]
# Events
event_list = [ handle for handle in db . get_event_handles ( ) \
if db . get_event_from_handle ( handle ) . has_source_reference ( source_handle )
]
# Places
place_list = [ handle for handle in db . get_place_handles ( ) \
if db . get_place_from_handle ( handle ) . has_source_reference ( source_handle )
]
# Sources
source_list = [ handle for handle in db . get_source_handles ( ) \
if db . get_source_from_handle ( handle ) . has_source_reference ( source_handle )
]
# Media Objects
media_list = [ handle for handle in db . get_media_object_handles ( ) \
if db . get_object_from_handle ( handle ) . has_source_reference ( source_handle )
]
return ( person_list , family_list , event_list ,
place_list , source_list , media_list )
2005-03-12 06:14:11 +05:30
def get_media_referents ( media_handle , db ) :
"""
Find objects that refer the media object .
This function finds all primary objects that refer
to a given media handle in a given database .
"""
# Persons
person_list = [ handle \
for handle in db . get_person_handles ( sort_handles = False ) \
if media_handle in \
[ photo . get_reference_handle ( ) for photo \
in db . get_person_from_handle ( handle ) . get_media_list ( ) ]
]
# Families
family_list = [ handle for handle in db . get_family_handles ( ) \
if media_handle in \
[ photo . get_reference_handle ( ) for photo \
in db . get_family_from_handle ( handle ) . get_media_list ( ) ]
]
# Events
event_list = [ handle for handle in db . get_event_handles ( ) \
if media_handle in \
[ photo . get_reference_handle ( ) for photo \
in db . get_event_from_handle ( handle ) . get_media_list ( ) ]
]
# Places
place_list = [ handle for handle in db . get_place_handles ( ) \
if media_handle in \
[ photo . get_reference_handle ( ) for photo \
in db . get_place_from_handle ( handle ) . get_media_list ( ) ]
]
# Sources
source_list = [ handle for handle in db . get_source_handles ( ) \
if media_handle in \
[ photo . get_reference_handle ( ) for photo \
in db . get_source_from_handle ( handle ) . get_media_list ( ) ]
]
return ( person_list , family_list , event_list , place_list , source_list )
2005-05-27 23:13:04 +05:30
2004-07-09 23:49:47 +05:30
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
* src/Plugins.py: Add native_format flag to import plugin registration.
* src/ReadXML.py, src/ReadGedcom.py: Register as native formats
to prevent loading twice on File->Open.
* src/data/gramps.schemas: Add keys for last import and export dirs.
* src/GrampsCfg.py (get_last_import_dir, save_last_import_dir,
get_last_export_dir, save_last_export_dir): Add functions.
* src/Exportder.py (suggest_filename): Try last export and last
import folders before falling back to Home; (save): Save export folder.
* src/Utils.py (get_new_filename): Add optional folder argument.
* src/DbPrompter.py (ExistingDbPrompter.chooser): Only add
importers for non-native formats, the rest is already taken care of;
Try last file, last import, last export, then home folders;
(ImportDbPrompter.chooser): Save import folder; Try last import,
last file, last export, then home folders.
(NewNativeDbPrompter): Try last file, last import, last export folders,
then fall back to home.
svn: r3493
2004-08-24 03:35:55 +05:30
_NEW_NAME_PATTERN = ' %s Untitled_ %d . %s '
2004-07-09 23:49:47 +05:30
* src/Plugins.py: Add native_format flag to import plugin registration.
* src/ReadXML.py, src/ReadGedcom.py: Register as native formats
to prevent loading twice on File->Open.
* src/data/gramps.schemas: Add keys for last import and export dirs.
* src/GrampsCfg.py (get_last_import_dir, save_last_import_dir,
get_last_export_dir, save_last_export_dir): Add functions.
* src/Exportder.py (suggest_filename): Try last export and last
import folders before falling back to Home; (save): Save export folder.
* src/Utils.py (get_new_filename): Add optional folder argument.
* src/DbPrompter.py (ExistingDbPrompter.chooser): Only add
importers for non-native formats, the rest is already taken care of;
Try last file, last import, last export, then home folders;
(ImportDbPrompter.chooser): Save import folder; Try last import,
last file, last export, then home folders.
(NewNativeDbPrompter): Try last file, last import, last export folders,
then fall back to home.
svn: r3493
2004-08-24 03:35:55 +05:30
def get_new_filename ( ext , folder = ' ~/ ' ) :
2004-07-09 23:49:47 +05:30
ix = 1
* src/Plugins.py: Add native_format flag to import plugin registration.
* src/ReadXML.py, src/ReadGedcom.py: Register as native formats
to prevent loading twice on File->Open.
* src/data/gramps.schemas: Add keys for last import and export dirs.
* src/GrampsCfg.py (get_last_import_dir, save_last_import_dir,
get_last_export_dir, save_last_export_dir): Add functions.
* src/Exportder.py (suggest_filename): Try last export and last
import folders before falling back to Home; (save): Save export folder.
* src/Utils.py (get_new_filename): Add optional folder argument.
* src/DbPrompter.py (ExistingDbPrompter.chooser): Only add
importers for non-native formats, the rest is already taken care of;
Try last file, last import, last export, then home folders;
(ImportDbPrompter.chooser): Save import folder; Try last import,
last file, last export, then home folders.
(NewNativeDbPrompter): Try last file, last import, last export folders,
then fall back to home.
svn: r3493
2004-08-24 03:35:55 +05:30
while os . path . isfile ( os . path . expanduser ( _NEW_NAME_PATTERN % ( folder , ix , ext ) ) ) :
2004-07-09 23:49:47 +05:30
ix = ix + 1
* src/Plugins.py: Add native_format flag to import plugin registration.
* src/ReadXML.py, src/ReadGedcom.py: Register as native formats
to prevent loading twice on File->Open.
* src/data/gramps.schemas: Add keys for last import and export dirs.
* src/GrampsCfg.py (get_last_import_dir, save_last_import_dir,
get_last_export_dir, save_last_export_dir): Add functions.
* src/Exportder.py (suggest_filename): Try last export and last
import folders before falling back to Home; (save): Save export folder.
* src/Utils.py (get_new_filename): Add optional folder argument.
* src/DbPrompter.py (ExistingDbPrompter.chooser): Only add
importers for non-native formats, the rest is already taken care of;
Try last file, last import, last export, then home folders;
(ImportDbPrompter.chooser): Save import folder; Try last import,
last file, last export, then home folders.
(NewNativeDbPrompter): Try last file, last import, last export folders,
then fall back to home.
svn: r3493
2004-08-24 03:35:55 +05:30
return os . path . expanduser ( _NEW_NAME_PATTERN % ( folder , ix , ext ) )
2004-12-22 07:26:37 +05:30
def get_type_converter ( val ) :
"""
Returns function that converts strings into the type of val .
"""
val_type = type ( val )
if val_type in ( str , unicode ) :
return unicode
elif val_type == int :
return int
elif val_type == float :
return float
elif val_type in ( list , tuple ) :
return list
def type_name ( val ) :
"""
Returns the name the type of val .
Only numbers and strings are supported .
The rest becomes strings ( unicode ) .
"""
val_type = type ( val )
if val_type == int :
return ' int '
elif val_type == float :
return ' float '
elif val_type in ( str , unicode ) :
return ' unicode '
return ' unicode '
def get_type_converter_by_name ( val_str ) :
"""
Returns function that converts strings into the type given by val_str .
Only numbers and strings are supported .
The rest becomes strings ( unicode ) .
"""
if val_str == ' int ' :
return int
elif val_str == ' float ' :
return float
elif val_str in ( ' str ' , ' unicode ' ) :
return unicode
return unicode