diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index a446c67b1..fa959d6af 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,10 @@ +2006-01-17 Richard Taylor + * src/ObjectSelector/_FamilyFrame.py, src/ObjectSelector/_FamilyPreviewFrame.py, + src/ObjectSelector/_ObjectFrameBase.py, src/ObjectSelector/_ObjectSelectorWindow.py, + src/ObjectSelector/_PersonFrame.py, src/ObjectSelector/_PersonPreviewFrame.py, + src/ObjectSelector/_PersonTreeFrame.py src/ObjectSelector/_ObjectSelectorResult.py: + object selection and initial preview works for Family and Person + 2006-01-17 Richard Taylor * src/ObjectSelector/_FamilyFrame.py: basic object selection now working * src/ObjectSelector/_FamilyTreeFrame.py: basic object selection now working diff --git a/gramps2/src/ObjectSelector/_Factories.py b/gramps2/src/ObjectSelector/_Factories.py index f8b9274b9..ebf184dd5 100644 --- a/gramps2/src/ObjectSelector/_Factories.py +++ b/gramps2/src/ObjectSelector/_Factories.py @@ -1,7 +1,6 @@ from _Constants import ObjectTypes from _PersonFrame import PersonFrame - from _FamilyFrame import FamilyFrame diff --git a/gramps2/src/ObjectSelector/_FamilyFrame.py b/gramps2/src/ObjectSelector/_FamilyFrame.py index 1ab72c86f..236d90718 100644 --- a/gramps2/src/ObjectSelector/_FamilyFrame.py +++ b/gramps2/src/ObjectSelector/_FamilyFrame.py @@ -21,7 +21,7 @@ class FamilyFrame(ObjectFrameBase): gobject.TYPE_STRING)), } - __default_border_width = 5 + __person_id_field = 0 def __init__(self, dbstate): @@ -34,7 +34,7 @@ class FamilyFrame(ObjectFrameBase): def handle_selection(treeselection): (model, iter) = treeselection.get_selected() - if iter: + if iter and model.get_value(iter,0): self.emit('selection-changed', "%s / %s (%s)" % ( str(model.get_value(iter,1)), str(model.get_value(iter,2)), @@ -46,14 +46,8 @@ class FamilyFrame(ObjectFrameBase): self._tree_frame.get_selection().connect('changed',handle_selection) - def set_preview_frame_sensitivity(treeselection): - (model, iter) = treeselection.get_selected() - if iter: - self._preview_frame.set_sensitive(True) - else: - self._preview_frame.set_sensitive(False) + self._tree_frame.get_selection().connect('changed',self.set_preview,self.__class__.__person_id_field) - self._tree_frame.get_selection().connect('changed',set_preview_frame_sensitivity) diff --git a/gramps2/src/ObjectSelector/_FamilyPreviewFrame.py b/gramps2/src/ObjectSelector/_FamilyPreviewFrame.py index 53adca404..daede31de 100644 --- a/gramps2/src/ObjectSelector/_FamilyPreviewFrame.py +++ b/gramps2/src/ObjectSelector/_FamilyPreviewFrame.py @@ -1,5 +1,9 @@ import gtk import gobject +from logging import getLogger +log = getLogger(".ObjectSelector") + +import ImgManip class FamilyPreviewFrame(gtk.Frame): @@ -13,15 +17,21 @@ class FamilyPreviewFrame(gtk.Frame): def __init__(self,dbstate,label="Preview"): gtk.Frame.__init__(self,label) + self._dbstate = dbstate + align = gtk.Alignment() # Image - image = gtk.Image() + self._image_l = gtk.Image() + self._image_r = gtk.Image() + image_box = gtk.HBox() + image_box.pack_start(self._image_l) + image_box.pack_start(self._image_r) + # test image - image.set_from_file("../flist.svg") image_frame = gtk.Frame() - image_frame.add(image) + image_frame.add(image_box) # Text label = gtk.Label() @@ -52,7 +62,38 @@ class FamilyPreviewFrame(gtk.Frame): self.add(align) - + self.clear_object() + + def set_object_from_id(self,id): + try: + family = self._dbstate.db.get_family_from_gramps_id(id) + + image = [self._image_l, self._image_r] + image_no = 0 + for person_handle in (family.get_father_handle(),family.get_mother_handle()): + person = self._dbstate.db.get_person_from_handle(person_handle) + if not person: + return + + image_list = person.get_media_list() + if image_list: + mobj = self._dbstate.db.get_object_from_handle(image_list[0].ref) + if mobj.get_mime_type()[0:5] == "image": + pixbuf = ImgManip.get_thumbnail_image(mobj.get_path()) + 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") + + 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") + if gtk.pygtk_version < (2,8,0): gobject.type_register(FamilyPreviewFrame) diff --git a/gramps2/src/ObjectSelector/_FamilyTreeFrame.py b/gramps2/src/ObjectSelector/_FamilyTreeFrame.py index 2bd987893..b475852bb 100644 --- a/gramps2/src/ObjectSelector/_FamilyTreeFrame.py +++ b/gramps2/src/ObjectSelector/_FamilyTreeFrame.py @@ -49,10 +49,7 @@ class FamilyTreeFrame(gtk.Frame): scrollwindow.add(self._list) - self._inactive = False - self._selection = self._list.get_selection() - #self._selection.connect('changed',self._row_changed) self.add(scrollwindow) diff --git a/gramps2/src/ObjectSelector/_ObjectFrameBase.py b/gramps2/src/ObjectSelector/_ObjectFrameBase.py index e3cd2a5a7..0e04e2520 100644 --- a/gramps2/src/ObjectSelector/_ObjectFrameBase.py +++ b/gramps2/src/ObjectSelector/_ObjectFrameBase.py @@ -57,6 +57,17 @@ class ObjectFrameBase(gtk.Frame): self.add(pane_align) + + def set_preview(self,treeselection,id_field): + (model, iter) = treeselection.get_selected() + if iter and model.get_value(iter,id_field): + self._preview_frame.set_sensitive(True) + self._preview_frame.set_object_from_id(model.get_value(iter,id_field)) + else: + self._preview_frame.set_sensitive(False) + self._preview_frame.clear_object() + + def get_selection(self): return self._tree_frame.get_selection() diff --git a/gramps2/src/ObjectSelector/_ObjectSelectorResult.py b/gramps2/src/ObjectSelector/_ObjectSelectorResult.py new file mode 100644 index 000000000..a56856be0 --- /dev/null +++ b/gramps2/src/ObjectSelector/_ObjectSelectorResult.py @@ -0,0 +1,46 @@ + +from _Constants import ObjectTypes + +class ObjectSelectorResult(object): + + def __init__(self): + self._gramps_id = None + self._object_type = None + + def __str__(self): + return "Object Type = %s\n"\ + "Gramps ID = %s" % (str(self._object_type), + str(self._gramps_id)) + + def set_gramps_id(self,id): + self._gramps_id = id + + def get_gramps_id(self): + return self._gramps_id + + def set_object_type(self,object_type): + self._object_type = object_type + + def get_object_type(self,object_type): + return self._object_type + + def is_person(self): + return self._object_type == ObjectTypes.PERSON + + def is_family(self): + return self._object_type == ObjectTypes.FAMILY + + def is_event(self): + return self._object_type == ObjectTypes.EVENT + + def is_source(self): + return self._object_type == ObjectTypes.SOURCE + + def is_repository(self): + return self._object_type == ObjectTypes.REPOSITORY + + def is_media(self): + return self._object_type == ObjectTypes.MEDIA + + def is_place(self): + return self._object_type == ObjectTypes.PLACE diff --git a/gramps2/src/ObjectSelector/_ObjectSelectorWindow.py b/gramps2/src/ObjectSelector/_ObjectSelectorWindow.py index b4ea1ab48..c208dfdf2 100644 --- a/gramps2/src/ObjectSelector/_ObjectSelectorWindow.py +++ b/gramps2/src/ObjectSelector/_ObjectSelectorWindow.py @@ -7,12 +7,14 @@ import gobject import _Factories from _Constants import ObjectTypes +from _ObjectSelectorResult import ObjectSelectorResult class _ObjectTypeWidgets(object): def __init__(self): self.frame = None self.sel_label = None + self.selected_id = None def show(self): self.frame.show_all() @@ -22,16 +24,22 @@ class _ObjectTypeWidgets(object): self.frame.hide_all() self.sel_label.hide_all() + def set_selected_id(self,id): + self.selected_id = id + OBJECT_LIST = [ObjectTypes.PERSON, ObjectTypes.FAMILY, ObjectTypes.SOURCE, ObjectTypes.EVENT, ObjectTypes.MEDIA, ObjectTypes.PLACE, - ObjectTypes.REPOSITORY, ObjectTypes.REFERENCE] + ObjectTypes.REPOSITORY] class ObjectSelectorWindow(gtk.Window): __gproperties__ = {} __gsignals__ = { + 'add-object' : (gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), } __default_border_width = 5 @@ -47,6 +55,7 @@ class ObjectSelectorWindow(gtk.Window): self._dbstate = dbstate self._object_list = object_list + self._current_object_type = None self.set_title("Add Person") @@ -146,15 +155,25 @@ class ObjectSelectorWindow(gtk.Window): lambda widget,text,handle,label: label.set_text(text), self._object_frames[object_type].sel_label) + self._object_frames[object_type].frame.connect( + 'selection-changed', + lambda widget,text,handle,current_object: current_object.set_selected_id(handle), + self._object_frames[object_type]) + + self._object_frames[object_type].frame.connect( + 'selection-changed', + self.on_selection_changed) + frame_box.pack_start(self._object_frames[object_type].frame,True,True) - self._set_object_type(default_object_type) # Bottom buttons - add_button = gtk.Button(stock=gtk.STOCK_ADD) - add_button.set_sensitive(False) - add_button.show() + self._add_button = gtk.Button(stock=gtk.STOCK_ADD) + self._add_button.set_sensitive(False) + self._add_button.show() + + self._add_button.connect("clicked", self.on_add) cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL) cancel_button.show() @@ -166,7 +185,7 @@ class ObjectSelectorWindow(gtk.Window): bottom_button_bar.set_spacing(self.__class__.__default_border_width/2) bottom_button_bar.set_border_width(self.__class__.__default_border_width) bottom_button_bar.add(cancel_button) - bottom_button_bar.add(add_button) + bottom_button_bar.add(self._add_button) bottom_button_bar.show() box = gtk.VBox() @@ -186,15 +205,20 @@ class ObjectSelectorWindow(gtk.Window): self.add(align) + self._set_object_type(default_object_type) + def _set_object_type(self,selected_object_type): - # enable default + # enable selected object type self._object_frames[selected_object_type].show() # disable all the others [ self._object_frames[object_type].hide() for object_type in self._object_list if object_type != selected_object_type] + # Set the object selector list to the selected object type + # this is required because we may be asked to set the object type + # without the use selecting it explicitly from the list. store = self._tool_list it = store.get_iter_first() while it: @@ -204,7 +228,32 @@ class ObjectSelectorWindow(gtk.Window): if it != None: self._tool_combo.set_active_iter(it) - + + self._current_object_type = selected_object_type + + # Set the add button sensitivity + if self._object_frames[selected_object_type].selected_id: + self._add_button.set_sensitive(True) + else: + self._add_button.set_sensitive(False) + + + def get_result(self): + result = ObjectSelectorResult() + result.set_object_type(self._current_object_type) + result.set_gramps_id(self._object_frames[self._current_object_type].selected_id) + return result + + def on_add(self,button): + self.emit('add-object',self.get_result()) + + def on_selection_changed(self,widget,text,handle): + if handle: + self._add_button.set_sensitive(True) + else: + self._add_button.set_sensitive(False) + + if gtk.pygtk_version < (2,8,0): gobject.type_register(PersonSearchCriteriaWidget) @@ -214,11 +263,24 @@ if __name__ == "__main__": import GrampsDb import const + import logging + import sys,os.path + + form = logging.Formatter(fmt="%(relativeCreated)d: %(levelname)s: %(filename)s: line %(lineno)d: %(message)s") + stderrh = logging.StreamHandler(sys.stderr) + stderrh.setFormatter(form) + stderrh.setLevel(logging.DEBUG) + + # everything. + l = logging.getLogger() + l.setLevel(logging.DEBUG) + l.addHandler(stderrh) + def cb(d): pass db = GrampsDb.gramps_db_factory(const.app_gramps)() - db.load("/home/rtaylor/devel/Personal/gramps/test/Untitled_2.grdb", + db.load(os.path.realpath(sys.argv[1]), cb, # callback "w") class D: @@ -226,7 +288,7 @@ if __name__ == "__main__": dbstate = D() dbstate.db = db - + w = ObjectSelectorWindow(dbstate=dbstate, default_object_type = ObjectTypes.FAMILY, @@ -235,4 +297,9 @@ if __name__ == "__main__": w.show() w.connect("destroy", gtk.main_quit) + def add(w,results): + print str(results) + + w.connect('add-object',add) + gtk.main() diff --git a/gramps2/src/ObjectSelector/_PersonFrame.py b/gramps2/src/ObjectSelector/_PersonFrame.py index 5f4530a0d..3e8834357 100644 --- a/gramps2/src/ObjectSelector/_PersonFrame.py +++ b/gramps2/src/ObjectSelector/_PersonFrame.py @@ -21,6 +21,8 @@ class PersonFrame(ObjectFrameBase): gobject.TYPE_STRING)), } + __person_id_field = 1 + def __init__(self, dbstate): @@ -32,14 +34,20 @@ class PersonFrame(ObjectFrameBase): def handle_selection(treeselection): (model, iter) = treeselection.get_selected() - self.emit('selection-changed', "%s (%s)" % ( - str(model.get_value(iter,0)), - str(model.get_value(iter,1))), - model.get_value(iter,0)) + if iter and model.get_value(iter,1): + self.emit('selection-changed', "%s (%s)" % ( + str(model.get_value(iter,0)), + str(model.get_value(iter,1))), + model.get_value(iter,1)) + else: + self.emit('selection-changed',"No Selection","") self._tree_frame.get_selection().connect('changed',handle_selection) + + self._tree_frame.get_selection().connect('changed',self.set_preview,self.__class__.__person_id_field) + if gtk.pygtk_version < (2,8,0): gobject.type_register(PersonFrame) diff --git a/gramps2/src/ObjectSelector/_PersonPreviewFrame.py b/gramps2/src/ObjectSelector/_PersonPreviewFrame.py index b5b9af0a0..b1256198e 100644 --- a/gramps2/src/ObjectSelector/_PersonPreviewFrame.py +++ b/gramps2/src/ObjectSelector/_PersonPreviewFrame.py @@ -1,5 +1,9 @@ import gtk import gobject +from logging import getLogger +log = getLogger(".ObjectSelector") + +import ImgManip class PersonPreviewFrame(gtk.Frame): @@ -13,15 +17,17 @@ class PersonPreviewFrame(gtk.Frame): def __init__(self,dbstate,label="Preview"): gtk.Frame.__init__(self,label) + self._dbstate = dbstate + align = gtk.Alignment() # Image - image = gtk.Image() + self._image = gtk.Image() # test image - image.set_from_file("../person.svg") + self._image.set_from_file("../person.svg") image_frame = gtk.Frame() - image_frame.add(image) + image_frame.add(self._image) # Text label = gtk.Label() @@ -52,7 +58,27 @@ class PersonPreviewFrame(gtk.Frame): self.add(align) - + def set_object_from_id(self,id): + try: + person = self._dbstate.db.get_person_from_gramps_id(id) + if not person: + return + + image_list = person.get_media_list() + if image_list: + mobj = self._dbstate.db.get_object_from_handle(image_list[0].ref) + if mobj.get_mime_type()[0:5] == "image": + pixbuf = ImgManip.get_thumbnail_image(mobj.get_path()) + self._image.set_from_pixbuf(pixbuf) + else: + self._image.set_from_file("../person.svg") + + except: + log.warn("Failed to generate preview for person", exc_info=True) + self._clear_object() + + def clear_object(self): + self._image.set_from_file("../person.svg") if gtk.pygtk_version < (2,8,0): gobject.type_register(PersonPreviewFrame) diff --git a/gramps2/src/ObjectSelector/_PersonTreeFrame.py b/gramps2/src/ObjectSelector/_PersonTreeFrame.py index edcea1daf..61553b862 100644 --- a/gramps2/src/ObjectSelector/_PersonTreeFrame.py +++ b/gramps2/src/ObjectSelector/_PersonTreeFrame.py @@ -58,9 +58,14 @@ class PersonTreeFrame(gtk.Frame): column.set_min_width(60) column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) self._tree.append_column(column) - - self.add(self._tree) - self.set_shadow_type(gtk.SHADOW_IN) + + scrollwindow = gtk.ScrolledWindow() + scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrollwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN) + + scrollwindow.add(self._tree) + + self.add(scrollwindow) self.set_model(self._dbstate.db)