From e6b645cd2b5cafeb63e3bb14313d0d6b291479e5 Mon Sep 17 00:00:00 2001 From: Richard Taylor Date: Fri, 20 Jan 2006 10:30:35 +0000 Subject: [PATCH] integrated object selector into edit family svn: r5804 --- gramps2/ChangeLog | 11 +++ gramps2/src/EditFamily.py | 98 ++++++++++++++++++- gramps2/src/ObjectSelector/_Factories.py | 4 +- .../src/ObjectSelector/_FamilyFilterFrame.py | 10 +- gramps2/src/ObjectSelector/_FamilyFrame.py | 5 +- .../src/ObjectSelector/_FamilyPreviewFrame.py | 10 +- .../src/ObjectSelector/_FilterFrameBase.py | 5 +- gramps2/src/ObjectSelector/_FilterSpec.py | 14 +++ gramps2/src/ObjectSelector/_FilterSpecBase.py | 14 +++ .../ObjectSelector/_ObjectSelectorWindow.py | 27 +++-- .../src/ObjectSelector/_PersonFilterFrame.py | 77 +++++++++++++-- .../src/ObjectSelector/_PersonFilterSpec.py | 65 ++++++++++++ gramps2/src/ObjectSelector/_PersonFrame.py | 12 ++- .../src/ObjectSelector/_PersonPreviewFrame.py | 73 ++++++++++++-- gramps2/src/ObjectSelector/__init__.py | 15 +++ gramps2/src/gramps.py | 4 + 16 files changed, 405 insertions(+), 39 deletions(-) create mode 100644 gramps2/src/ObjectSelector/_FilterSpec.py create mode 100644 gramps2/src/ObjectSelector/_FilterSpecBase.py create mode 100644 gramps2/src/ObjectSelector/_PersonFilterSpec.py create mode 100644 gramps2/src/ObjectSelector/__init__.py diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index 01db2a60b..3bcb982a6 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,14 @@ +2006-01-20 Richard Taylor + * src/gramps.py: stoped Ctrl-C causing an error report + * src/EditFamily.py: integrated ObjectSelector + * src/ObjectSelector/_Factories.py, src/ObjectSelector/_FamilyFilterFrame.py, + src/ObjectSelector/_FamilyFrame.py, src/ObjectSelector/_FamilyPreviewFrame.py, + src/ObjectSelector/_FilterFrameBase.py, src/ObjectSelector/_ObjectSelectorWindow.py, + src/ObjectSelector/_PersonFilterFrame.py, src/ObjectSelector/_PersonFrame.py, + src/ObjectSelector/_PersonPreviewFrame.py, src/ObjectSelector/_FilterSpec.py, + src/ObjectSelector/_FilterSpecBase.py, src/ObjectSelector/_PersonFilterSpec.py, + src/ObjectSelector/__init__.py: implemented filter specs and setup package exports + 2006-01-19 Don Allingham * src/DisplayModels.py: use dirty flag to only draw when requested * src/PageView.py: use dirty flag to only draw when requested diff --git a/gramps2/src/EditFamily.py b/gramps2/src/EditFamily.py index 0006f86e2..2c96125f1 100644 --- a/gramps2/src/EditFamily.py +++ b/gramps2/src/EditFamily.py @@ -62,6 +62,7 @@ from DdTargets import DdTargets from WindowUtils import GladeIf from DisplayTabs import * from GrampsWidgets import * +from ObjectSelector import PersonSelector,PersonFilterSpec #------------------------------------------------------------------------- # @@ -153,7 +154,21 @@ class ChildEmbedList(EmbeddedList): return [(1,0),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(0,8),(0,9)] def add_button_clicked(self,obj): - print "Add Button Clicked" + # we could workout the death years of the parents here and + # set a suitable filter_spec on the PersonSelector + # we might also be able to set a filter that only includes + # people that are not already listed as children in another + # family. + selector = PersonSelector(self.dbstate,self.uistate,self.track) + + # this need the window handle of the main EditFamily window + # to make the PersonSelector transient to it. I am not sure + # want the best way is to get that handle from here. + #selector.set_transient_for(self.window) + + # Connect this to the method used to add a new child. + #selector.connect('add-object',self.on_add_child) + def del_button_clicked(self,obj): handle = self.get_selected() @@ -327,13 +342,72 @@ class EditFamily(DisplayState.ManagedWindow): def update_mother(self,handle): self.load_parent(handle, self.mbox, self.mbirth, self.mdeath, self.mbutton) + def on_change_mother(self, selector_window, select_result): + if select_result.is_person(): + try: + self.update_mother( + self.dbstate.db.get_person_from_gramps_id( + select_result.get_gramps_id()).get_handle()) + except: + log.warn("Failed to update mother: \n" + "gramps_id returned from selector was: %s\n" + "person returned from get_person_from_gramps_id: %s" + % (select_result.get_gramps_id(), + repr(self.dbstate.db.get_person_from_gramps_id( + select_result.get_gramps_id())))) + raise + else: + log.warn("Object selector returned a result of type = %s, it should " + "have been of type PERSON." % (str(select_result.get_object_type()))) + + selector_window.close() + def mother_clicked(self,obj): handle = self.family.get_mother_handle() if handle: self.family.set_mother_handle(None) self.update_mother(None) else: - print "Call person selector" + filter_spec = PersonFilterSpec() + filter_spec.set_gender(RelLib.Person.FEMALE) + + child_birth_years = [] + for person_handle in self.family.get_child_handle_list(): + person = self.dbstate.db.get_person_from_handle(person_handle) + event_handle = person.get_birth_handle() + if event_handle: + event = self.dbstate.db.get_event_from_handle(event_handle) + child_birth_years.append(event.get_date_object().get_year()) + + if len(child_birth_years) > 0: + filter_spec.set_birth_year(min(child_birth_years)) + filter_spec.set_birth_criteria(PersonFilterSpec.BEFORE) + + + selector = PersonSelector(self.dbstate,self.uistate,self.track,filter_spec=filter_spec) + selector.set_transient_for(self.window) + selector.connect('add-object',self.on_change_mother) + + + def on_change_father(self, selector_window, select_result): + if select_result.is_person(): + try: + self.update_father( + self.dbstate.db.get_person_from_gramps_id( + select_result.get_gramps_id()).get_handle()) + except: + log.warn("Failed to update father: \n" + "gramps_id returned from selector was: %s\n" + "person returned from get_person_from_gramps_id: %s" + % (select_result.get_gramps_id(), + repr(self.dbstate.db.get_person_from_gramps_id( + select_result.get_gramps_id())))) + raise + else: + log.warn("Object selector returned a result of type = %s, it should " + "have been of type PERSON." % (str(select_result.get_object_type()))) + + selector_window.close() def father_clicked(self,obj): handle = self.family.get_father_handle() @@ -341,7 +415,25 @@ class EditFamily(DisplayState.ManagedWindow): self.family.set_father_handle(None) self.update_father(None) else: - print "Call person selector" + filter_spec = PersonFilterSpec() + filter_spec.set_gender(RelLib.Person.MALE) + + child_birth_years = [] + for person_handle in self.family.get_child_handle_list(): + person = self.dbstate.db.get_person_from_handle(person_handle) + event_handle = person.get_birth_handle() + if event_handle: + event = self.dbstate.db.get_event_from_handle(event_handle) + child_birth_years.append(event.get_date_object().get_year()) + + if len(child_birth_years) > 0: + filter_spec.set_birth_year(min(child_birth_years)) + filter_spec.set_birth_criteria(PersonFilterSpec.BEFORE) + + selector = PersonSelector(self.dbstate,self.uistate,self.track,filter_spec=filter_spec) + selector.set_transient_for(self.window) + selector.connect('add-object',self.on_change_father) + def edit_person(self,obj,event,handle): if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1: diff --git a/gramps2/src/ObjectSelector/_Factories.py b/gramps2/src/ObjectSelector/_Factories.py index 6704d9a4d..1db9bc8d0 100644 --- a/gramps2/src/ObjectSelector/_Factories.py +++ b/gramps2/src/ObjectSelector/_Factories.py @@ -8,7 +8,7 @@ class ObjectFrameFactory(object): __frame_creators = {ObjectTypes.PERSON: PersonFrame, ObjectTypes.FAMILY: FamilyFrame} - def get_frame(self,object_type,dbstate,uistate): - return self.__class__.__frame_creators[object_type](dbstate,uistate) + def get_frame(self,object_type,dbstate,uistate,filter_spec=None): + return self.__class__.__frame_creators[object_type](dbstate,uistate,filter_spec) diff --git a/gramps2/src/ObjectSelector/_FamilyFilterFrame.py b/gramps2/src/ObjectSelector/_FamilyFilterFrame.py index bbef6c192..3a69e9028 100644 --- a/gramps2/src/ObjectSelector/_FamilyFilterFrame.py +++ b/gramps2/src/ObjectSelector/_FamilyFilterFrame.py @@ -13,8 +13,8 @@ class FamilyFilterFrame(FilterFrameBase): __default_border_width = 5 - def __init__(self,dbstate,label="Filter"): - FilterFrameBase.__init__(self,label) + def __init__(self,dbstate,filter_spec=None,label="Filter"): + FilterFrameBase.__init__(self,filter_spec,label) # Gramps ID id_check = gtk.CheckButton() @@ -115,7 +115,13 @@ class FamilyFilterFrame(FilterFrameBase): self._table.attach(filter_label,self._label_col,self._label_col+1,current_row,current_row+1,xoptions=gtk.FILL,yoptions=False) self._table.attach(filter_combo,self._control_col,self._control_col+1,current_row,current_row+1,xoptions=gtk.EXPAND|gtk.FILL,yoptions=False) + if filter_spec is not None: + self._set_filter(filter_spec) + + def _set_filter(filter_spec): + pass + def on_apply(self,button): pass diff --git a/gramps2/src/ObjectSelector/_FamilyFrame.py b/gramps2/src/ObjectSelector/_FamilyFrame.py index 4583e982b..341435cf9 100644 --- a/gramps2/src/ObjectSelector/_FamilyFrame.py +++ b/gramps2/src/ObjectSelector/_FamilyFrame.py @@ -29,12 +29,13 @@ class FamilyFrame(ObjectFrameBase): def __init__(self, dbstate, - uistate): + uistate, + filter_spec=None): ObjectFrameBase.__init__(self, dbstate=dbstate, uistate=uistate, - filter_frame = FamilyFilterFrame(dbstate), + filter_frame = FamilyFilterFrame(filter_spec=filter_spec), preview_frame = FamilyPreviewFrame(dbstate), tree_frame = FamilyTreeFrame(dbstate)) diff --git a/gramps2/src/ObjectSelector/_FamilyPreviewFrame.py b/gramps2/src/ObjectSelector/_FamilyPreviewFrame.py index 83be2f9c5..8cdfdbc83 100644 --- a/gramps2/src/ObjectSelector/_FamilyPreviewFrame.py +++ b/gramps2/src/ObjectSelector/_FamilyPreviewFrame.py @@ -1,9 +1,11 @@ +import os.path import gtk import gobject from logging import getLogger log = getLogger(".ObjectSelector") import ImgManip +import const class FamilyPreviewFrame(gtk.Frame): @@ -79,16 +81,16 @@ class FamilyPreviewFrame(gtk.Frame): image[image_no].set_from_pixbuf(pixbuf) image_no += 1 else: - self._image_l.set_from_file("../person.svg") - self._image_r.set_from_file("../person.svg") + self._image_l.set_from_file(os.path.join(const.rootDir,"person.svg")) + self._image_r.set_from_file(os.path.join(const.rootDir,"person.svg")) except: log.warn("Failed to generate preview for family", exc_info=True) self.clear_object() def clear_object(self): - self._image_l.set_from_file("../person.svg") - self._image_r.set_from_file("../person.svg") + self._image_l.set_from_file(os.path.join(const.rootDir,"person.svg")) + self._image_r.set_from_file(os.path.join(const.rootDir,"person.svg")) if gtk.pygtk_version < (2,8,0): diff --git a/gramps2/src/ObjectSelector/_FilterFrameBase.py b/gramps2/src/ObjectSelector/_FilterFrameBase.py index f36a9fe25..360ad5202 100644 --- a/gramps2/src/ObjectSelector/_FilterFrameBase.py +++ b/gramps2/src/ObjectSelector/_FilterFrameBase.py @@ -16,8 +16,10 @@ class FilterFrameBase(gtk.Frame): __default_border_width = 5 - def __init__(self,dbstate,label="Filter"): + def __init__(self,filter_spec=None,label="Filter"): gtk.Frame.__init__(self,label) + + self._filter_spec = filter_spec align = gtk.Alignment() @@ -54,6 +56,7 @@ class FilterFrameBase(gtk.Frame): self.add(align) + def on_apply(self,button): """Build a GenericFilter object from the settings in the filter controls and emit a 'apply-filter' signal with the GenericFilter object as the parameter.""" diff --git a/gramps2/src/ObjectSelector/_FilterSpec.py b/gramps2/src/ObjectSelector/_FilterSpec.py new file mode 100644 index 000000000..0ea5a39ff --- /dev/null +++ b/gramps2/src/ObjectSelector/_FilterSpec.py @@ -0,0 +1,14 @@ + +class FilterSpecBase(object): + + def __init__(self): + self._gramps_id = None + + def set_gramps_id(self,gramps_id): + self._gramps_id = gramps_id + + def get_gramps_id(self): + return self._gramps_id + + def include_gramps_id(self): + return self._gramps_id is not None diff --git a/gramps2/src/ObjectSelector/_FilterSpecBase.py b/gramps2/src/ObjectSelector/_FilterSpecBase.py new file mode 100644 index 000000000..0ea5a39ff --- /dev/null +++ b/gramps2/src/ObjectSelector/_FilterSpecBase.py @@ -0,0 +1,14 @@ + +class FilterSpecBase(object): + + def __init__(self): + self._gramps_id = None + + def set_gramps_id(self,gramps_id): + self._gramps_id = gramps_id + + def get_gramps_id(self): + return self._gramps_id + + def include_gramps_id(self): + return self._gramps_id is not None diff --git a/gramps2/src/ObjectSelector/_ObjectSelectorWindow.py b/gramps2/src/ObjectSelector/_ObjectSelectorWindow.py index e62030db1..f3bea69e5 100644 --- a/gramps2/src/ObjectSelector/_ObjectSelectorWindow.py +++ b/gramps2/src/ObjectSelector/_ObjectSelectorWindow.py @@ -4,13 +4,18 @@ sys.path.append("..") sys.path.append(".") sys.path.append("ObjectSelector") +import os.path import gtk import gobject +from gettext import gettext as _ import _Factories from _Constants import ObjectTypes from _ObjectSelectorResult import ObjectSelectorResult +from DisplayState import ManagedWindow +import const + class _ObjectTypeWidgets(object): def __init__(self): @@ -37,7 +42,7 @@ OBJECT_LIST = [ObjectTypes.PERSON, ObjectTypes.FAMILY, ObjectTypes.MEDIA, ObjectTypes.PLACE, ObjectTypes.REPOSITORY] -class ObjectSelectorWindow(gtk.Window): +class ObjectSelectorWindow(gtk.Window,ManagedWindow): __gproperties__ = {} @@ -54,13 +59,21 @@ class ObjectSelectorWindow(gtk.Window): def __init__(self, dbstate, uistate, + track, + title = _("Select Object"), + filter_spec = None, default_object_type = ObjectTypes.PERSON, object_list = OBJECT_LIST): - + + # Init the display manager + ManagedWindow.__init__(self,uistate,track,self) + + # Init the Window gtk.Window.__init__(self) self._dbstate = dbstate self._uistate = dbstate + self._track = track self._object_list = object_list self._current_object_type = None @@ -70,7 +83,7 @@ class ObjectSelectorWindow(gtk.Window): for object_type in object_list: self._object_frames[object_type] = _ObjectTypeWidgets() - self.set_title("Add Person") + self.set_title(title) # Selected object label @@ -122,8 +135,8 @@ class ObjectSelectorWindow(gtk.Window): self.__class__.__default_border_width) - person_pixbuf = gtk.gdk.pixbuf_new_from_file("./person.svg") - flist_pixbuf = gtk.gdk.pixbuf_new_from_file("./flist.svg") + person_pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(const.rootDir,"person.svg")) + flist_pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(const.rootDir,"flist.svg")) self._tool_list = gtk.ListStore(gtk.gdk.Pixbuf, str,int) @@ -178,7 +191,7 @@ class ObjectSelectorWindow(gtk.Window): for object_type in object_list: self._object_frames[object_type].frame = \ - _Factories.ObjectFrameFactory().get_frame(object_type,dbstate,uistate) + _Factories.ObjectFrameFactory().get_frame(object_type,dbstate,uistate,filter_spec) # connect signals self._object_frames[object_type].frame.connect( @@ -246,6 +259,8 @@ class ObjectSelectorWindow(gtk.Window): self._set_object_type(default_object_type) self.set_default_size(700,300) + self.show() + def _set_object_type(self,selected_object_type): # enable selected object type diff --git a/gramps2/src/ObjectSelector/_PersonFilterFrame.py b/gramps2/src/ObjectSelector/_PersonFilterFrame.py index d5c971051..5e148d85f 100644 --- a/gramps2/src/ObjectSelector/_PersonFilterFrame.py +++ b/gramps2/src/ObjectSelector/_PersonFilterFrame.py @@ -19,8 +19,8 @@ class PersonFilterFrame(FilterFrameBase): __default_border_width = 5 - def __init__(self,dbstate,label="Filter"): - FilterFrameBase.__init__(self,label) + def __init__(self,filter_spec=None,label="Filter"): + FilterFrameBase.__init__(self,filter_spec,label) # Gramps ID self._id_check = gtk.CheckButton() @@ -86,13 +86,13 @@ class PersonFilterFrame(FilterFrameBase): self._b_unknown = gtk.CheckButton("Include Unknown") self._b_unknown.set_sensitive(False) - self._b_unknown.set_active(True) + self._b_unknown.set_active(False) self._birth_check.connect('toggled',lambda b: self._b_edit.set_sensitive(self._birth_check.get_active())) self._birth_check.connect('toggled',lambda b: self._b_before.set_sensitive(self._birth_check.get_active())) self._birth_check.connect('toggled',lambda b: self._b_after.set_sensitive(self._birth_check.get_active())) - self._birth_check.connect('toggled',lambda b: self._b_unknown.set_sensitive(self._birth_check.get_active())) - + #self._birth_check.connect('toggled',lambda b: self._b_unknown.set_sensitive(self._birth_check.get_active())) + self._b_inner_box = gtk.HBox() self._b_inner_box.pack_start(self._b_before) self._b_inner_box.pack_start(self._b_after) @@ -118,12 +118,12 @@ class PersonFilterFrame(FilterFrameBase): self._d_unknown = gtk.CheckButton("Include Unknown") self._d_unknown.set_sensitive(False) - self._d_unknown.set_active(True) + self._d_unknown.set_active(False) self._death_check.connect('toggled',lambda b: self._d_edit.set_sensitive(self._death_check.get_active())) self._death_check.connect('toggled',lambda b: self._d_before.set_sensitive(self._death_check.get_active())) self._death_check.connect('toggled',lambda b: self._d_after.set_sensitive(self._death_check.get_active())) - self._death_check.connect('toggled',lambda b: self._d_unknown.set_sensitive(self._death_check.get_active())) + #self._death_check.connect('toggled',lambda b: self._d_unknown.set_sensitive(self._death_check.get_active())) d_inner_box = gtk.HBox() d_inner_box.pack_start(self._d_before) @@ -257,7 +257,68 @@ class PersonFilterFrame(FilterFrameBase): self._table.attach(self._filter_combo,self._control_col,self._control_col+1, current_row,current_row+1,xoptions=gtk.EXPAND|gtk.FILL,yoptions=False) - def on_apply(self,button): + if filter_spec is not None: + self._set_filter(filter_spec) + + + def _set_filter(self,filter_spec): + if filter_spec.include_gramps_id(): + self._id_check.set_active(True) + self._id_edit.set_text(filter_spec.get_gramps_id()) + else: + self._id_check.set_active(False) + self._id_edit.set_text("") + + if filter_spec.include_name(): + self._name_check.set_active(True) + self._name_edit.set_text(filter_spec.get_name()) + else: + self._name_check.set_active(False) + self._name_edit.set_text("") + + if filter_spec.include_gender(): + self._gender_check.set_active(True) + store = self._gender_list + it = store.get_iter_first() + while it: + if store.get(it, 1)[0] == filter_spec.get_gender(): + break + it = store.iter_next(it) + + if it != None: + self._gender_combo.set_active_iter(it) + else: + self._gender_check.set_active(False) + + + if filter_spec.include_birth(): + self._birth_check.set_active(True) + self._b_edit.set_text(filter_spec.get_birth_year()) + if filter_spec.get_birth_criteria() == filter_spec.__class__.BEFORE: + self._b_before.set_active(True) + self._b_after.set_active(False) + else: + self._b_before.set_active(False) + self._b_after.set_active(True) + else: + self._birth_check.set_active(False) + self._b_edit.set_text("") + + if filter_spec.include_death(): + self._death_check.set_active(True) + self._d_edit.set_text(filter_spec.get_death_year()) + if filter_spec.get_death_criteria() == filter_spec.__class__.BEFORE: + self._d_before.set_active(True) + self._d_after.set_active(False) + else: + self._d_before.set_active(False) + self._d_after.set_active(True) + else: + self._death_check.set_active(False) + self._d_edit.set_text("") + + + def on_apply(self,button=None): filter = GenericFilter.GenericFilter() if self._id_check.get_active(): diff --git a/gramps2/src/ObjectSelector/_PersonFilterSpec.py b/gramps2/src/ObjectSelector/_PersonFilterSpec.py new file mode 100644 index 000000000..1165dc72f --- /dev/null +++ b/gramps2/src/ObjectSelector/_PersonFilterSpec.py @@ -0,0 +1,65 @@ +from _FilterSpecBase import FilterSpecBase + +class PersonFilterSpec(FilterSpecBase): + + BEFORE = 1 + AFTER = 2 + + def __init__(self): + FilterSpecBase.__init__(self) + + self._name = None + self._gender = None + self._birth_year = None + self._birth_criteria = self.__class__.BEFORE + self._death_year = None + self._death_criteria = self.__class__.BEFORE + + def set_name(self,name): + self._name = name + + def get_name(self): + return self._name + + def include_name(self): + return self._name is not None + + def set_gender(self,gender): + self._gender = gender + + def get_gender(self): + return self._gender + + def include_gender(self): + return self._gender is not None + + def set_birth_year(self,year): + self._birth_year = str(year) + + def get_birth_year(self): + return self._birth_year + + def include_birth(self): + return self._birth_year is not None + + def set_birth_criteria(self,birth_criteria): + self._birth_criteria = birth_criteria + + def get_birth_criteria(self): + return self._birth_criteria + + def set_death_year(self,year): + self._death_year = str(year) + + def get_death_year(self): + return self._death_year + + def include_death(self): + return self._death_year is not None + + def set_death_criteria(self,death_criteria): + self._death_criteria = death_criteria + + def get_death_criteria(self): + return self._death_criteria + diff --git a/gramps2/src/ObjectSelector/_PersonFrame.py b/gramps2/src/ObjectSelector/_PersonFrame.py index 2063592e0..10c174656 100644 --- a/gramps2/src/ObjectSelector/_PersonFrame.py +++ b/gramps2/src/ObjectSelector/_PersonFrame.py @@ -33,12 +33,13 @@ class PersonFrame(ObjectFrameBase): def __init__(self, dbstate, - uistate): + uistate, + filter_spec = None): ObjectFrameBase.__init__(self, dbstate=dbstate, - uistate=uistate, - filter_frame = PersonFilterFrame(dbstate), + uistate=uistate, + filter_frame = PersonFilterFrame(filter_spec=filter_spec), preview_frame = PersonPreviewFrame(dbstate), tree_frame = PersonTreeFrame(dbstate)) @@ -59,6 +60,11 @@ class PersonFrame(ObjectFrameBase): self._filter_frame.connect('apply-filter',lambda w,m: self._tree_frame.set_model(m)) + # Now that the filter is connected we need to tell it to apply any + # filter_spec that may have been passed to it. We can't apply the filter + # until the connections have been made. + self._filter_frame.on_apply() + def _on_row_activated(self,widget,path,col): (model, iter) = widget.get_selection().get_selected() if iter and model.get_value(iter,self.__class__.__person_id_field): diff --git a/gramps2/src/ObjectSelector/_PersonPreviewFrame.py b/gramps2/src/ObjectSelector/_PersonPreviewFrame.py index d52df36ff..bdc942c02 100644 --- a/gramps2/src/ObjectSelector/_PersonPreviewFrame.py +++ b/gramps2/src/ObjectSelector/_PersonPreviewFrame.py @@ -1,9 +1,22 @@ +import os.path + +from xml.sax.saxutils import escape + import gtk import gobject from logging import getLogger log = getLogger(".ObjectSelector") import ImgManip +import const +from ToolTips import PersonTip +import DateHandler + +def short(val,size=60): + if len(val) > size: + return "%s..." % val[0:size] + else: + return val class PersonPreviewFrame(gtk.Frame): @@ -25,17 +38,14 @@ class PersonPreviewFrame(gtk.Frame): self._image = gtk.Image() # test image - self._image.set_from_file("../person.svg") + self._image.set_from_file(os.path.join(const.rootDir,"person.svg")) # Text label = gtk.Label() label.set_use_markup(True) label.set_line_wrap(True) label.set_justify(gtk.JUSTIFY_LEFT) - label.set_alignment(xalign=0.1,yalign=0.1) - label.set_markup("Name: Joe Blogs\n" - "b: 1906\n" - "d: 1937\n") + label.set_alignment(xalign=0.5,yalign=0.1) # box box = gtk.VBox() @@ -56,6 +66,49 @@ class PersonPreviewFrame(gtk.Frame): self.add(align) + self._label = label + + def _get_text_preview(self,person): + global escape + + birth_str = "" + birth_ref = person.get_birth_ref() + if birth_ref: + birth = self._dbstate.db.get_event_from_handle(birth_ref.ref) + date_str = DateHandler.get_date(birth) + if date_str != "": + birth_str = escape(date_str) + + death_str = "" + death_ref = person.get_death_ref() + if death_ref: + death = self._dbstate.db.get_event_from_handle(death_ref.ref) + date_str = DateHandler.get_date(death) + if date_str != "": + death_str = escape(date_str) + + s = "%s\n"\ + " %s: %s\n"\ + " %s: %s\n"\ + " %s: %s\n"% ( + _("Person"), + _("Name"),escape(person.get_primary_name().get_name()), + _("Birth"),birth_str, + _("Death"),death_str) + + if len(person.get_source_references()) > 0: + psrc_ref = person.get_source_references()[0] + psrc_id = psrc_ref.get_base_handle() + psrc = self._dbstate.db.get_source_from_handle(psrc_id) + + s += "\n%s\n"\ + " %s: %s\n" % ( + _("Primary source"), + _("Name"), + escape(short(psrc.get_title()))) + + return s + def set_object_from_id(self,id): try: person = self._dbstate.db.get_person_from_gramps_id(id) @@ -69,14 +122,18 @@ class PersonPreviewFrame(gtk.Frame): pixbuf = ImgManip.get_thumbnail_image(mobj.get_path()) self._image.set_from_pixbuf(pixbuf) else: - self._image.set_from_file("../person.svg") + self._image.set_from_file(os.path.join(const.rootDir,"person.svg")) + + self._label.set_markup(self._get_text_preview(person)) except: log.warn("Failed to generate preview for person", exc_info=True) - self._clear_object() + self.clear_object() def clear_object(self): - self._image.set_from_file("../person.svg") + self._image.set_from_file(os.path.join(const.rootDir,"person.svg")) + self._label.set_markup("") + if gtk.pygtk_version < (2,8,0): gobject.type_register(PersonPreviewFrame) diff --git a/gramps2/src/ObjectSelector/__init__.py b/gramps2/src/ObjectSelector/__init__.py new file mode 100644 index 000000000..901bfdac2 --- /dev/null +++ b/gramps2/src/ObjectSelector/__init__.py @@ -0,0 +1,15 @@ +from gettext import gettext as _ + +from _ObjectSelectorWindow import ObjectSelectorWindow +from _Constants import ObjectTypes +from _PersonFilterSpec import PersonFilterSpec + +class PersonSelector(ObjectSelectorWindow): + """Provides an ObjectSelectorWindow configured for selecting a person object.""" + + def __init__(self,dbstate,uistate,track,filter_spec=None,title=_("Select Person")): + ObjectSelectorWindow.__init__(self,dbstate,uistate,track, + title=title, + filter_spec=filter_spec, + default_object_type = ObjectTypes.PERSON, + object_list = [ObjectTypes.PERSON]) diff --git a/gramps2/src/gramps.py b/gramps2/src/gramps.py index 30883c390..99fd55431 100755 --- a/gramps2/src/gramps.py +++ b/gramps2/src/gramps.py @@ -28,6 +28,7 @@ import os import locale import signal import gettext +import exceptions import logging log = logging.getLogger(".") @@ -124,6 +125,9 @@ def setup_logging(): # put a hook on to catch any completly unhandled exceptions. def exc_hook(type, value, tb): + if type == KeyboardInterrupt: + # Ctrl-C is not a bug. + return import traceback log.error("Unhandled exception\n" + "".join(traceback.format_exception(type, value, tb)))