remove empty families
svn: r6293
This commit is contained in:
		@@ -1,3 +1,6 @@
 | 
			
		||||
2006-04-07  Don Allingham  <don@gramps-project.org>
 | 
			
		||||
	* src/Editors/_EditFamily.py: remove empty families
 | 
			
		||||
 | 
			
		||||
2006-04-07  Brian Matherly  <pez4brian@users.sourceforge.net>
 | 
			
		||||
	* src/docgen/PdfDoc.py: fix columns, error check images
 | 
			
		||||
	* src/docgen/RTFDoc.py: error check images
 | 
			
		||||
 
 | 
			
		||||
@@ -34,9 +34,9 @@ import Errors
 | 
			
		||||
from PluginUtils import ReportUtils
 | 
			
		||||
 | 
			
		||||
_GenderCode = {
 | 
			
		||||
    RelLib.Person.MALE    : u'\u2642',
 | 
			
		||||
    RelLib.Person.FEMALE  : u'\u2640',
 | 
			
		||||
    RelLib.Person.UNKNOWN : u'\u2650',
 | 
			
		||||
    RelLib.Person.MALE    : u'\u2642', 
 | 
			
		||||
    RelLib.Person.FEMALE  : u'\u2640', 
 | 
			
		||||
    RelLib.Person.UNKNOWN : u'\u2650', 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
_NAME_START   = 0
 | 
			
		||||
@@ -72,19 +72,20 @@ class AttachList:
 | 
			
		||||
        self.max_x = 0
 | 
			
		||||
        self.max_y = 0
 | 
			
		||||
 | 
			
		||||
    def attach(self,widget,x0,x1,y0,y1,xoptions=gtk.EXPAND|gtk.FILL,
 | 
			
		||||
    def attach(self, widget, x0, x1, y0, y1, xoptions=gtk.EXPAND|gtk.FILL, 
 | 
			
		||||
               yoptions=gtk.EXPAND|gtk.FILL):
 | 
			
		||||
        assert(x1>x0)
 | 
			
		||||
        self.list.append((widget,x0,x1,y0,y1,xoptions,yoptions))
 | 
			
		||||
        self.max_x = max(self.max_x,x1)
 | 
			
		||||
        self.max_y = max(self.max_y,y1)
 | 
			
		||||
        self.list.append((widget, x0, x1, y0, y1, xoptions, yoptions))
 | 
			
		||||
        self.max_x = max(self.max_x, x1)
 | 
			
		||||
        self.max_y = max(self.max_y, y1)
 | 
			
		||||
 | 
			
		||||
class FamilyView(PageView.PersonNavView):
 | 
			
		||||
 | 
			
		||||
    def __init__(self,dbstate,uistate):
 | 
			
		||||
        PageView.PersonNavView.__init__(self,'Relationship View',dbstate,uistate)
 | 
			
		||||
        dbstate.connect('database-changed',self.change_db)
 | 
			
		||||
        dbstate.connect('active-changed',self.change_person)
 | 
			
		||||
    def __init__(self, dbstate, uistate):
 | 
			
		||||
        
 | 
			
		||||
        PageView.PersonNavView.__init__(self, 'Relationship View', dbstate, uistate)
 | 
			
		||||
        dbstate.connect('database-changed', self.change_db)
 | 
			
		||||
        dbstate.connect('active-changed', self.change_person)
 | 
			
		||||
        self.show_siblings = Config.get_family_siblings()
 | 
			
		||||
        if self.show_siblings == None:
 | 
			
		||||
            self.show_siblings = True
 | 
			
		||||
@@ -95,15 +96,15 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
        self.redrawing = False
 | 
			
		||||
        self.child = None
 | 
			
		||||
            
 | 
			
		||||
    def connect_to_db(self,db):
 | 
			
		||||
    def connect_to_db(self, db):
 | 
			
		||||
        db.connect('person-update', self.person_update)
 | 
			
		||||
        db.connect('person-rebuild',self.person_rebuild)
 | 
			
		||||
        db.connect('person-rebuild', self.person_rebuild)
 | 
			
		||||
        db.connect('family-update', self.family_update)
 | 
			
		||||
        db.connect('family-add',    self.family_add)
 | 
			
		||||
        db.connect('family-delete', self.family_delete)
 | 
			
		||||
        db.connect('family-rebuild',self.family_rebuild)
 | 
			
		||||
        db.connect('family-rebuild', self.family_rebuild)
 | 
			
		||||
 | 
			
		||||
    def person_update(self,handle_list):
 | 
			
		||||
    def person_update(self, handle_list):
 | 
			
		||||
        if self.dbstate.active:
 | 
			
		||||
            while not self.change_person(self.dbstate.active.handle):
 | 
			
		||||
                pass
 | 
			
		||||
@@ -113,17 +114,17 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
            while not self.change_person(self.dbstate.active.handle):
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
    def family_update(self,handle_list):
 | 
			
		||||
    def family_update(self, handle_list):
 | 
			
		||||
        if self.dbstate.active:
 | 
			
		||||
            while not self.change_person(self.dbstate.active.handle):
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
    def family_add(self,handle_list):
 | 
			
		||||
    def family_add(self, handle_list):
 | 
			
		||||
        if self.dbstate.active:
 | 
			
		||||
            while not self.change_person(self.dbstate.active.handle):
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
    def family_delete(self,handle_list):
 | 
			
		||||
    def family_delete(self, handle_list):
 | 
			
		||||
        if self.dbstate.active:
 | 
			
		||||
            while not self.change_person(self.dbstate.active.handle):
 | 
			
		||||
                pass
 | 
			
		||||
@@ -143,7 +144,7 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
 | 
			
		||||
    def build_widget(self):
 | 
			
		||||
        self.scroll = gtk.ScrolledWindow()
 | 
			
		||||
        self.scroll.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
 | 
			
		||||
        self.scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 | 
			
		||||
        self.scroll.show()
 | 
			
		||||
        self.vbox = gtk.VBox()
 | 
			
		||||
        self.vbox.show()
 | 
			
		||||
@@ -190,36 +191,36 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
    def define_actions(self):
 | 
			
		||||
        PageView.PersonNavView.define_actions(self)
 | 
			
		||||
 | 
			
		||||
        self.add_toggle_action('Details', None, _('Show details'),
 | 
			
		||||
                               None, None, self.details_toggle,
 | 
			
		||||
        self.add_toggle_action('Details', None, _('Show details'), 
 | 
			
		||||
                               None, None, self.details_toggle, 
 | 
			
		||||
                               self.show_details)
 | 
			
		||||
        self.add_toggle_action('Siblings', None, _('Show siblings'),
 | 
			
		||||
                               None, None, self.siblings_toggle,
 | 
			
		||||
        self.add_toggle_action('Siblings', None, _('Show siblings'), 
 | 
			
		||||
                               None, None, self.siblings_toggle, 
 | 
			
		||||
                               self.show_siblings)
 | 
			
		||||
 | 
			
		||||
    def siblings_toggle(self,obj):
 | 
			
		||||
    def siblings_toggle(self, obj):
 | 
			
		||||
        self.show_siblings = obj.get_active()
 | 
			
		||||
        self.change_person(self.dbstate.active.handle)
 | 
			
		||||
        Config.save_family_siblings(self.show_siblings)
 | 
			
		||||
 | 
			
		||||
    def details_toggle(self,obj):
 | 
			
		||||
    def details_toggle(self, obj):
 | 
			
		||||
        self.show_details = obj.get_active()
 | 
			
		||||
        self.change_person(self.dbstate.active.handle)
 | 
			
		||||
        Config.save_family_details(self.show_details)
 | 
			
		||||
 | 
			
		||||
    def change_db(self,db):
 | 
			
		||||
    def change_db(self, db):
 | 
			
		||||
        self.connect_to_db(db)
 | 
			
		||||
        if self.child:
 | 
			
		||||
            self.vbox.remove(self.child)
 | 
			
		||||
            self.child = None
 | 
			
		||||
        self.dbstate.db.connect('family-update',self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('family-add',self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('family-delete',self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('person-update',self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('person-add',self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('person-delete',self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('family-update', self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('family-add', self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('family-delete', self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('person-update', self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('person-add', self.redraw)
 | 
			
		||||
        self.dbstate.db.connect('person-delete', self.redraw)
 | 
			
		||||
 | 
			
		||||
    def get_name(self,handle,use_gender=False):
 | 
			
		||||
    def get_name(self, handle, use_gender=False):
 | 
			
		||||
        if handle:
 | 
			
		||||
            p = self.dbstate.db.get_person_from_handle(handle)
 | 
			
		||||
            name = NameDisplay.displayer.display(p)
 | 
			
		||||
@@ -227,15 +228,15 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
                gender = _GenderCode[p.gender]
 | 
			
		||||
            else:
 | 
			
		||||
                gender = ""
 | 
			
		||||
            return (name,gender)
 | 
			
		||||
            return (name, gender)
 | 
			
		||||
        else:
 | 
			
		||||
            return (_(u"Unknown"),"")
 | 
			
		||||
            return (_(u"Unknown"), "")
 | 
			
		||||
 | 
			
		||||
    def redraw(self,*obj):
 | 
			
		||||
    def redraw(self, *obj):
 | 
			
		||||
        if self.dbstate.active:
 | 
			
		||||
            self.change_person(self.dbstate.active.handle)
 | 
			
		||||
        
 | 
			
		||||
    def change_person(self,obj):
 | 
			
		||||
    def change_person(self, obj):
 | 
			
		||||
        if self.redrawing:
 | 
			
		||||
            return False
 | 
			
		||||
        self.redrawing = True
 | 
			
		||||
@@ -251,11 +252,11 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
        self.row = 5
 | 
			
		||||
        family_handle_list = person.get_parent_family_handle_list()
 | 
			
		||||
        if family_handle_list:
 | 
			
		||||
            for (family_handle,mrel,frel) in family_handle_list:
 | 
			
		||||
            for (family_handle, mrel, frel) in family_handle_list:
 | 
			
		||||
                if family_handle:
 | 
			
		||||
                    self.write_parents(family_handle)
 | 
			
		||||
        else:
 | 
			
		||||
            self.write_label("%s:" % _('Parents'),None,True)
 | 
			
		||||
            self.write_label("%s:" % _('Parents'), None, True)
 | 
			
		||||
            self.row += 1
 | 
			
		||||
                
 | 
			
		||||
        family_handle_list = person.get_family_handle_list()
 | 
			
		||||
@@ -264,14 +265,14 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
                if family_handle:
 | 
			
		||||
                    self.write_family(family_handle)
 | 
			
		||||
        else:
 | 
			
		||||
            self.write_label("%s:" % _('Family'),None,False)
 | 
			
		||||
            self.write_label("%s:" % _('Family'), None, False)
 | 
			
		||||
            self.row += 1
 | 
			
		||||
 | 
			
		||||
        self.row = 1
 | 
			
		||||
        self.write_title(person)
 | 
			
		||||
 | 
			
		||||
        # Here it is necessary to beat GTK into submission. For some
 | 
			
		||||
        # bizzare reason, if you have an empty column that is spanned,
 | 
			
		||||
        # bizzare reason, if you have an empty column that is spanned, 
 | 
			
		||||
        # you lose the appropriate FILL handling. So, we need to see if
 | 
			
		||||
        # column 3 is unused (usually if there is no siblings or children.
 | 
			
		||||
        # If so, we need to subtract one index of each x coord > 3.
 | 
			
		||||
@@ -286,7 +287,7 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
        else:
 | 
			
		||||
            cols = self.attach.max_x-1
 | 
			
		||||
 | 
			
		||||
        self.child = gtk.Table(self.attach.max_y,cols)
 | 
			
		||||
        self.child = gtk.Table(self.attach.max_y, cols)
 | 
			
		||||
        self.child.set_border_width(12)
 | 
			
		||||
        self.child.set_col_spacings(12)
 | 
			
		||||
        self.child.set_row_spacings(9)
 | 
			
		||||
@@ -299,31 +300,31 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
                   x0 -= 1
 | 
			
		||||
                if x1 > 4:
 | 
			
		||||
                    x1 -= 1
 | 
			
		||||
            self.child.attach(d[0],x0,x1,d[3],d[4],d[5],d[6])
 | 
			
		||||
            self.child.attach(d[0], x0, x1, d[3], d[4], d[5], d[6])
 | 
			
		||||
 | 
			
		||||
        self.child.show_all()
 | 
			
		||||
        if old_child:
 | 
			
		||||
            self.vbox.remove(old_child)
 | 
			
		||||
 | 
			
		||||
        self.vbox.pack_start(self.child,False)
 | 
			
		||||
        self.vbox.pack_start(self.child, False)
 | 
			
		||||
        self.redrawing = False
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def write_title(self,person):
 | 
			
		||||
    def write_title(self, person):
 | 
			
		||||
 | 
			
		||||
        # name and edit button
 | 
			
		||||
        name = NameDisplay.displayer.display(person)
 | 
			
		||||
        fmt = '<span size="larger" weight="bold">%s %s</span>'
 | 
			
		||||
        text = fmt % (cgi.escape(name),_GenderCode[person.gender])
 | 
			
		||||
        text = fmt % (cgi.escape(name), _GenderCode[person.gender])
 | 
			
		||||
        label = GrampsWidgets.MarkupLabel(text)
 | 
			
		||||
        button = GrampsWidgets.IconButton(self.edit_button_press,person.handle)
 | 
			
		||||
        button = GrampsWidgets.IconButton(self.edit_button_press, person.handle)
 | 
			
		||||
 | 
			
		||||
        hbox = GrampsWidgets.LinkBox(label,button)
 | 
			
		||||
        hbox = GrampsWidgets.LinkBox(label, button)
 | 
			
		||||
                
 | 
			
		||||
        # GRAMPS ID
 | 
			
		||||
        self.row = 1
 | 
			
		||||
 | 
			
		||||
        self.write_person_data("%s:" % _('ID'),person.gramps_id)
 | 
			
		||||
        self.write_person_data("%s:" % _('ID'), person.gramps_id)
 | 
			
		||||
 | 
			
		||||
        # birth/death events
 | 
			
		||||
 | 
			
		||||
@@ -332,20 +333,20 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
            birth = self.dbstate.db.get_event_from_handle(birth_ref.ref)
 | 
			
		||||
        else:
 | 
			
		||||
            birth = None
 | 
			
		||||
        self.write_person_event("%s:" % _('Birth'),birth)
 | 
			
		||||
        self.write_person_event("%s:" % _('Birth'), birth)
 | 
			
		||||
        
 | 
			
		||||
        death_ref = person.get_death_ref()
 | 
			
		||||
        if death_ref:
 | 
			
		||||
            death = self.dbstate.db.get_event_from_handle(death_ref.ref)
 | 
			
		||||
        else:
 | 
			
		||||
            death = None
 | 
			
		||||
        self.write_person_event("%s:" % _('Death'),death)
 | 
			
		||||
        self.write_person_event("%s:" % _('Death'), death)
 | 
			
		||||
 | 
			
		||||
        # separator
 | 
			
		||||
        end = self.attach.max_x
 | 
			
		||||
        sep = gtk.HSeparator()
 | 
			
		||||
        sep.show()
 | 
			
		||||
        self.attach.attach(hbox,_NAME_START,end,0,1,gtk.FILL|gtk.EXPAND)
 | 
			
		||||
        self.attach.attach(hbox, _NAME_START, end, 0, 1, gtk.FILL|gtk.EXPAND)
 | 
			
		||||
 | 
			
		||||
        # image
 | 
			
		||||
        image_list = person.get_media_list()
 | 
			
		||||
@@ -356,10 +357,10 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
                image = gtk.Image()
 | 
			
		||||
                image.set_from_pixbuf(pixbuf)
 | 
			
		||||
                image.show()
 | 
			
		||||
                self.attach.attach(image,end,end+1,0,4,
 | 
			
		||||
                self.attach.attach(image, end, end+1, 0, 4, 
 | 
			
		||||
                                   xoptions=gtk.SHRINK|gtk.FILL)
 | 
			
		||||
 | 
			
		||||
        self.attach.attach(sep,0,self.attach.max_x,4,5)
 | 
			
		||||
        self.attach.attach(sep, 0, self.attach.max_x, 4, 5)
 | 
			
		||||
 | 
			
		||||
    def write_person_event(self, ename, event):
 | 
			
		||||
        if event:
 | 
			
		||||
@@ -372,8 +373,8 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
            date_str = DateHandler.displayer.display(dobj)
 | 
			
		||||
 | 
			
		||||
            value = {
 | 
			
		||||
                'date' : DateHandler.displayer.display(dobj),
 | 
			
		||||
                'place' : pname,
 | 
			
		||||
                'date' : DateHandler.displayer.display(dobj), 
 | 
			
		||||
                'place' : pname, 
 | 
			
		||||
                }
 | 
			
		||||
        else:
 | 
			
		||||
            pname = None
 | 
			
		||||
@@ -381,37 +382,37 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
 | 
			
		||||
        if dobj:
 | 
			
		||||
            if pname:
 | 
			
		||||
                self.write_person_data(ename,
 | 
			
		||||
                self.write_person_data(ename, 
 | 
			
		||||
                                       _('%(date)s in %(place)s') % value)
 | 
			
		||||
            else:
 | 
			
		||||
                self.write_person_data(ename,'%(date)s' % value)
 | 
			
		||||
                self.write_person_data(ename, '%(date)s' % value)
 | 
			
		||||
        elif pname:
 | 
			
		||||
            self.write_person_data(ename,pname)
 | 
			
		||||
            self.write_person_data(ename, pname)
 | 
			
		||||
        else:
 | 
			
		||||
            self.write_person_data(ename,'')
 | 
			
		||||
            self.write_person_data(ename, '')
 | 
			
		||||
 | 
			
		||||
    def write_person_data(self,title,data):
 | 
			
		||||
        self.attach.attach(GrampsWidgets.BasicLabel(title),_ALABEL_START,
 | 
			
		||||
                           _ALABEL_STOP,self.row,self.row+1,
 | 
			
		||||
    def write_person_data(self, title, data):
 | 
			
		||||
        self.attach.attach(GrampsWidgets.BasicLabel(title), _ALABEL_START, 
 | 
			
		||||
                           _ALABEL_STOP, self.row, self.row+1, 
 | 
			
		||||
                           xoptions=gtk.FILL|gtk.SHRINK)
 | 
			
		||||
        self.attach.attach(GrampsWidgets.BasicLabel(data),
 | 
			
		||||
                           _ADATA_START,_ADATA_STOP,
 | 
			
		||||
                           self.row,self.row+1)
 | 
			
		||||
        self.attach.attach(GrampsWidgets.BasicLabel(data), 
 | 
			
		||||
                           _ADATA_START, _ADATA_STOP, 
 | 
			
		||||
                           self.row, self.row+1)
 | 
			
		||||
        self.row += 1
 | 
			
		||||
 | 
			
		||||
    def write_label(self,title,family,is_parent):
 | 
			
		||||
    def write_label(self, title, family, is_parent):
 | 
			
		||||
        msg = "<i><b>%s</b></i>" % cgi.escape(title)
 | 
			
		||||
        self.attach.attach(GrampsWidgets.MarkupLabel(msg),
 | 
			
		||||
                           _LABEL_START,_LABEL_STOP,
 | 
			
		||||
                           self.row,self.row+1,gtk.SHRINK|gtk.FILL)
 | 
			
		||||
        self.attach.attach(GrampsWidgets.MarkupLabel(msg), 
 | 
			
		||||
                           _LABEL_START, _LABEL_STOP, 
 | 
			
		||||
                           self.row, self.row+1, gtk.SHRINK|gtk.FILL)
 | 
			
		||||
 | 
			
		||||
        if family:
 | 
			
		||||
            value = family.gramps_id
 | 
			
		||||
        else:
 | 
			
		||||
            value = ""
 | 
			
		||||
        self.attach.attach(GrampsWidgets.BasicLabel(value),
 | 
			
		||||
                           _DATA_START,_DATA_STOP,
 | 
			
		||||
                           self.row,self.row+1,gtk.SHRINK|gtk.FILL)
 | 
			
		||||
        self.attach.attach(GrampsWidgets.BasicLabel(value), 
 | 
			
		||||
                           _DATA_START, _DATA_STOP, 
 | 
			
		||||
                           self.row, self.row+1, gtk.SHRINK|gtk.FILL)
 | 
			
		||||
 | 
			
		||||
        hbox = gtk.HBox()
 | 
			
		||||
        hbox.set_spacing(12)
 | 
			
		||||
@@ -422,42 +423,42 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
            call_fcn = self.add_family
 | 
			
		||||
            del_fcn = self.delete_family
 | 
			
		||||
            
 | 
			
		||||
        add = GrampsWidgets.IconButton(call_fcn,None,gtk.STOCK_ADD)
 | 
			
		||||
        hbox.pack_start(add,False)
 | 
			
		||||
        add = GrampsWidgets.IconButton(call_fcn, None, gtk.STOCK_ADD)
 | 
			
		||||
        hbox.pack_start(add, False)
 | 
			
		||||
 | 
			
		||||
        if is_parent:
 | 
			
		||||
            add = GrampsWidgets.IconButton(self.select_family,None,gtk.STOCK_INDEX)
 | 
			
		||||
            hbox.pack_start(add,False)
 | 
			
		||||
            add = GrampsWidgets.IconButton(self.select_family, None, gtk.STOCK_INDEX)
 | 
			
		||||
            hbox.pack_start(add, False)
 | 
			
		||||
 | 
			
		||||
        if family:
 | 
			
		||||
            edit = GrampsWidgets.IconButton(self.edit_family,family.handle,
 | 
			
		||||
            edit = GrampsWidgets.IconButton(self.edit_family, family.handle, 
 | 
			
		||||
                                            gtk.STOCK_EDIT)
 | 
			
		||||
            hbox.pack_start(edit,False)
 | 
			
		||||
            delete = GrampsWidgets.IconButton(del_fcn,family.handle,
 | 
			
		||||
            hbox.pack_start(edit, False)
 | 
			
		||||
            delete = GrampsWidgets.IconButton(del_fcn, family.handle, 
 | 
			
		||||
                                              gtk.STOCK_REMOVE)
 | 
			
		||||
            hbox.pack_start(delete,False)
 | 
			
		||||
        self.attach.attach(hbox,_BTN_START,_BTN_STOP,self.row,self.row+1)
 | 
			
		||||
            hbox.pack_start(delete, False)
 | 
			
		||||
        self.attach.attach(hbox, _BTN_START, _BTN_STOP, self.row, self.row+1)
 | 
			
		||||
        self.row += 1
 | 
			
		||||
        
 | 
			
		||||
######################################################################
 | 
			
		||||
 | 
			
		||||
    def write_parents(self,family_handle):
 | 
			
		||||
    def write_parents(self, family_handle):
 | 
			
		||||
        family = self.dbstate.db.get_family_from_handle(family_handle)
 | 
			
		||||
        if not family:
 | 
			
		||||
            return
 | 
			
		||||
        self.write_label("%s:" % _('Parents'),family,True),
 | 
			
		||||
        self.write_person(_('Father'),family.get_father_handle())
 | 
			
		||||
        self.write_label("%s:" % _('Parents'), family, True), 
 | 
			
		||||
        self.write_person(_('Father'), family.get_father_handle())
 | 
			
		||||
        if self.show_details:
 | 
			
		||||
            value = self.info_string(family.get_father_handle())
 | 
			
		||||
            if value:
 | 
			
		||||
                self.attach.attach(GrampsWidgets.BasicLabel(value),_PDTLS_START,
 | 
			
		||||
                                   _PDTLS_STOP,self.row, self.row+1)
 | 
			
		||||
                self.attach.attach(GrampsWidgets.BasicLabel(value), _PDTLS_START, 
 | 
			
		||||
                                   _PDTLS_STOP, self.row, self.row+1)
 | 
			
		||||
                self.row += 1
 | 
			
		||||
        self.write_person(_('Mother'),family.get_mother_handle())
 | 
			
		||||
        self.write_person(_('Mother'), family.get_mother_handle())
 | 
			
		||||
        if self.show_details:
 | 
			
		||||
            value = self.info_string(family.get_mother_handle())
 | 
			
		||||
            if value:
 | 
			
		||||
                self.attach.attach(GrampsWidgets.BasicLabel(value),_PDTLS_START,
 | 
			
		||||
                self.attach.attach(GrampsWidgets.BasicLabel(value), _PDTLS_START, 
 | 
			
		||||
                                   _PDTLS_STOP, self.row, self.row+1)
 | 
			
		||||
                self.row += 1
 | 
			
		||||
 | 
			
		||||
@@ -469,50 +470,50 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
            label = _("Siblings")
 | 
			
		||||
            if child_list:
 | 
			
		||||
                for child in child_list:
 | 
			
		||||
                    self.write_child(label,child)
 | 
			
		||||
                    self.write_child(label, child)
 | 
			
		||||
                    label = u""
 | 
			
		||||
        self.row += 1
 | 
			
		||||
 | 
			
		||||
    def write_person(self,title,handle):
 | 
			
		||||
    def write_person(self, title, handle):
 | 
			
		||||
        if title:
 | 
			
		||||
            format = '<span weight="bold">%s: </span>'
 | 
			
		||||
        else:
 | 
			
		||||
            format = "%s"
 | 
			
		||||
 | 
			
		||||
        label = GrampsWidgets.MarkupLabel(format % cgi.escape(title))
 | 
			
		||||
        self.attach.attach(label,_PLABEL_START,_PLABEL_STOP,self.row,
 | 
			
		||||
        self.attach.attach(label, _PLABEL_START, _PLABEL_STOP, self.row, 
 | 
			
		||||
                           self.row+1, xoptions=gtk.FILL|gtk.SHRINK)
 | 
			
		||||
 | 
			
		||||
        if handle:
 | 
			
		||||
            link_label = GrampsWidgets.LinkLabel(self.get_name(handle,True),
 | 
			
		||||
                                                 self.button_press,handle)
 | 
			
		||||
            button = GrampsWidgets.IconButton(self.edit_button_press,handle)
 | 
			
		||||
            self.attach.attach(GrampsWidgets.LinkBox(link_label,button),
 | 
			
		||||
                               _PDATA_START,_PDATA_STOP,self.row,self.row+1)
 | 
			
		||||
            link_label = GrampsWidgets.LinkLabel(self.get_name(handle, True), 
 | 
			
		||||
                                                 self.button_press, handle)
 | 
			
		||||
            button = GrampsWidgets.IconButton(self.edit_button_press, handle)
 | 
			
		||||
            self.attach.attach(GrampsWidgets.LinkBox(link_label, button), 
 | 
			
		||||
                               _PDATA_START, _PDATA_STOP, self.row, self.row+1)
 | 
			
		||||
        else:
 | 
			
		||||
            link_label = gtk.Label(_('Unknown'))
 | 
			
		||||
            link_label.set_alignment(0,0.5)
 | 
			
		||||
            link_label.set_alignment(0, 0.5)
 | 
			
		||||
            link_label.show()
 | 
			
		||||
            self.attach.attach(link_label,
 | 
			
		||||
                               _PDATA_START,_PDATA_STOP,self.row,self.row+1)
 | 
			
		||||
            self.attach.attach(link_label, 
 | 
			
		||||
                               _PDATA_START, _PDATA_STOP, self.row, self.row+1)
 | 
			
		||||
            
 | 
			
		||||
        self.row += 1
 | 
			
		||||
 | 
			
		||||
    def write_child(self,title,handle):
 | 
			
		||||
    def write_child(self, title, handle):
 | 
			
		||||
        if title:
 | 
			
		||||
            format = '<span weight="bold">%s: </span>'
 | 
			
		||||
        else:
 | 
			
		||||
            format = "%s"
 | 
			
		||||
 | 
			
		||||
        label = GrampsWidgets.MarkupLabel(format % cgi.escape(title))
 | 
			
		||||
        self.attach.attach(label,_CLABEL_START,_CLABEL_STOP,self.row,
 | 
			
		||||
                           self.row+1,xoptions=gtk.FILL|gtk.SHRINK)
 | 
			
		||||
        self.attach.attach(label, _CLABEL_START, _CLABEL_STOP, self.row, 
 | 
			
		||||
                           self.row+1, xoptions=gtk.FILL|gtk.SHRINK)
 | 
			
		||||
 | 
			
		||||
        link_label = GrampsWidgets.LinkLabel(self.get_name(handle,True),
 | 
			
		||||
                                             self.button_press,handle)
 | 
			
		||||
        button = GrampsWidgets.IconButton(self.edit_button_press,handle)
 | 
			
		||||
        self.attach.attach(GrampsWidgets.LinkBox(link_label,button),
 | 
			
		||||
                           _CDATA_START, _CDATA_STOP, self.row, self.row+1,
 | 
			
		||||
        link_label = GrampsWidgets.LinkLabel(self.get_name(handle, True), 
 | 
			
		||||
                                             self.button_press, handle)
 | 
			
		||||
        button = GrampsWidgets.IconButton(self.edit_button_press, handle)
 | 
			
		||||
        self.attach.attach(GrampsWidgets.LinkBox(link_label, button), 
 | 
			
		||||
                           _CDATA_START, _CDATA_STOP, self.row, self.row+1, 
 | 
			
		||||
                           xoptions=gtk.EXPAND|gtk.FILL)
 | 
			
		||||
 | 
			
		||||
        self.row += 1
 | 
			
		||||
@@ -520,17 +521,17 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
        if self.show_details:
 | 
			
		||||
            value = self.info_string(handle)
 | 
			
		||||
            if value:
 | 
			
		||||
                self.attach.attach(GrampsWidgets.BasicLabel(value),
 | 
			
		||||
                                   _CDTLS_START, _CDTLS_STOP, self.row,
 | 
			
		||||
                self.attach.attach(GrampsWidgets.BasicLabel(value), 
 | 
			
		||||
                                   _CDTLS_START, _CDTLS_STOP, self.row, 
 | 
			
		||||
                                   self.row+1)
 | 
			
		||||
                self.row += 1
 | 
			
		||||
        
 | 
			
		||||
    def write_data(self,title,start_col=_SDATA_START,stop_col=_SDATA_STOP):
 | 
			
		||||
        self.attach.attach(GrampsWidgets.BasicLabel(title),start_col,stop_col,
 | 
			
		||||
    def write_data(self, title, start_col=_SDATA_START, stop_col=_SDATA_STOP):
 | 
			
		||||
        self.attach.attach(GrampsWidgets.BasicLabel(title), start_col, stop_col, 
 | 
			
		||||
                           self.row, self.row+1, xoptions=gtk.EXPAND|gtk.FILL)
 | 
			
		||||
        self.row += 1
 | 
			
		||||
 | 
			
		||||
    def info_string(self,handle):
 | 
			
		||||
    def info_string(self, handle):
 | 
			
		||||
        child = self.dbstate.db.get_person_from_handle(handle)
 | 
			
		||||
        if not child:
 | 
			
		||||
            return None
 | 
			
		||||
@@ -538,22 +539,22 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
        death_ref = child.get_death_ref()
 | 
			
		||||
        value = None
 | 
			
		||||
        if birth_ref or death_ref:
 | 
			
		||||
            info = ReportUtils.get_birth_death_strings(self.dbstate.db,child)
 | 
			
		||||
            info = ReportUtils.get_birth_death_strings(self.dbstate.db, child)
 | 
			
		||||
            bdate = info[0]
 | 
			
		||||
            ddate = info[4]
 | 
			
		||||
            if bdate and ddate:
 | 
			
		||||
                value = _("b. %s, d. %s") % (bdate,ddate)
 | 
			
		||||
                value = _("b. %s, d. %s") % (bdate, ddate)
 | 
			
		||||
            elif bdate:
 | 
			
		||||
                value = _("b. %s") % (bdate)
 | 
			
		||||
            elif ddate:
 | 
			
		||||
                value = _("d. %s") % (ddate)
 | 
			
		||||
        return value
 | 
			
		||||
 | 
			
		||||
    def button_press(self,obj,event,handle):
 | 
			
		||||
    def button_press(self, obj, event, handle):
 | 
			
		||||
        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
 | 
			
		||||
            self.dbstate.change_active_handle(handle)
 | 
			
		||||
 | 
			
		||||
    def write_relationship(self,family):
 | 
			
		||||
    def write_relationship(self, family):
 | 
			
		||||
        rtype = family.get_relationship()
 | 
			
		||||
        if type(rtype) == tuple:
 | 
			
		||||
            if rtype[0] == RelLib.Family.CUSTOM:
 | 
			
		||||
@@ -564,22 +565,22 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
            rel_text = Utils.family_relations[rtype]
 | 
			
		||||
        self.write_data(_('Relationship type: %s') % rel_text)
 | 
			
		||||
 | 
			
		||||
    def place_name(self,handle):
 | 
			
		||||
    def place_name(self, handle):
 | 
			
		||||
        p = self.dbstate.db.get_place_from_handle(handle)
 | 
			
		||||
        return p.get_title()
 | 
			
		||||
 | 
			
		||||
    def write_marriage(self,family):
 | 
			
		||||
    def write_marriage(self, family):
 | 
			
		||||
        value = False
 | 
			
		||||
        for event_ref in family.get_event_ref_list():
 | 
			
		||||
            handle = event_ref.ref
 | 
			
		||||
            event = self.dbstate.db.get_event_from_handle(handle)
 | 
			
		||||
            etype = event.get_type()
 | 
			
		||||
            if etype[0] == RelLib.Event.MARRIAGE:
 | 
			
		||||
                self.write_event_ref(_('Marriage'),event)
 | 
			
		||||
                self.write_event_ref(_('Marriage'), event)
 | 
			
		||||
                value = True
 | 
			
		||||
        return value
 | 
			
		||||
 | 
			
		||||
    def write_event_ref(self, ename, event, start_col=_SDATA_START,
 | 
			
		||||
    def write_event_ref(self, ename, event, start_col=_SDATA_START, 
 | 
			
		||||
                        stop_col=_SDATA_STOP):
 | 
			
		||||
        if event:
 | 
			
		||||
            dobj = event.get_date_object()
 | 
			
		||||
@@ -591,9 +592,9 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
            date_str = DateHandler.displayer.display(dobj)
 | 
			
		||||
 | 
			
		||||
            value = {
 | 
			
		||||
                'date' : DateHandler.displayer.display(dobj),
 | 
			
		||||
                'place' : pname,
 | 
			
		||||
                'event_type' : ename,
 | 
			
		||||
                'date' : DateHandler.displayer.display(dobj), 
 | 
			
		||||
                'place' : pname, 
 | 
			
		||||
                'event_type' : ename, 
 | 
			
		||||
                }
 | 
			
		||||
        else:
 | 
			
		||||
            pname = None
 | 
			
		||||
@@ -603,18 +604,18 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
        if dobj:
 | 
			
		||||
            if pname:
 | 
			
		||||
                self.write_data(_('%(event_type)s: %(date)s in %(place)s') %
 | 
			
		||||
                                value,start_col,stop_col)
 | 
			
		||||
                                value, start_col, stop_col)
 | 
			
		||||
            else:
 | 
			
		||||
                self.write_data(_('%(event_type)s: %(date)s') % value,
 | 
			
		||||
                self.write_data(_('%(event_type)s: %(date)s') % value, 
 | 
			
		||||
                                start_col, stop_col)
 | 
			
		||||
        elif pname:
 | 
			
		||||
            self.write_data(_('%(event_type)s: %(place)s') % value,
 | 
			
		||||
                            start_col,stop_col)
 | 
			
		||||
            self.write_data(_('%(event_type)s: %(place)s') % value, 
 | 
			
		||||
                            start_col, stop_col)
 | 
			
		||||
        else:
 | 
			
		||||
            self.write_data(_('%(event_type)s:') % value,
 | 
			
		||||
            self.write_data(_('%(event_type)s:') % value, 
 | 
			
		||||
                            start_col, stop_col)
 | 
			
		||||
 | 
			
		||||
    def write_family(self,family_handle):
 | 
			
		||||
    def write_family(self, family_handle):
 | 
			
		||||
        family = self.dbstate.db.get_family_from_handle(family_handle)
 | 
			
		||||
        father_handle = family.get_father_handle()
 | 
			
		||||
        mother_handle = family.get_mother_handle()
 | 
			
		||||
@@ -623,14 +624,14 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
        else:
 | 
			
		||||
            handle = father_handle
 | 
			
		||||
 | 
			
		||||
        self.write_label("%s:" % _('Family'),family,False)
 | 
			
		||||
        self.write_label("%s:" % _('Family'), family, False)
 | 
			
		||||
        if handle:
 | 
			
		||||
            self.write_person(_('Spouse'),handle)
 | 
			
		||||
            self.write_person(_('Spouse'), handle)
 | 
			
		||||
 | 
			
		||||
            value = self.info_string(handle)
 | 
			
		||||
            if value:
 | 
			
		||||
                self.attach.attach(GrampsWidgets.BasicLabel(value),
 | 
			
		||||
                                   _PDTLS_START, _PDTLS_STOP,
 | 
			
		||||
                self.attach.attach(GrampsWidgets.BasicLabel(value), 
 | 
			
		||||
                                   _PDTLS_START, _PDTLS_STOP, 
 | 
			
		||||
                                   self.row, self.row+1)
 | 
			
		||||
                self.row += 1
 | 
			
		||||
            if not self.write_marriage(family):
 | 
			
		||||
@@ -640,7 +641,7 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
        label = _("Children")
 | 
			
		||||
        if child_list:
 | 
			
		||||
            for child in child_list:
 | 
			
		||||
                self.write_child(label,child)
 | 
			
		||||
                self.write_child(label, child)
 | 
			
		||||
                label = u""
 | 
			
		||||
 | 
			
		||||
        self.row += 1
 | 
			
		||||
@@ -654,7 +655,7 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
            except Errors.WindowActiveError:
 | 
			
		||||
                pass
 | 
			
		||||
        
 | 
			
		||||
    def edit_person(self,obj,handle):
 | 
			
		||||
    def edit_person(self, obj, handle):
 | 
			
		||||
        from Editors import EditPerson
 | 
			
		||||
        person = self.dbstate.db.get_person_from_handle(handle)
 | 
			
		||||
        try:
 | 
			
		||||
@@ -662,16 +663,16 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
        except Errors.WindowActiveError:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
    def edit_family(self,obj,event,handle):
 | 
			
		||||
    def edit_family(self, obj, event, handle):
 | 
			
		||||
        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
 | 
			
		||||
            from Editors import EditFamily
 | 
			
		||||
            family = self.dbstate.db.get_family_from_handle(handle)
 | 
			
		||||
            try:
 | 
			
		||||
                EditFamily(self.dbstate,self.uistate,[],family)
 | 
			
		||||
                EditFamily(self.dbstate, self.uistate, [], family)
 | 
			
		||||
            except Errors.WindowActiveError:
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
    def add_family(self,obj,event,handle):
 | 
			
		||||
    def add_family(self, obj, event, handle):
 | 
			
		||||
        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
 | 
			
		||||
            from Editors import EditFamily
 | 
			
		||||
            family = RelLib.Family()
 | 
			
		||||
@@ -683,7 +684,7 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
                family.set_mother_handle(person.handle)
 | 
			
		||||
                
 | 
			
		||||
            try:
 | 
			
		||||
                EditFamily(self.dbstate,self.uistate,[],family)
 | 
			
		||||
                EditFamily(self.dbstate, self.uistate, [], family)
 | 
			
		||||
            except Errors.WindowActiveError:
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
@@ -700,16 +701,16 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
                family.add_child_handle(person.handle)
 | 
			
		||||
                
 | 
			
		||||
                person.add_parent_family_handle(
 | 
			
		||||
                    family.handle,
 | 
			
		||||
                    (RelLib.Person.CHILD_BIRTH,''),
 | 
			
		||||
                    (RelLib.Person.CHILD_BIRTH,''))
 | 
			
		||||
                    family.handle, 
 | 
			
		||||
                    (RelLib.Person.CHILD_BIRTH, ''), 
 | 
			
		||||
                    (RelLib.Person.CHILD_BIRTH, ''))
 | 
			
		||||
                
 | 
			
		||||
                trans = self.dbstate.db.transaction_begin()
 | 
			
		||||
                self.dbstate.db.commit_person(person,trans)
 | 
			
		||||
                self.dbstate.db.commit_family(family,trans)
 | 
			
		||||
                self.dbstate.db.transaction_commit(trans,_("Add Family"))
 | 
			
		||||
                self.dbstate.db.commit_person(person, trans)
 | 
			
		||||
                self.dbstate.db.commit_family(family, trans)
 | 
			
		||||
                self.dbstate.db.transaction_commit(trans, _("Add Family"))
 | 
			
		||||
            
 | 
			
		||||
    def add_parent_family(self,obj,event,handle):
 | 
			
		||||
    def add_parent_family(self, obj, event, handle):
 | 
			
		||||
        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
 | 
			
		||||
            from Editors import EditFamily
 | 
			
		||||
            family = RelLib.Family()
 | 
			
		||||
@@ -718,24 +719,24 @@ class FamilyView(PageView.PersonNavView):
 | 
			
		||||
            family.add_child_handle(person.handle)
 | 
			
		||||
                
 | 
			
		||||
            try:
 | 
			
		||||
                EditFamily(self.dbstate,self.uistate,[],family)
 | 
			
		||||
                EditFamily(self.dbstate, self.uistate, [], family)
 | 
			
		||||
            except Errors.WindowActiveError:
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
    def delete_family(self,obj,event,handle):
 | 
			
		||||
    def delete_family(self, obj, event, handle):
 | 
			
		||||
        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
 | 
			
		||||
            import GrampsDb
 | 
			
		||||
            GrampsDb.remove_parent_from_family(self.dbstate.db,
 | 
			
		||||
                                               self.dbstate.active.handle,
 | 
			
		||||
            GrampsDb.remove_parent_from_family(self.dbstate.db, 
 | 
			
		||||
                                               self.dbstate.active.handle, 
 | 
			
		||||
                                               handle)
 | 
			
		||||
 | 
			
		||||
    def delete_parent_family(self,obj,event,handle):
 | 
			
		||||
    def delete_parent_family(self, obj, event, handle):
 | 
			
		||||
        if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
 | 
			
		||||
            import GrampsDb
 | 
			
		||||
            GrampsDb.remove_child_from_family(self.dbstate.db,
 | 
			
		||||
                                              self.dbstate.active.handle,
 | 
			
		||||
            GrampsDb.remove_child_from_family(self.dbstate.db, 
 | 
			
		||||
                                              self.dbstate.active.handle, 
 | 
			
		||||
                                              handle)
 | 
			
		||||
 | 
			
		||||
    def change_to(self,obj,handle):
 | 
			
		||||
    def change_to(self, obj, handle):
 | 
			
		||||
        self.dbstate.change_active_handle(handle)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -335,7 +335,8 @@ class FastFemaleFilter:
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class EditFamily(EditPrimary):
 | 
			
		||||
 | 
			
		||||
    def __init__(self,dbstate,uistate,track,family):
 | 
			
		||||
    def __init__(self,dbstate, uistate, track, family):
 | 
			
		||||
        
 | 
			
		||||
        EditPrimary.__init__(self, dbstate, uistate, track,
 | 
			
		||||
                             family, dbstate.db.get_family_from_handle)
 | 
			
		||||
 | 
			
		||||
@@ -765,7 +766,13 @@ class EditFamily(EditPrimary):
 | 
			
		||||
                    person.family_list.append(self.obj.handle)
 | 
			
		||||
                self.db.commit_person(person,trans)
 | 
			
		||||
 | 
			
		||||
    def object_is_empty(self):
 | 
			
		||||
        return self.obj.get_father_handle() == None and \
 | 
			
		||||
               self.obj.get_mother_handle() == None and \
 | 
			
		||||
               len(self.obj.get_child_handle_list()) == 0
 | 
			
		||||
 | 
			
		||||
    def save(self,*obj):
 | 
			
		||||
 | 
			
		||||
        if not self.added:
 | 
			
		||||
            original = self.db.get_family_from_handle(self.obj.handle)
 | 
			
		||||
        else:
 | 
			
		||||
@@ -806,6 +813,10 @@ class EditFamily(EditPrimary):
 | 
			
		||||
                        _("No data exists for this family. Please "
 | 
			
		||||
                          "enter data or cancel the edit."))
 | 
			
		||||
            return
 | 
			
		||||
        elif original and self.object_is_empty():
 | 
			
		||||
            trans = self.db.transaction_begin()
 | 
			
		||||
            self.db.remove_family(self.obj.handle,trans)
 | 
			
		||||
            self.db.transaction_commit(trans,_("Remove Family"))
 | 
			
		||||
        elif cmp(original.serialize(),self.obj.serialize()):
 | 
			
		||||
 | 
			
		||||
            trans = self.db.transaction_begin()
 | 
			
		||||
@@ -838,5 +849,6 @@ class EditFamily(EditPrimary):
 | 
			
		||||
            else:
 | 
			
		||||
                self.db.commit_family(self.obj,trans)
 | 
			
		||||
            self.db.transaction_commit(trans,_("Edit Family"))
 | 
			
		||||
 | 
			
		||||
        self.close_window()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,21 +5,28 @@
 | 
			
		||||
#
 | 
			
		||||
# 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
 | 
			
		||||
# 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, 
 | 
			
		||||
# 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
 | 
			
		||||
# along with this program; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# $Id$
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
TreeModel for the GRAMPS Person tree.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
__author__ = "Donald N. Allingham"
 | 
			
		||||
__revision__ = "$Revision:$"
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# Standard python modules
 | 
			
		||||
@@ -77,32 +84,38 @@ _codeset = GrampsLocale.codeset
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
_ID_COL    = 1
 | 
			
		||||
_GENDER_COL= 2
 | 
			
		||||
_NAME_COL  = 3
 | 
			
		||||
_DEATH_COL = 6
 | 
			
		||||
_BIRTH_COL = 7
 | 
			
		||||
_EVENT_COL = 8
 | 
			
		||||
_FAMILY_COL= 9
 | 
			
		||||
_CHANGE_COL= 19
 | 
			
		||||
_MARKER_COL= 20
 | 
			
		||||
_ID_COL     = 1
 | 
			
		||||
_GENDER_COL = 2
 | 
			
		||||
_NAME_COL   = 3
 | 
			
		||||
_DEATH_COL  = 6
 | 
			
		||||
_BIRTH_COL  = 7
 | 
			
		||||
_EVENT_COL  = 8
 | 
			
		||||
_FAMILY_COL = 9
 | 
			
		||||
_CHANGE_COL = 19
 | 
			
		||||
_MARKER_COL = 20
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# python 2.3 has a bug in the unicode sorting using locale.strcoll. Seems
 | 
			
		||||
# to have a buffer overrun. We can convince it to do the right thing by
 | 
			
		||||
# forcing the string to be nul terminated,sorting,then stripping off the
 | 
			
		||||
# forcing the string to be nul terminated, sorting, then stripping off the
 | 
			
		||||
# nul.
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
if sys.version_info[0:2] == (2, 3):
 | 
			
		||||
    def locale_sort(mylist):
 | 
			
		||||
        mylist = map(lambda x: x + "\x00",mylist)
 | 
			
		||||
        """
 | 
			
		||||
        Sort version to get around a python2.3 bug with unicode strings
 | 
			
		||||
        """
 | 
			
		||||
        mylist = [ value + "\x00" for value in mylist ]
 | 
			
		||||
        mylist.sort(locale.strcoll)
 | 
			
		||||
        return map(lambda x: x[:-1],mylist)
 | 
			
		||||
        return [ value[:-1] for value in mylist ]
 | 
			
		||||
else:
 | 
			
		||||
    def locale_sort(mylist):
 | 
			
		||||
        """
 | 
			
		||||
        Normal sort routine
 | 
			
		||||
        """
 | 
			
		||||
        mylist.sort(locale.strcoll)
 | 
			
		||||
        return mylist
 | 
			
		||||
 | 
			
		||||
@@ -112,8 +125,15 @@ else:
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
    """
 | 
			
		||||
    Basic GenericTreeModel interface to handle the Tree interface for
 | 
			
		||||
    the PersonView
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, db, data_filter=None, invert_result=False, skip=[]):
 | 
			
		||||
        """
 | 
			
		||||
        Initialize the model building the initial data
 | 
			
		||||
        """
 | 
			
		||||
        gtk.GenericTreeModel.__init__(self)
 | 
			
		||||
 | 
			
		||||
        self.db = db
 | 
			
		||||
@@ -128,10 +148,16 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
        self.rebuild_data(data_filter, skip)
 | 
			
		||||
 | 
			
		||||
    def rebuild_data(self, data_filter=None, skip=[]):
 | 
			
		||||
        """
 | 
			
		||||
        Convience function that calculates the new data and assigns it.
 | 
			
		||||
        """
 | 
			
		||||
        self.calculate_data(data_filter, skip)
 | 
			
		||||
        self.assign_data()
 | 
			
		||||
        
 | 
			
		||||
    def calculate_data(self, dfilter=None, skip=[]):
 | 
			
		||||
        """
 | 
			
		||||
        Calculates the new path to node values for the model.
 | 
			
		||||
        """
 | 
			
		||||
        if dfilter:
 | 
			
		||||
            self.dfilter = dfilter
 | 
			
		||||
        self.temp_iter2path = {}
 | 
			
		||||
@@ -194,7 +220,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
    def on_get_n_columns(self):
 | 
			
		||||
        return len(COLUMN_DEFS)
 | 
			
		||||
 | 
			
		||||
    def on_get_path(self,node):
 | 
			
		||||
    def on_get_path(self,  node):
 | 
			
		||||
        '''returns the tree path (a tuple of indices at the various
 | 
			
		||||
        levels) for a particular node.'''
 | 
			
		||||
        try:
 | 
			
		||||
@@ -209,7 +235,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
    def on_get_column_type(self, index):
 | 
			
		||||
        return COLUMN_DEFS[index][COLUMN_DEF_TYPE]
 | 
			
		||||
 | 
			
		||||
    def on_get_iter(self,path):
 | 
			
		||||
    def on_get_iter(self, path):
 | 
			
		||||
        try:
 | 
			
		||||
            if len(path)==1: # Top Level
 | 
			
		||||
                return self.top_path2iter[path[0]]
 | 
			
		||||
@@ -223,23 +249,23 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
        # test for header or data row-type
 | 
			
		||||
        if self.sname_sub.has_key(node):
 | 
			
		||||
            # Header rows dont get the background color set
 | 
			
		||||
            if col==self.marker_color_column:
 | 
			
		||||
            if col == self.marker_color_column:
 | 
			
		||||
                return None
 | 
			
		||||
            # test for 'header' column being empty (most are)
 | 
			
		||||
            if not COLUMN_DEFS[col][COLUMN_DEF_HEADER]:
 | 
			
		||||
                return u''
 | 
			
		||||
            # return values for 'header' row,calling a function
 | 
			
		||||
            # return values for 'header' row, calling a function
 | 
			
		||||
            # according to column_defs table
 | 
			
		||||
            val = COLUMN_DEFS[col][COLUMN_DEF_HEADER](self, node)
 | 
			
		||||
            return val
 | 
			
		||||
        else:
 | 
			
		||||
            # return values for 'data' row,calling a function
 | 
			
		||||
            # return values for 'data' row, calling a function
 | 
			
		||||
            # according to column_defs table
 | 
			
		||||
            try:
 | 
			
		||||
                if node != self.prev_handle:
 | 
			
		||||
                    self.prev_data = self.db.get_raw_person_data(str(node))
 | 
			
		||||
                    self.prev_handle = node
 | 
			
		||||
                return COLUMN_DEFS[col][COLUMN_DEF_LIST](self, 
 | 
			
		||||
                return COLUMN_DEFS[col][COLUMN_DEF_LIST](self,
 | 
			
		||||
                                                         self.prev_data, node)
 | 
			
		||||
            except:
 | 
			
		||||
                if col == _MARKER_COL:
 | 
			
		||||
@@ -247,7 +273,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
                else:
 | 
			
		||||
                    return u'error'
 | 
			
		||||
 | 
			
		||||
    def on_iter_next(self,node):
 | 
			
		||||
    def on_iter_next(self,  node):
 | 
			
		||||
        '''returns the next node at this level of the tree'''
 | 
			
		||||
        try:
 | 
			
		||||
            path = self.top_path2iter.index(node)
 | 
			
		||||
@@ -265,7 +291,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
        else:
 | 
			
		||||
            return self.path2iter.get((node, 0))
 | 
			
		||||
 | 
			
		||||
    def on_iter_has_child(self,node):
 | 
			
		||||
    def on_iter_has_child(self, node):
 | 
			
		||||
        '''returns true if this node has children'''
 | 
			
		||||
        if node == None:
 | 
			
		||||
            return len(self.sname_sub)
 | 
			
		||||
@@ -292,7 +318,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
        except IndexError:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
    def on_iter_parent(self,node):
 | 
			
		||||
    def on_iter_parent(self, node):
 | 
			
		||||
        '''returns the parent of this node'''
 | 
			
		||||
        path = self.iter2path.get(node)
 | 
			
		||||
        if path:
 | 
			
		||||
@@ -309,7 +335,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
        handle = data[0]
 | 
			
		||||
        for family_handle in data[_FAMILY_COL]:
 | 
			
		||||
            family = self.db.get_family_from_handle(family_handle)
 | 
			
		||||
            for spouse_id in [family.get_father_handle(), 
 | 
			
		||||
            for spouse_id in [family.get_father_handle(),
 | 
			
		||||
                              family.get_mother_handle()]:
 | 
			
		||||
                if not spouse_id:
 | 
			
		||||
                    continue
 | 
			
		||||
@@ -317,7 +343,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
                    continue
 | 
			
		||||
                spouse = self.db.get_person_from_handle(spouse_id)
 | 
			
		||||
                if len(spouses_names) > 0:
 | 
			
		||||
                    spouses_names += ","
 | 
			
		||||
                    spouses_names += ", "
 | 
			
		||||
                spouses_names += NameDisplay.displayer.display(spouse)
 | 
			
		||||
        return spouses_names
 | 
			
		||||
 | 
			
		||||
@@ -330,15 +356,16 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
        return data[_ID_COL]
 | 
			
		||||
 | 
			
		||||
    def column_change(self, data, node):
 | 
			
		||||
        return unicode(time.strftime('%x %X', time.localtime(data[_CHANGE_COL])), 
 | 
			
		||||
                            _codeset)
 | 
			
		||||
        return unicode(
 | 
			
		||||
            time.strftime('%x %X', time.localtime(data[_CHANGE_COL])),
 | 
			
		||||
            _codeset)
 | 
			
		||||
 | 
			
		||||
    def column_gender(self, data, node):
 | 
			
		||||
        return _GENDER[data[_GENDER_COL]]
 | 
			
		||||
 | 
			
		||||
    def column_birth_day(self, data, node):
 | 
			
		||||
        if data[_BIRTH_COL]:
 | 
			
		||||
            b=EventRef()
 | 
			
		||||
            b = EventRef()
 | 
			
		||||
            b.unserialize(data[_BIRTH_COL])
 | 
			
		||||
            birth = self.db.get_event_from_handle(b.ref)
 | 
			
		||||
            date_str = DateHandler.get_date(birth)
 | 
			
		||||
@@ -351,7 +378,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
            event = self.db.get_event_from_handle(er.ref)
 | 
			
		||||
            etype = event.get_type()[0]
 | 
			
		||||
            date_str = DateHandler.get_date(event)
 | 
			
		||||
            if (etype in [Event.BAPTISM,Event.CHRISTEN]
 | 
			
		||||
            if (etype in [Event.BAPTISM, Event.CHRISTEN]
 | 
			
		||||
                and date_str != ""):
 | 
			
		||||
                return "<i>" + cgi.escape(date_str) + "</i>"
 | 
			
		||||
        
 | 
			
		||||
@@ -372,7 +399,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
            event = self.db.get_event_from_handle(er.ref)
 | 
			
		||||
            etype = event.get_type()[0]
 | 
			
		||||
            date_str = DateHandler.get_date(event)
 | 
			
		||||
            if (etype in [Event.BURIAL,Event.CREMATION]
 | 
			
		||||
            if (etype in [Event.BURIAL, Event.CREMATION]
 | 
			
		||||
                and date_str != ""):
 | 
			
		||||
                return "<i>" + cgi.escape(date_str) + "</i>"
 | 
			
		||||
        
 | 
			
		||||
@@ -404,7 +431,7 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
            er.unserialize(event_ref)
 | 
			
		||||
            event = self.db.get_event_from_handle(er.ref)
 | 
			
		||||
            etype = event.get_type()[0]
 | 
			
		||||
            if etype in [Event.BAPTISM,Event.CHRISTEN]:
 | 
			
		||||
            if etype in [Event.BAPTISM, Event.CHRISTEN]:
 | 
			
		||||
                place_handle = event.get_place_handle()
 | 
			
		||||
                if place_handle:
 | 
			
		||||
                    place = self.db.get_place_from_handle(place_handle)
 | 
			
		||||
@@ -422,7 +449,8 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
            if event:
 | 
			
		||||
                place_handle = event.get_place_handle()
 | 
			
		||||
                if place_handle:
 | 
			
		||||
                    place_title = self.db.get_place_from_handle(place_handle).get_title()
 | 
			
		||||
                    place = self.db.get_place_from_handle(place_handle)
 | 
			
		||||
                    place_title = place.get_title()
 | 
			
		||||
                    if place_title != "":
 | 
			
		||||
                        return cgi.escape(place_title)
 | 
			
		||||
        
 | 
			
		||||
@@ -431,10 +459,11 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
            er.unserialize(event_ref)
 | 
			
		||||
            event = self.db.get_event_from_handle(er.ref)
 | 
			
		||||
            etype = event.get_type()[0]
 | 
			
		||||
            if etype in [Event.BURIAL,Event.CREMATION]:
 | 
			
		||||
            if etype in [Event.BURIAL, Event.CREMATION]:
 | 
			
		||||
                place_handle = event.get_place_handle()
 | 
			
		||||
                if place_handle:
 | 
			
		||||
                    place_title = self.db.get_place_from_handle(place_handle).get_title()
 | 
			
		||||
                    place = self.db.get_place_from_handle(place_handle)
 | 
			
		||||
                    place_title = place.get_title()
 | 
			
		||||
                    if place_title != "":
 | 
			
		||||
                        return "<i>" + cgi.escape(place_title) + "</i>"
 | 
			
		||||
        
 | 
			
		||||
@@ -466,7 +495,10 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
 | 
			
		||||
    def column_tooltip(self, data, node):
 | 
			
		||||
        if const.use_tips:
 | 
			
		||||
            return ToolTips.TipFromFunction(self.db,lambda: self.db.get_person_from_handle(data[0]))
 | 
			
		||||
            return ToolTips.TipFromFunction(
 | 
			
		||||
                self.db,
 | 
			
		||||
                lambda: self.db.get_person_from_handle(data[0])
 | 
			
		||||
                )
 | 
			
		||||
        else:
 | 
			
		||||
            return u''
 | 
			
		||||
        
 | 
			
		||||
@@ -480,32 +512,32 @@ class PeopleModel(gtk.GenericTreeModel):
 | 
			
		||||
    def column_header_view(self, node):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
_GENDER = [ _(u'female'),_(u'male'),_(u'unknown') ]
 | 
			
		||||
_GENDER = [ _(u'female'), _(u'male'), _(u'unknown') ]
 | 
			
		||||
 | 
			
		||||
# table of column definitions
 | 
			
		||||
# (unless this is declared after the PeopleModel class,an error is thrown)
 | 
			
		||||
# (unless this is declared after the PeopleModel class, an error is thrown)
 | 
			
		||||
 | 
			
		||||
COLUMN_DEFS = [
 | 
			
		||||
    # data column (method)          header column (method)         column data type 
 | 
			
		||||
    (PeopleModel.column_name,           PeopleModel.column_header, str), 
 | 
			
		||||
    (PeopleModel.column_id,             None,                      str), 
 | 
			
		||||
    (PeopleModel.column_gender,         None,                      str), 
 | 
			
		||||
    (PeopleModel.column_birth_day,      None,                      str), 
 | 
			
		||||
    (PeopleModel.column_birth_place,    None,                      str), 
 | 
			
		||||
    (PeopleModel.column_death_day,      None,                      str), 
 | 
			
		||||
    (PeopleModel.column_death_place,    None,                      str), 
 | 
			
		||||
    (PeopleModel.column_spouse,         None,                      str), 
 | 
			
		||||
    (PeopleModel.column_change,         None,                      str), 
 | 
			
		||||
    (PeopleModel.column_cause_of_death, None,                      str), 
 | 
			
		||||
    (PeopleModel.column_marker_text,    None,                      str), 
 | 
			
		||||
    (PeopleModel.column_marker_color,   None,                      str), 
 | 
			
		||||
    (PeopleModel.column_name,           PeopleModel.column_header, str),
 | 
			
		||||
    (PeopleModel.column_id,             None,                      str),
 | 
			
		||||
    (PeopleModel.column_gender,         None,                      str),
 | 
			
		||||
    (PeopleModel.column_birth_day,      None,                      str),
 | 
			
		||||
    (PeopleModel.column_birth_place,    None,                      str),
 | 
			
		||||
    (PeopleModel.column_death_day,      None,                      str),
 | 
			
		||||
    (PeopleModel.column_death_place,    None,                      str),
 | 
			
		||||
    (PeopleModel.column_spouse,         None,                      str),
 | 
			
		||||
    (PeopleModel.column_change,         None,                      str),
 | 
			
		||||
    (PeopleModel.column_cause_of_death, None,                      str),
 | 
			
		||||
    (PeopleModel.column_marker_text,    None,                      str),
 | 
			
		||||
    (PeopleModel.column_marker_color,   None,                      str),
 | 
			
		||||
    # the order of the above columns must match PeopleView.column_names
 | 
			
		||||
 | 
			
		||||
    # these columns are hidden,and must always be last in the list
 | 
			
		||||
    (PeopleModel.column_tooltip,        None,                      object),   
 | 
			
		||||
    (PeopleModel.column_int_id,         None,                      str), 
 | 
			
		||||
    # these columns are hidden, and must always be last in the list
 | 
			
		||||
    (PeopleModel.column_tooltip,        None,                      object),  
 | 
			
		||||
    (PeopleModel.column_int_id,         None,                      str),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
# dynamic calculation of column indices,for use by various Views
 | 
			
		||||
# dynamic calculation of column indices, for use by various Views
 | 
			
		||||
COLUMN_INT_ID = 13
 | 
			
		||||
 | 
			
		||||
# indices into main column definition table
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
# 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,
 | 
			
		||||
# 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.
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
"Support for dates"
 | 
			
		||||
 | 
			
		||||
__author__ = "Donald N. Allingham"
 | 
			
		||||
__version__ = "$Revision$"
 | 
			
		||||
__revision__ = "$Revision$"
 | 
			
		||||
 | 
			
		||||
from gettext import gettext as _
 | 
			
		||||
from _CalSdn import *
 | 
			
		||||
@@ -35,7 +35,7 @@ from _CalSdn import *
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class DateError(Exception):
 | 
			
		||||
    """Error used to report Date errors"""
 | 
			
		||||
    def __init__(self,value=""):
 | 
			
		||||
    def __init__(self, value=""):
 | 
			
		||||
        Exception.__init__(self)
 | 
			
		||||
        self.value = value
 | 
			
		||||
 | 
			
		||||
@@ -49,7 +49,7 @@ class DateError(Exception):
 | 
			
		||||
#-------------------------------------------------------------------------
 | 
			
		||||
class Date:
 | 
			
		||||
    """
 | 
			
		||||
    The core date handling class for GRAMPs. Supports partial dates,
 | 
			
		||||
    The core date handling class for GRAMPs. Supports partial dates, 
 | 
			
		||||
    compound dates and alternate calendars.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@@ -61,9 +61,9 @@ class Date:
 | 
			
		||||
    MOD_SPAN       = 5
 | 
			
		||||
    MOD_TEXTONLY   = 6
 | 
			
		||||
 | 
			
		||||
    QUAL_NONE      = 0
 | 
			
		||||
    QUAL_ESTIMATED = 1
 | 
			
		||||
    QUAL_CALCULATED= 2
 | 
			
		||||
    QUAL_NONE       = 0
 | 
			
		||||
    QUAL_ESTIMATED  = 1
 | 
			
		||||
    QUAL_CALCULATED = 2
 | 
			
		||||
 | 
			
		||||
    CAL_GREGORIAN  = 0
 | 
			
		||||
    CAL_JULIAN     = 1
 | 
			
		||||
@@ -72,7 +72,7 @@ class Date:
 | 
			
		||||
    CAL_PERSIAN    = 4
 | 
			
		||||
    CAL_ISLAMIC    = 5
 | 
			
		||||
 | 
			
		||||
    EMPTY = (0,0,0,False)
 | 
			
		||||
    EMPTY = (0, 0, 0, False)
 | 
			
		||||
 | 
			
		||||
    _POS_DAY  = 0
 | 
			
		||||
    _POS_MON  = 1
 | 
			
		||||
@@ -84,39 +84,39 @@ class Date:
 | 
			
		||||
    _POS_RSL  = 7
 | 
			
		||||
 | 
			
		||||
    _calendar_convert = [
 | 
			
		||||
        gregorian_sdn,
 | 
			
		||||
        julian_sdn,
 | 
			
		||||
        hebrew_sdn,
 | 
			
		||||
        french_sdn,
 | 
			
		||||
        persian_sdn,
 | 
			
		||||
        islamic_sdn,
 | 
			
		||||
        gregorian_sdn, 
 | 
			
		||||
        julian_sdn, 
 | 
			
		||||
        hebrew_sdn, 
 | 
			
		||||
        french_sdn, 
 | 
			
		||||
        persian_sdn, 
 | 
			
		||||
        islamic_sdn, 
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
    _calendar_change = [
 | 
			
		||||
        gregorian_ymd,
 | 
			
		||||
        julian_ymd,
 | 
			
		||||
        hebrew_ymd,
 | 
			
		||||
        french_ymd,
 | 
			
		||||
        persian_ymd,
 | 
			
		||||
        islamic_ymd,
 | 
			
		||||
        gregorian_ymd, 
 | 
			
		||||
        julian_ymd, 
 | 
			
		||||
        hebrew_ymd, 
 | 
			
		||||
        french_ymd, 
 | 
			
		||||
        persian_ymd, 
 | 
			
		||||
        islamic_ymd, 
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
    calendar_names = ["Gregorian",
 | 
			
		||||
                      "Julian",
 | 
			
		||||
                      "Hebrew",
 | 
			
		||||
                      "French Republican",
 | 
			
		||||
                      "Persian",
 | 
			
		||||
    calendar_names = ["Gregorian", 
 | 
			
		||||
                      "Julian", 
 | 
			
		||||
                      "Hebrew", 
 | 
			
		||||
                      "French Republican", 
 | 
			
		||||
                      "Persian", 
 | 
			
		||||
                      "Islamic"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ui_calendar_names = [_("Gregorian"),
 | 
			
		||||
                         _("Julian"),
 | 
			
		||||
                         _("Hebrew"),
 | 
			
		||||
                         _("French Republican"),
 | 
			
		||||
                         _("Persian"),
 | 
			
		||||
    ui_calendar_names = [_("Gregorian"), 
 | 
			
		||||
                         _("Julian"), 
 | 
			
		||||
                         _("Hebrew"), 
 | 
			
		||||
                         _("French Republican"), 
 | 
			
		||||
                         _("Persian"), 
 | 
			
		||||
                         _("Islamic")]
 | 
			
		||||
 | 
			
		||||
    def __init__(self,source=None):
 | 
			
		||||
    def __init__(self, source=None):
 | 
			
		||||
        """
 | 
			
		||||
        Creates a new Date instance.
 | 
			
		||||
        """
 | 
			
		||||
@@ -136,15 +136,21 @@ class Date:
 | 
			
		||||
            self.sortval  = 0
 | 
			
		||||
 | 
			
		||||
    def serialize(self):
 | 
			
		||||
        return (self.calendar,self.modifier,self.quality,
 | 
			
		||||
                self.dateval,self.text,self.sortval)
 | 
			
		||||
        """
 | 
			
		||||
        Convert to a series of tuples for data storage
 | 
			
		||||
        """
 | 
			
		||||
        return (self.calendar, self.modifier, self.quality, 
 | 
			
		||||
                self.dateval, self.text, self.sortval)
 | 
			
		||||
 | 
			
		||||
    def unserialize(self,data):
 | 
			
		||||
        (self.calendar,self.modifier,self.quality,
 | 
			
		||||
         self.dateval,self.text,self.sortval) = data
 | 
			
		||||
    def unserialize(self, data):
 | 
			
		||||
        """
 | 
			
		||||
        Load from the format created by serialize
 | 
			
		||||
        """
 | 
			
		||||
        (self.calendar, self.modifier, self.quality, 
 | 
			
		||||
         self.dateval, self.text, self.sortval) = data
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    def copy(self,source):
 | 
			
		||||
    def copy(self, source):
 | 
			
		||||
        """
 | 
			
		||||
        Copy all the attributes of the given Date instance
 | 
			
		||||
        to the present instance, without creating a new object.
 | 
			
		||||
@@ -156,17 +162,17 @@ class Date:
 | 
			
		||||
        self.text     = source.text
 | 
			
		||||
        self.sortval  = source.sortval
 | 
			
		||||
 | 
			
		||||
    def __cmp__(self,other):
 | 
			
		||||
    def __cmp__(self, other):
 | 
			
		||||
        """
 | 
			
		||||
        Comparison function. Allows the usage of equality tests.
 | 
			
		||||
        This allows you do run statements like 'date1 <= date2'
 | 
			
		||||
        """
 | 
			
		||||
        if isinstance(other,Date):
 | 
			
		||||
            return cmp(self.sortval,other.sortval)
 | 
			
		||||
        if isinstance(other, Date):
 | 
			
		||||
            return cmp(self.sortval, other.sortval)
 | 
			
		||||
        else:
 | 
			
		||||
            return -1
 | 
			
		||||
 | 
			
		||||
    def is_equal(self,other):
 | 
			
		||||
    def is_equal(self, other):
 | 
			
		||||
        """
 | 
			
		||||
        Return 1 if the given Date instance is the same as the present
 | 
			
		||||
        instance IN ALL REGARDS. Needed, because the __cmp__ only looks
 | 
			
		||||
@@ -216,14 +222,14 @@ class Date:
 | 
			
		||||
            val = self.text
 | 
			
		||||
        elif self.modifier == Date.MOD_RANGE or self.modifier == Date.MOD_SPAN:
 | 
			
		||||
            val = "%04d-%02d-%02d - %04d-%02d-%02d" % (
 | 
			
		||||
                self.dateval[Date._POS_YR],self.dateval[Date._POS_MON],
 | 
			
		||||
                self.dateval[Date._POS_DAY],self.dateval[Date._POS_RYR],
 | 
			
		||||
                self.dateval[Date._POS_RMON],self.dateval[Date._POS_RDAY])
 | 
			
		||||
                self.dateval[Date._POS_YR], self.dateval[Date._POS_MON], 
 | 
			
		||||
                self.dateval[Date._POS_DAY], self.dateval[Date._POS_RYR], 
 | 
			
		||||
                self.dateval[Date._POS_RMON], self.dateval[Date._POS_RDAY])
 | 
			
		||||
        else:
 | 
			
		||||
            val = "%04d-%02d-%02d" % (
 | 
			
		||||
                self.dateval[Date._POS_YR],self.dateval[Date._POS_MON],
 | 
			
		||||
                self.dateval[Date._POS_YR], self.dateval[Date._POS_MON], 
 | 
			
		||||
                self.dateval[Date._POS_DAY])
 | 
			
		||||
        return "%s%s%s%s" % (qual,pref,val,cal)
 | 
			
		||||
        return "%s%s%s%s" % (qual, pref, val, cal)
 | 
			
		||||
 | 
			
		||||
    def get_sort_value(self):
 | 
			
		||||
        """
 | 
			
		||||
@@ -251,12 +257,12 @@ class Date:
 | 
			
		||||
        """
 | 
			
		||||
        return self.modifier
 | 
			
		||||
 | 
			
		||||
    def set_modifier(self,val):
 | 
			
		||||
    def set_modifier(self, val):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the modifier for the date.
 | 
			
		||||
        """
 | 
			
		||||
        if val not in (Date.MOD_NONE,Date.MOD_BEFORE,Date.MOD_AFTER,
 | 
			
		||||
                       Date.MOD_ABOUT,Date.MOD_RANGE,Date.MOD_SPAN,
 | 
			
		||||
        if val not in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, 
 | 
			
		||||
                       Date.MOD_ABOUT, Date.MOD_RANGE, Date.MOD_SPAN, 
 | 
			
		||||
                       Date.MOD_TEXTONLY):
 | 
			
		||||
            raise DateError("Invalid modifier")
 | 
			
		||||
        self.modifier = val
 | 
			
		||||
@@ -272,11 +278,11 @@ class Date:
 | 
			
		||||
        """
 | 
			
		||||
        return self.quality
 | 
			
		||||
 | 
			
		||||
    def set_quality(self,val):
 | 
			
		||||
    def set_quality(self, val):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the quality selected for the date.
 | 
			
		||||
        """
 | 
			
		||||
        if val not in (Date.QUAL_NONE,Date.QUAL_ESTIMATED,
 | 
			
		||||
        if val not in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, 
 | 
			
		||||
                       Date.QUAL_CALCULATED):
 | 
			
		||||
            raise DateError("Invalid quality")
 | 
			
		||||
        self.quality = val
 | 
			
		||||
@@ -295,12 +301,12 @@ class Date:
 | 
			
		||||
        """
 | 
			
		||||
        return self.calendar
 | 
			
		||||
 | 
			
		||||
    def set_calendar(self,val):
 | 
			
		||||
    def set_calendar(self, val):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the calendar selected for the date.
 | 
			
		||||
        """
 | 
			
		||||
        if val not in (Date.CAL_GREGORIAN,Date.CAL_JULIAN,Date.CAL_HEBREW,
 | 
			
		||||
                       Date.CAL_FRENCH,Date.CAL_PERSIAN,Date.CAL_ISLAMIC):
 | 
			
		||||
        if val not in (Date.CAL_GREGORIAN, Date.CAL_JULIAN, Date.CAL_HEBREW, 
 | 
			
		||||
                       Date.CAL_FRENCH, Date.CAL_PERSIAN, Date.CAL_ISLAMIC):
 | 
			
		||||
            raise DateError("Invalid calendar")
 | 
			
		||||
        self.calendar = val
 | 
			
		||||
 | 
			
		||||
@@ -309,7 +315,7 @@ class Date:
 | 
			
		||||
        Returns a tuple representing the start date. If the date is a
 | 
			
		||||
        compound date (range or a span), it is the first part of the
 | 
			
		||||
        compound date. If the date is a text string, a tuple of
 | 
			
		||||
        (0,0,0,False) is returned. Otherwise, a date of (DD,MM,YY,slash)
 | 
			
		||||
        (0, 0, 0, False) is returned. Otherwise, a date of (DD, MM, YY, slash)
 | 
			
		||||
        is returned. If slash is True, then the date is in the form of 1530/1.
 | 
			
		||||
        """
 | 
			
		||||
        if self.modifier == Date.MOD_TEXTONLY:
 | 
			
		||||
@@ -322,7 +328,7 @@ class Date:
 | 
			
		||||
        """
 | 
			
		||||
        Returns a tuple representing the second half of a compound date. 
 | 
			
		||||
        If the date is not a compound date, (including text strings) a tuple
 | 
			
		||||
        of (0,0,0,False) is returned. Otherwise, a date of (DD,MM,YY,slash)
 | 
			
		||||
        of (0, 0, 0, False) is returned. Otherwise, a date of (DD, MM, YY, slash)
 | 
			
		||||
        is returned. If slash is True, then the date is in the form of 1530/1.
 | 
			
		||||
        """
 | 
			
		||||
        if self.modifier == Date.MOD_RANGE or self.modifier == Date.MOD_SPAN:
 | 
			
		||||
@@ -331,21 +337,30 @@ class Date:
 | 
			
		||||
            val = Date.EMPTY
 | 
			
		||||
        return val
 | 
			
		||||
 | 
			
		||||
    def _get_low_item(self,index):
 | 
			
		||||
    def _get_low_item(self, index):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the item specified
 | 
			
		||||
        """
 | 
			
		||||
        if self.modifier == Date.MOD_TEXTONLY:
 | 
			
		||||
            val = 0
 | 
			
		||||
        else:
 | 
			
		||||
            val = self.dateval[index]
 | 
			
		||||
        return val
 | 
			
		||||
 | 
			
		||||
    def _get_low_item_valid(self,index):
 | 
			
		||||
    def _get_low_item_valid(self, index):
 | 
			
		||||
        """
 | 
			
		||||
        Determines if the item specified is valid
 | 
			
		||||
        """
 | 
			
		||||
        if self.modifier == Date.MOD_TEXTONLY:
 | 
			
		||||
            val = False
 | 
			
		||||
        else:
 | 
			
		||||
            val = self.dateval[index] != 0
 | 
			
		||||
        return val
 | 
			
		||||
        
 | 
			
		||||
    def _get_high_item(self,index):
 | 
			
		||||
    def _get_high_item(self, index):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the item specified
 | 
			
		||||
        """
 | 
			
		||||
        if self.modifier == Date.MOD_SPAN or self.modifier == Date.MOD_RANGE:
 | 
			
		||||
            val = self.dateval[index]
 | 
			
		||||
        else:
 | 
			
		||||
@@ -360,13 +375,17 @@ class Date:
 | 
			
		||||
        """
 | 
			
		||||
        return self._get_low_item(Date._POS_YR)
 | 
			
		||||
 | 
			
		||||
    def set_year(self,year):
 | 
			
		||||
    def set_year(self, year):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the year value
 | 
			
		||||
        """
 | 
			
		||||
        self.dateval = self.dateval[0:2] + (year,) + self.dateval[3:]
 | 
			
		||||
        self.calc_sort_value()
 | 
			
		||||
        self.dateval = self.dateval[0:2] + (year, ) + self.dateval[3:]
 | 
			
		||||
        self._calc_sort_value()
 | 
			
		||||
 | 
			
		||||
    def get_year_valid(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns true if the year is valid
 | 
			
		||||
        """
 | 
			
		||||
        return self._get_low_item_valid(Date._POS_YR)
 | 
			
		||||
 | 
			
		||||
    def get_month(self):
 | 
			
		||||
@@ -378,6 +397,9 @@ class Date:
 | 
			
		||||
        return self._get_low_item(Date._POS_MON)
 | 
			
		||||
 | 
			
		||||
    def get_month_valid(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns true if the month is valid
 | 
			
		||||
        """
 | 
			
		||||
        return self._get_low_item_valid(Date._POS_MON)
 | 
			
		||||
 | 
			
		||||
    def get_day(self):
 | 
			
		||||
@@ -389,15 +411,15 @@ class Date:
 | 
			
		||||
        return self._get_low_item(Date._POS_DAY)
 | 
			
		||||
 | 
			
		||||
    def get_day_valid(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns true if the day is valid
 | 
			
		||||
        """
 | 
			
		||||
        return self._get_low_item_valid(Date._POS_DAY)
 | 
			
		||||
 | 
			
		||||
    def get_valid(self):
 | 
			
		||||
        """ Returns true if any part of the date is valid"""
 | 
			
		||||
        return self.modifier != Date.MOD_TEXTONLY
 | 
			
		||||
 | 
			
		||||
    def get_incomplete(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def get_stop_year(self):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the day of the year associated with the second
 | 
			
		||||
@@ -441,7 +463,7 @@ class Date:
 | 
			
		||||
        """
 | 
			
		||||
        return self.text
 | 
			
		||||
 | 
			
		||||
    def set(self,quality,modifier,calendar,value,text=None):
 | 
			
		||||
    def set(self, quality, modifier, calendar, value, text=None):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the date to the specified value. Parameters are::
 | 
			
		||||
 | 
			
		||||
@@ -452,76 +474,82 @@ class Date:
 | 
			
		||||
          calendar - The calendar associated with the date (see
 | 
			
		||||
                     get_calendar for more information).
 | 
			
		||||
          value    - A tuple representing the date information. For a
 | 
			
		||||
                     non-compound date, the format is (DD,MM,YY,slash)
 | 
			
		||||
                     non-compound date, the format is (DD, MM, YY, slash)
 | 
			
		||||
                     and for a compound date the tuple stores data as
 | 
			
		||||
                     (DD,MM,YY,slash1,DD,MM,YY,slash2)
 | 
			
		||||
                     (DD, MM, YY, slash1, DD, MM, YY, slash2)
 | 
			
		||||
          text     - A text string holding either the verbatim user input
 | 
			
		||||
                     or a comment relating to the date.
 | 
			
		||||
 | 
			
		||||
        The sort value is recalculated.
 | 
			
		||||
        """
 | 
			
		||||
        
 | 
			
		||||
        if modifier in (Date.MOD_NONE,Date.MOD_BEFORE,
 | 
			
		||||
                        Date.MOD_AFTER,Date.MOD_ABOUT) and len(value) < 4:
 | 
			
		||||
            raise DateError("Invalid value. Should be: (DD,MM,YY,slash)")
 | 
			
		||||
        if modifier in (Date.MOD_RANGE,Date.MOD_SPAN) and len(value) < 8:
 | 
			
		||||
            raise DateError(
 | 
			
		||||
                "Invalid value. Should be: (DD,MM,YY,slash1,DD,MM,YY,slash2)")
 | 
			
		||||
        if modifier not in (Date.MOD_NONE,Date.MOD_BEFORE,Date.MOD_AFTER,
 | 
			
		||||
                            Date.MOD_ABOUT,Date.MOD_RANGE,Date.MOD_SPAN,
 | 
			
		||||
        if modifier in (Date.MOD_NONE, Date.MOD_BEFORE, 
 | 
			
		||||
                        Date.MOD_AFTER, Date.MOD_ABOUT) and len(value) < 4:
 | 
			
		||||
            raise DateError("Invalid value. Should be: (DD, MM, YY, slash)")
 | 
			
		||||
        if modifier in (Date.MOD_RANGE, Date.MOD_SPAN) and len(value) < 8:
 | 
			
		||||
            raise DateError("Invalid value. Should be: (DD, MM, "
 | 
			
		||||
                            "YY, slash1, DD, MM, YY, slash2)")
 | 
			
		||||
        if modifier not in (Date.MOD_NONE, Date.MOD_BEFORE, Date.MOD_AFTER, 
 | 
			
		||||
                            Date.MOD_ABOUT, Date.MOD_RANGE, Date.MOD_SPAN, 
 | 
			
		||||
                            Date.MOD_TEXTONLY):
 | 
			
		||||
            raise DateError("Invalid modifier")
 | 
			
		||||
        if quality not in (Date.QUAL_NONE,Date.QUAL_ESTIMATED,
 | 
			
		||||
        if quality not in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, 
 | 
			
		||||
                           Date.QUAL_CALCULATED):
 | 
			
		||||
            raise DateError("Invalid quality")
 | 
			
		||||
        if calendar not in (Date.CAL_GREGORIAN,Date.CAL_JULIAN,Date.CAL_HEBREW,
 | 
			
		||||
                            Date.CAL_FRENCH,Date.CAL_PERSIAN,Date.CAL_ISLAMIC):
 | 
			
		||||
        if calendar not in (Date.CAL_GREGORIAN, Date.CAL_JULIAN,
 | 
			
		||||
                            Date.CAL_HEBREW, Date.CAL_FRENCH,
 | 
			
		||||
                            Date.CAL_PERSIAN, Date.CAL_ISLAMIC):
 | 
			
		||||
            raise DateError("Invalid calendar")
 | 
			
		||||
 | 
			
		||||
        self.quality = quality
 | 
			
		||||
        self.modifier = modifier
 | 
			
		||||
        self.calendar = calendar
 | 
			
		||||
        self.dateval = value
 | 
			
		||||
        year = max(value[Date._POS_YR],1)
 | 
			
		||||
        month = max(value[Date._POS_MON],1)
 | 
			
		||||
        day = max(value[Date._POS_DAY],1)
 | 
			
		||||
        year = max(value[Date._POS_YR], 1)
 | 
			
		||||
        month = max(value[Date._POS_MON], 1)
 | 
			
		||||
        day = max(value[Date._POS_DAY], 1)
 | 
			
		||||
        if year == 0 and month == 0 and day == 0:
 | 
			
		||||
            self.sortval = 0
 | 
			
		||||
        else:
 | 
			
		||||
            self.sortval = Date._calendar_convert[calendar](year,month,day)
 | 
			
		||||
            func = Date._calendar_convert[calendar]
 | 
			
		||||
            self.sortval = func(year, month, day)
 | 
			
		||||
        if text:
 | 
			
		||||
            self.text = text
 | 
			
		||||
 | 
			
		||||
    def calc_sort_value(self):
 | 
			
		||||
        year = max(self.dateval[Date._POS_YR],1)
 | 
			
		||||
        month = max(self.dateval[Date._POS_MON],1)
 | 
			
		||||
        day = max(self.dateval[Date._POS_DAY],1)
 | 
			
		||||
    def _calc_sort_value(self):
 | 
			
		||||
        """
 | 
			
		||||
        Calculates the numerical sort value associated with the date
 | 
			
		||||
        """
 | 
			
		||||
        year = max(self.dateval[Date._POS_YR], 1)
 | 
			
		||||
        month = max(self.dateval[Date._POS_MON], 1)
 | 
			
		||||
        day = max(self.dateval[Date._POS_DAY], 1)
 | 
			
		||||
        if year == 0 and month == 0 and day == 0:
 | 
			
		||||
            self.sortval = 0
 | 
			
		||||
        else:
 | 
			
		||||
            self.sortval = Date._calendar_convert[self.calendar](year,month,day)
 | 
			
		||||
            func = Date._calendar_convert[self.calendar]
 | 
			
		||||
            self.sortval = func(year, month, day)
 | 
			
		||||
 | 
			
		||||
    def convert_calendar(self,calendar):
 | 
			
		||||
    def convert_calendar(self, calendar):
 | 
			
		||||
        """
 | 
			
		||||
        Converts the date from the current calendar to the specified
 | 
			
		||||
        calendar.
 | 
			
		||||
        """
 | 
			
		||||
        if calendar == self.calendar:
 | 
			
		||||
            return
 | 
			
		||||
        (y,m,d) = Date._calendar_change[calendar](self.sortval)
 | 
			
		||||
        (year, month, day) = Date._calendar_change[calendar](self.sortval)
 | 
			
		||||
        if self.is_compound():
 | 
			
		||||
            ry = max(self.dateval[Date._POS_RYR],1)
 | 
			
		||||
            rm = max(self.dateval[Date._POS_RMON],1)
 | 
			
		||||
            rd = max(self.dateval[Date._POS_RDAY],1)
 | 
			
		||||
            sdn = Date._calendar_convert[self.calendar](ry,rm,rd)
 | 
			
		||||
            (ny,nm,nd) = Date._calendar_change[calendar](sdn)
 | 
			
		||||
            self.dateval = (d,m,y,self.dateval[Date._POS_SL],
 | 
			
		||||
                            nd,nm,ny,self.dateval[Date._POS_RSL])
 | 
			
		||||
            ryear = max(self.dateval[Date._POS_RYR], 1)
 | 
			
		||||
            rmonth = max(self.dateval[Date._POS_RMON], 1)
 | 
			
		||||
            rday = max(self.dateval[Date._POS_RDAY], 1)
 | 
			
		||||
            sdn = Date._calendar_convert[self.calendar](ryear, rmonth, rday)
 | 
			
		||||
            (nyear, nmonth, nday) = Date._calendar_change[calendar](sdn)
 | 
			
		||||
            self.dateval = (day, month, year, self.dateval[Date._POS_SL], 
 | 
			
		||||
                            nday, nmonth, nyear, self.dateval[Date._POS_RSL])
 | 
			
		||||
        else:
 | 
			
		||||
            self.dateval = (d,m,y,self.dateval[Date._POS_SL])
 | 
			
		||||
            self.dateval = (day, month, year, self.dateval[Date._POS_SL])
 | 
			
		||||
        self.calendar = calendar
 | 
			
		||||
 | 
			
		||||
    def set_as_text(self,text):
 | 
			
		||||
    def set_as_text(self, text):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the day to a text string, and assigns the sort value
 | 
			
		||||
        to zero.
 | 
			
		||||
@@ -530,7 +558,7 @@ class Date:
 | 
			
		||||
        self.text = text
 | 
			
		||||
        self.sortval = 0
 | 
			
		||||
 | 
			
		||||
    def set_text_value(self,text):
 | 
			
		||||
    def set_text_value(self, text):
 | 
			
		||||
        """
 | 
			
		||||
        Sets the text string to a given text.
 | 
			
		||||
        """
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user