class PersonChildren(Children): """ Displays the children of a person. """ def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected child.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [('', NOSORT, 50,), (_('Child'), 1, 250), (_('Birth Date'), 3, 100), ('', 3, 100), (_('Death Date'), 5, 100), ('', 5, 100), (_('Spouse'), 6, 250)] self.model = ListModel(top, titles, event_func=self.edit_person) return top def db_changed(self): self.dbstate.db.connect('person-update', self.update) def active_changed(self, handle): self.update() def main(self): active_handle = self.get_active('Person') self.model.clear() if active_handle: self.display_person(active_handle) else: self.set_has_data(False) def update_has_data(self): active_handle = self.get_active('Person') if active_handle: active = self.dbstate.db.get_person_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) else: self.set_has_data(False) def get_has_data(self, active_person): """ Return True if the gramplet has data, else return False. """ if active_person is None: return False for family_handle in active_person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(family_handle) if family and family.get_child_ref_list(): return True return False def display_person(self, active_handle): """ Display the children of the active person. """ active_person = self.dbstate.db.get_person_from_handle(active_handle) for family_handle in active_person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(family_handle) self.display_family(family, active_person) self.set_has_data(self.model.count > 0) def display_family(self, family, active_person): """ Display the children of given family. """ spouse_handle = find_spouse(active_person, family) if spouse_handle: spouse = self.dbstate.db.get_person_from_handle(spouse_handle) else: spouse = None for child_ref in family.get_child_ref_list(): child = self.dbstate.db.get_person_from_handle(child_ref.ref) self.add_child(child, spouse) def add_child(self, child, spouse): """ Add a child to the model. """ name = name_displayer.display(child) if spouse: spouse = name_displayer.display(spouse) spouse = spouse or '' birth = get_birth_or_fallback(self.dbstate.db, child) birth_date, birth_sort, birth_place = self.get_date_place(birth) death = get_death_or_fallback(self.dbstate.db, child) death_date, death_sort, death_place = self.get_date_place(death) self.model.add((child.get_handle(), name, birth_date, birth_sort, death_date, death_sort, spouse))
class MediaBrowser(Gramplet): """ Displays an object tree and a media preview for a person. """ def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET) self.gui.WIDGET.show() def build_gui(self): """ Build the GUI interface. """ top = Gtk.HBox() self.photo = Photo() self.photo.show() view = Gtk.TreeView() titles = [(_("Object"), 1, 250)] self.model = ListModel(view, titles, list_mode="tree", select_func=self.row_selected) top.pack_start(view, True, True, 0) top.pack_start(self.photo, True, False, 5) top.show_all() return top def db_changed(self): self.dbstate.db.connect("person-update", self.update) self.update() def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active("Person") active = self.dbstate.db.get_person_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) def main(self): active_handle = self.get_active("Person") active = self.dbstate.db.get_person_from_handle(active_handle) self.model.clear() self.photo.set_image(None) if active: self.display_data(active) else: self.set_has_data(False) def display_data(self, person): """ Display the object tree for the active person. """ self.add_media(person) self.add_events(person) self.add_sources(person) self.set_has_data(self.model.count > 0) def add_events(self, obj, parent_node=None): """ Add event nodes to the model. """ for event_ref in obj.get_event_ref_list(): handle = event_ref.ref name, event = navigation_label(self.dbstate.db, "Event", handle) node = self.model.add([name], node=parent_node) self.add_sources(event, node) self.add_media(event, node) def add_sources(self, obj, parent_node=None): """ Add source nodes to the model. """ for citation_handle in obj.get_citation_list(): citation = self.dbstate.db.get_citation_from_handle(citation_handle) handle = citation.get_reference_handle() name, src = navigation_label(self.dbstate.db, "Source", handle) node = self.model.add([name], node=parent_node) self.add_media(src, node) def add_media(self, obj, parent_node=None): """ Add media object nodes to the model. """ for media_ref in obj.get_media_list(): handle = media_ref.ref name, media = navigation_label(self.dbstate.db, "Media", handle) full_path = media_path_full(self.dbstate.db, media.get_path()) rect = media_ref.get_rectangle() self.model.add([name], info=media_ref, node=parent_node) def row_selected(self, selection): """ Change the image when a row is selected. """ selected = self.model.get_selected_objects() if selected: if selected[0]: self.load_image(selected[0]) else: self.photo.set_image(None) else: self.photo.set_image(None) def load_image(self, media_ref): """ Display an image from the given media reference. """ media = self.dbstate.db.get_object_from_handle(media_ref.ref) full_path = media_path_full(self.dbstate.db, media.get_path()) mime_type = media.get_mime_type() rectangle = media_ref.get_rectangle() self.photo.set_image(full_path, mime_type, rectangle) def get_has_data(self, person): """ Return True if the gramplet has data, else return False. """ if person is None: return False elif person.get_event_ref_list(): return True elif person.get_citation_list(): return True elif person.get_media_list(): return True return False
class ShowMatches(ManagedWindow): def __init__(self, dbstate, uistate, track, the_list, the_map, callback): ManagedWindow.__init__(self,uistate,track,self.__class__) self.dellist = {} self.list = the_list self.map = the_map self.length = len(self.list) self.update = callback self.db = dbstate.db self.dbstate = dbstate self.uistate = uistate top = Glade(toplevel="mergelist") window = top.toplevel self.set_window(window, top.get_object('title'), _('Potential Merges')) self.mlist = top.get_object("mlist") top.connect_signals({ "destroy_passed_object" : self.close, "on_do_merge_clicked" : self.on_do_merge_clicked, "on_help_show_clicked" : self.on_help_clicked, "on_delete_show_event" : self.close, "on_merge_ok_clicked" : self.__dummy, "on_help_clicked" : self.__dummy, "on_delete_merge_event" : self.__dummy, "on_delete_event" : self.__dummy, }) mtitles = [ (_('Rating'),3,75), (_('First Person'),1,200), (_('Second Person'),2,200), ('',-1,0) ] self.list = ListModel(self.mlist,mtitles, event_func=self.on_do_merge_clicked) self.redraw() self.show() def build_menu_names(self, obj): return (_("Merge candidates"),None) def on_help_clicked(self, obj): """Display the relevant portion of GRAMPS manual""" display_help(WIKI_HELP_PAGE , WIKI_HELP_SEC) def redraw(self): list = [] for p1key, p1data in self.map.items(): if p1key in self.dellist: continue (p2key,c) = p1data if p1key == p2key: continue list.append((c,p1key,p2key)) self.list.clear() for (c,p1key,p2key) in list: c1 = "%5.2f" % c c2 = "%5.2f" % (100-c) p1 = self.db.get_person_from_handle(p1key) p2 = self.db.get_person_from_handle(p2key) if not p1 or not p2: continue pn1 = name_displayer.display(p1) pn2 = name_displayer.display(p2) self.list.add([c1, pn1, pn2,c2],(p1key,p2key)) def on_do_merge_clicked(self, obj): store,iter = self.list.selection.get_selected() if not iter: return (self.p1,self.p2) = self.list.get_object(iter) MergePerson(self.dbstate, self.uistate, self.p1, self.p2, self.on_update, True) def on_update(self): if self.db.has_person_handle(self.p1): phoenix = self.p1 titanic = self.p2 else: phoenix = self.p2 titanic = self.p1 self.dellist[titanic] = phoenix for key, data in self.dellist.items(): if data == titanic: self.dellist[key] = phoenix self.update() self.redraw() def update_and_destroy(self, obj): self.update(1) self.close() def __dummy(self, obj): """dummy callback, needed because a shared glade file is used for both toplevel windows and all signals must be handled. """ pass
class Locations(Gramplet, DbGUIElement): """ Gramplet showing the locations of a place over time. """ def __init__(self, gui, nav_group=0): Gramplet.__init__(self, gui, nav_group) DbGUIElement.__init__(self, self.dbstate.db) def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.WIDGET.show() def _connect_db_signals(self): """ called on init of DbGUIElement, connect to db as required. """ self.callman.register_callbacks({'place-update': self.changed}) self.callman.connect_all(keys=['place']) def db_changed(self): self.connect_signal('Place', self.update) def changed(self, handle): """ Called when a registered place is updated. """ self.update() def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected place.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [('', 0, 50), (_('Name'), 1, 300), (_('Type'), 2, 150), (_('Date'), 5, 250), (_('ID'), 4, 100), ('', NOSORT, 50)] self.model = ListModel(top, titles, list_mode="tree", event_func=self.edit_place) return top def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Place') if active_handle: active = self.dbstate.db.get_place_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) else: self.set_has_data(False) def get_has_data(self, place): """ Return True if the gramplet has data, else return False. """ pass def main(self): self.model.clear() self.callman.unregister_all() active_handle = self.get_active('Place') if active_handle: active = self.dbstate.db.get_place_from_handle(active_handle) if active: self.display_place(active, None, [active_handle]) else: self.set_has_data(False) else: self.set_has_data(False) def display_place(self, place, node, visited): """ Display the location hierarchy for the active place. """ pass def add_place(self, placeref, place, node, visited): """ Add a place to the model. """ place_date = get_date(placeref) place_sort = '%012d' % placeref.get_date_object().get_sort_value() place_name = place.get_name().get_value() place_type = str(place.get_type()) place_id = place.get_gramps_id() new_node = self.model.add([ place.handle, place_name, place_type, place_date, place_id, place_sort ], node=node) self.display_place(place, new_node, visited + [place.handle]) def edit_place(self, treeview): """ Edit the selected place. """ model, iter_ = treeview.get_selection().get_selected() if iter_: handle = model.get_value(iter_, 0) place = self.dbstate.db.get_place_from_handle(handle) try: EditPlace(self.dbstate, self.uistate, [], place) except WindowActiveError: pass
class FamilyChildren(Children): """ Displays the children of a family. """ def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected child.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [('', NOSORT, 50,), (_('Child'), 1, 250), (_('Birth Date'), 3, 100), ('', 3, 100), (_('Death Date'), 5, 100), ('', 5, 100)] self.model = ListModel(top, titles, event_func=self.edit_person) return top def db_changed(self): self.connect(self.dbstate.db, 'family-update', self.update) self.connect_signal('Family', self.update) # familiy active-changed self.connect(self.dbstate.db, 'person-update', self.update) def main(self): active_handle = self.get_active('Family') self.model.clear() if active_handle: family = self.dbstate.db.get_family_from_handle(active_handle) self.display_family(family) else: self.set_has_data(False) def update_has_data(self): active_handle = self.get_active('Family') if active_handle: active = self.dbstate.db.get_family_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) else: self.set_has_data(False) def get_has_data(self, active_family): """ Return True if the gramplet has data, else return False. """ if active_family is None: return False if active_family.get_child_ref_list(): return True return False def display_family(self, family): """ Display the children of given family. """ for child_ref in family.get_child_ref_list(): child = self.dbstate.db.get_person_from_handle(child_ref.ref) self.add_child(child) self.set_has_data(self.model.count > 0) def add_child(self, child): """ Add a child to the model. """ name = name_displayer.display(child) birth = get_birth_or_fallback(self.dbstate.db, child) birth_date, birth_sort, birth_place = self.get_date_place(birth) death = get_death_or_fallback(self.dbstate.db, child) death_date, death_sort, death_place = self.get_date_place(death) self.model.add((child.get_handle(), name, birth_date, birth_sort, death_date, death_sort))
class Locations(Gramplet, DbGUIElement): """ Gramplet showing the locations of a place over time. """ def __init__(self, gui, nav_group=0): Gramplet.__init__(self, gui, nav_group) DbGUIElement.__init__(self, self.dbstate.db) def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.WIDGET.show() def _connect_db_signals(self): """ called on init of DbGUIElement, connect to db as required. """ self.callman.register_callbacks({'place-update': self.changed}) self.callman.connect_all(keys=['place']) def db_changed(self): self.connect_signal('Place', self.update) def changed(self, handle): """ Called when a registered place is updated. """ self.update() def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected place.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [('', 0, 50), (_('Name'), 1, 300), (_('Type'), 2, 150), (_('Date'), 4, 150), ('', NOSORT, 50)] self.model = ListModel(top, titles, list_mode="tree", event_func=self.edit_place) return top def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Place') if active_handle: active = self.dbstate.db.get_place_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) else: self.set_has_data(False) def get_has_data(self, place): """ Return True if the gramplet has data, else return False. """ pass def main(self): self.model.clear() self.callman.unregister_all() active_handle = self.get_active('Place') if active_handle: active = self.dbstate.db.get_place_from_handle(active_handle) if active: self.display_place(active, None, [active_handle]) else: self.set_has_data(False) else: self.set_has_data(False) def display_place(self, place, node, visited): """ Display the location hierarchy for the active place. """ pass def add_place(self, placeref, place, node, visited): """ Add a place to the model. """ place_date = get_date(placeref) place_sort = '%012d' % placeref.get_date_object().get_sort_value() place_name = place.get_name().get_value() place_type = str(place.get_type()) new_node = self.model.add([place.handle, place_name, place_type, place_date, place_sort], node=node) self.display_place(place, new_node, visited + [place.handle]) def edit_place(self, treeview): """ Edit the selected place. """ model, iter_ = treeview.get_selection().get_selected() if iter_: handle = model.get_value(iter_, 0) place = self.dbstate.db.get_place_from_handle(handle) try: EditPlace(self.dbstate, self.uistate, [], place) except WindowActiveError: pass
class Participants(Gramplet, DbGUIElement): """ Displays the participants of an event. """ def __init__(self, gui, nav_group=0): Gramplet.__init__(self, gui, nav_group) DbGUIElement.__init__(self, self.dbstate.db) def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET) self.gui.WIDGET.show() def _connect_db_signals(self): """ called on init of DbGUIElement, connect to db as required. """ self.callman.register_callbacks({'person-update': self.changed, 'event-update': self.changed}) self.callman.connect_all(keys=['person', 'event']) #self.dbstate.db.connect('person-update', self.update) self.connect_signal('Event', self.update) def changed(self, handle): """ Called when a registered person is updated. """ self.update() def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected participant.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [('', NOSORT, 50,), (_('Name'), 1, 250), (_('Role'), 2, 80), (_('Birth Date'), 3, 100), ('', 3, 100), (_('Spouses'), 4, 200)] self.model = ListModel(top, titles, event_func=self.edit_person) return top def display_participants(self, active_handle): """ Display the participants of an event. """ for classname, handle in \ self.dbstate.db.find_backlink_handles(active_handle): if classname == 'Person': self.display_person(handle, active_handle) elif classname == 'Family': self.display_family(handle, active_handle) self.set_has_data(self.model.count > 0) def display_person(self, handle, event_handle): """ Display a participant in the event. """ person = self.dbstate.db.get_person_from_handle(handle) role = self.get_role(person, event_handle) self.add_person(person, role) def display_family(self, handle, event_handle): """ Display a participant in the event. """ family = self.dbstate.db.get_family_from_handle(handle) role = self.get_role(family, event_handle) mother_handle = family.get_mother_handle() if mother_handle: mother = self.dbstate.db.get_person_from_handle(mother_handle) self.add_person(mother, role) father_handle = family.get_father_handle() if father_handle: father = self.dbstate.db.get_person_from_handle(father_handle) self.add_person(father, role) def add_person(self, person, role): """ Add a person to the model. """ self.callman.register_handles({'person': [person.get_handle()]}) name = displayer.display(person) spouses = self.get_spouses(person) birth = get_birth_or_fallback(self.dbstate.db, person) if birth: self.callman.register_handles({'event': [birth.get_handle()]}) birth_date, birth_sort, birth_place = self.get_date_place(birth) self.model.add((person.get_handle(), name, role, birth_date, birth_sort, spouses)) def get_role(self, obj, event_handle): """ Get the role of a person or family in an event. """ for event_ref in obj.get_event_ref_list(): if event_ref.ref == event_handle: return str(event_ref.get_role()) return None def get_spouses(self, person): """ Get the spouses of a given person. """ spouses = [] for handle in person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(handle) father_handle = family.get_father_handle() if father_handle and father_handle != person.get_handle(): self.callman.register_handles({'person': [father_handle]}) father = self.dbstate.db.get_person_from_handle(father_handle) spouses.append(displayer.display(father)) mother_handle = family.get_mother_handle() if mother_handle and mother_handle != person.get_handle(): self.callman.register_handles({'person': [mother_handle]}) mother = self.dbstate.db.get_person_from_handle(mother_handle) spouses.append(displayer.display(mother)) return ' | '.join(spouses) def get_date_place(self, event): """ Return the date and place of the given event. """ event_date = '' event_place = '' event_sort = '%012d' % 0 if event: event_date = get_date(event) event_sort = '%012d' % event.get_date_object().get_sort_value() event_place = place_displayer.display_event(self.dbstate.db, event) return (event_date, event_sort, event_place) def edit_person(self, treeview): """ Edit the selected child. """ model, iter_ = treeview.get_selection().get_selected() if iter_: handle = model.get_value(iter_, 0) try: person = self.dbstate.db.get_person_from_handle(handle) EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass def get_has_data(self, active_handle): """ Return True if the gramplet has data, else return False. """ if active_handle is None: return False for handle in self.dbstate.db.find_backlink_handles(active_handle): return True return False def update_has_data(self): active_handle = self.get_active('Event') self.set_has_data(self.get_has_data(active_handle)) def main(self): active_handle = self.get_active('Event') self.model.clear() self.callman.unregister_all() if active_handle: self.display_participants(active_handle) else: self.set_has_data(False)
class PersonResidence(Gramplet): """ Displays residence events for a person. """ def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.WIDGET.show() def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected event.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [( '', NOSORT, 50, ), (_('Date'), 1, 200), (_('Place'), 2, 200)] self.model = ListModel(top, titles, event_func=self.edit_event) return top def db_changed(self): self.dbstate.db.connect('person-update', self.update) def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Person') if active_handle: active = self.dbstate.db.get_person_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) else: self.set_has_data(False) def get_has_data(self, active_person): """ Return True if the gramplet has data, else return False. """ if active_person: for event_ref in active_person.get_event_ref_list(): if int(event_ref.get_role()) == EventRoleType.PRIMARY: event = self.dbstate.db.get_event_from_handle( event_ref.ref) if int(event.get_type()) == EventType.RESIDENCE: return True return False def main(self): # return false finishes self.model.clear() active_handle = self.get_active('Person') if active_handle: active_person = self.dbstate.db.get_person_from_handle( active_handle) if active_person: self.display_person(active_person) else: self.set_has_data(False) else: self.set_has_data(False) def display_person(self, active_person): """ Display the residence events of the active person. """ count = 0 for event_ref in active_person.get_event_ref_list(): if int(event_ref.get_role()) == EventRoleType.PRIMARY: event = self.dbstate.db.get_event_from_handle(event_ref.ref) if int(event.get_type()) == EventType.RESIDENCE: self.add_residence(event) count += 1 self.set_has_data(count > 0) def add_residence(self, event): """ Add a residence event to the model. """ date = get_date(event) place = '' handle = event.get_place_handle() if handle: place = place_displayer.display_event(self.dbstate.db, event) self.model.add((event.get_handle(), date, place)) def edit_event(self, treeview): """ Edit the selected event. """ model, iter_ = treeview.get_selection().get_selected() if iter_: handle = model.get_value(iter_, 0) try: event = self.dbstate.db.get_event_from_handle(handle) EditEvent(self.dbstate, self.uistate, [], event) except WindowActiveError: pass
class Ancestor(Gramplet): def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET) self.gui.WIDGET.show() def build_gui(self): """ Build the GUI interface. """ self.view = Gtk.TreeView() self.view.set_tooltip_column(3) titles = [ (_('Name'), 0, 230), (_('Birth'), 2, 100), ('', NOSORT, 1), ('', NOSORT, 1), # tooltip ('', NOSORT, 100) ] # handle self.model = ListModel(self.view, titles, list_mode="tree", event_func=self.cb_double_click) return self.view def get_has_data(self, active_handle): """ Return True if the gramplet has data, else return False. """ if active_handle: person = self.dbstate.db.get_person_from_handle(active_handle) if person: family_handle = person.get_main_parents_family_handle() family = self.dbstate.db.get_family_from_handle(family_handle) if family and (family.get_father_handle() or family.get_mother_handle()): return True return False def cb_double_click(self, treeview): """ Handle double click on treeview. """ (model, iter_) = treeview.get_selection().get_selected() if not iter_: return try: handle = model.get_value(iter_, 4) person = self.dbstate.db.get_person_from_handle(handle) EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass def db_changed(self): self.update() def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Person') if active_handle: self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def main(self): active_handle = self.get_active('Person') self.model.clear() if active_handle: self.add_to_tree(1, None, active_handle) self.view.expand_all() self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def add_to_tree(self, depth, parent_id, person_handle): if depth > config.get('behavior.generation-depth'): return person = self.dbstate.db.get_person_from_handle(person_handle) name = name_displayer.display(person) birth = get_birth_or_fallback(self.dbstate.db, person) death = get_death_or_fallback(self.dbstate.db, person) birth_text = birth_date = birth_sort = '' if birth: birth_date = get_date(birth) birth_sort = '%012d' % birth.get_date_object().get_sort_value() birth_text = _('%(abbr)s %(date)s') % \ {'abbr': birth.type.get_abbreviation(), 'date': birth_date} death_date = death_sort = death_text = '' if death: death_date = get_date(death) death_sort = '%012d' % death.get_date_object().get_sort_value() death_text = _('%(abbr)s %(date)s') % \ {'abbr': death.type.get_abbreviation(), 'date': death_date} tooltip = name + '\n' + birth_text + '\n' + death_text label = _('%(depth)s. %(name)s') % {'depth': depth, 'name': name} item_id = self.model.add( [label, birth_date, birth_sort, tooltip, person_handle], node=parent_id) family_handle = person.get_main_parents_family_handle() family = self.dbstate.db.get_family_from_handle(family_handle) if family: if family.get_father_handle(): self.add_to_tree(depth + 1, item_id, family.get_father_handle()) if family.get_mother_handle(): self.add_to_tree(depth + 1, item_id, family.get_mother_handle()) return item_id
class FamilyChildren(Children): """ Displays the children of a family. """ def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected child.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [( '', NOSORT, 50, ), (_('Child'), 1, 250), (_('Birth Date'), 3, 100), ('', 3, 100), (_('Death Date'), 5, 100), ('', 5, 100)] self.model = ListModel(top, titles, event_func=self.edit_person) return top def db_changed(self): self.connect(self.dbstate.db, 'family-update', self.update) self.connect_signal('Family', self.update) # familiy active-changed self.connect(self.dbstate.db, 'person-update', self.update) def main(self): active_handle = self.get_active('Family') self.model.clear() if active_handle: family = self.dbstate.db.get_family_from_handle(active_handle) self.display_family(family) else: self.set_has_data(False) def update_has_data(self): active_handle = self.get_active('Family') if active_handle: active = self.dbstate.db.get_family_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) else: self.set_has_data(False) def get_has_data(self, active_family): """ Return True if the gramplet has data, else return False. """ if active_family is None: return False if active_family.get_child_ref_list(): return True return False def display_family(self, family): """ Display the children of given family. """ for child_ref in family.get_child_ref_list(): child = self.dbstate.db.get_person_from_handle(child_ref.ref) self.add_child(child) self.set_has_data(self.model.count > 0) def add_child(self, child): """ Add a child to the model. """ name = name_displayer.display(child) birth = get_birth_or_fallback(self.dbstate.db, child) birth_date, birth_sort, birth_place = self.get_date_place(birth) death = get_death_or_fallback(self.dbstate.db, child) death_date, death_sort, death_place = self.get_date_place(death) self.model.add((child.get_handle(), name, birth_date, birth_sort, death_date, death_sort))
class MetadataView(Gtk.TreeView): def __init__(self): Gtk.TreeView.__init__(self) self.sections = {} titles = [(_('Key'), 1, 235), (_('Value'), 2, 325)] self.model = ListModel(self, titles, list_mode="tree") def display_exif_tags(self, full_path): """ Display the exif tags. """ self.sections = {} self.model.clear() if not os.path.exists(full_path): return False retval = False with open(full_path, 'rb') as fd: try: buf = fd.read() metadata = GExiv2.Metadata() metadata.open_buf(buf) get_human = metadata.get_tag_interpreted_string for section, key, key2, func in TAGS: if not key in metadata.get_exif_tags(): continue if func is not None: if key2 is None: human_value = func(metadata[key]) else: if key2 in metadata.get_exif_tags(): human_value = func(metadata[key], metadata[key2]) else: human_value = func(metadata[key], None) else: human_value = get_human(key) if key2 in metadata.get_exif_tags(): human_value += ' ' + get_human(key2) label = metadata.get_tag_label(key) node = self.__add_section(section) if human_value is None: human_value = '' self.model.add((label, human_value), node=node) self.model.tree.expand_all() retval = self.model.count > 0 except: pass return retval def __add_section(self, section): """ Add the section heading node to the model. """ if section not in self.sections: node = self.model.add([section, '']) self.sections[section] = node else: node = self.sections[section] return node def get_has_data(self, full_path): """ Return True if the gramplet has data, else return False. """ if not os.path.exists(full_path): return False with open(full_path, 'rb') as fd: retval = False try: buf = fd.read() metadata = GExiv2.Metadata() metadata.open_buf(buf) for tag in TAGS: if tag in metadata.get_exif_tags(): retval = True break except: pass return retval
class Participants(Gramplet, DbGUIElement): """ Displays the participants of an event. """ def __init__(self, gui, nav_group=0): Gramplet.__init__(self, gui, nav_group) DbGUIElement.__init__(self, self.dbstate.db) def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET) self.gui.WIDGET.show() def _connect_db_signals(self): """ called on init of DbGUIElement, connect to db as required. """ self.callman.register_callbacks({'person-update': self.changed, 'event-update': self.changed}) self.callman.connect_all(keys=['person', 'event']) #self.dbstate.db.connect('person-update', self.update) self.connect_signal('Event', self.update) def changed(self, handle): """ Called when a registered person is updated. """ self.update() def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected participant.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [('', NOSORT, 50,), (_('Name'), 1, 250), (_('Role'), 2, 80), (_('Birth Date'), 3, 100), ('', 3, 100), (_('Spouses'), 4, 200)] self.model = ListModel(top, titles, event_func=self.edit_person) return top def display_participants(self, active_handle): """ Display the participants of an event. """ for classname, handle in \ self.dbstate.db.find_backlink_handles(active_handle): if classname == 'Person': self.display_person(handle, active_handle) elif classname == 'Family': self.display_family(handle, active_handle) self.set_has_data(self.model.count > 0) def display_person(self, handle, event_handle): """ Display a participant in the event. """ person = self.dbstate.db.get_person_from_handle(handle) role = self.get_role(person, event_handle) self.add_person(person, role) def display_family(self, handle, event_handle): """ Display a participant in the event. """ family = self.dbstate.db.get_family_from_handle(handle) role = self.get_role(family, event_handle) mother_handle = family.get_mother_handle() mother = self.dbstate.db.get_person_from_handle(mother_handle) self.add_person(mother, role) father_handle = family.get_father_handle() father = self.dbstate.db.get_person_from_handle(father_handle) self.add_person(father, role) def add_person(self, person, role): """ Add a person to the model. """ self.callman.register_handles({'person': [person.get_handle()]}) name = displayer.display(person) spouses = self.get_spouses(person) birth = get_birth_or_fallback(self.dbstate.db, person) self.callman.register_handles({'event': [birth.get_handle()]}) birth_date, birth_sort, birth_place = self.get_date_place(birth) self.model.add((person.get_handle(), name, role, birth_date, birth_sort, spouses)) def get_role(self, obj, event_handle): """ Get the role of a person or family in an event. """ for event_ref in obj.get_event_ref_list(): if event_ref.ref == event_handle: return str(event_ref.get_role()) return None def get_spouses(self, person): """ Get the spouses of a given person. """ spouses = [] for handle in person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(handle) father_handle = family.get_father_handle() if father_handle and father_handle != person.get_handle(): self.callman.register_handles({'person': [father_handle]}) father = self.dbstate.db.get_person_from_handle(father_handle) spouses.append(displayer.display(father)) mother_handle = family.get_mother_handle() if mother_handle and mother_handle != person.get_handle(): self.callman.register_handles({'person': [mother_handle]}) mother = self.dbstate.db.get_person_from_handle(mother_handle) spouses.append(displayer.display(mother)) return ' | '.join(spouses) def get_date_place(self, event): """ Return the date and place of the given event. """ event_date = '' event_place = '' event_sort = '%012d' % 0 if event: event_date = get_date(event) event_sort = '%012d' % event.get_date_object().get_sort_value() handle = event.get_place_handle() if handle: place = self.dbstate.db.get_place_from_handle(handle) event_place = place.get_title() return (event_date, event_sort, event_place) def edit_person(self, treeview): """ Edit the selected child. """ model, iter_ = treeview.get_selection().get_selected() if iter_: handle = model.get_value(iter_, 0) try: person = self.dbstate.db.get_person_from_handle(handle) EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass def get_has_data(self, active_handle): """ Return True if the gramplet has data, else return False. """ if active_handle is None: return False for handle in self.dbstate.db.find_backlink_handles(active_handle): return True return False def update_has_data(self): active_handle = self.get_active('Event') self.set_has_data(self.get_has_data(active_handle)) def main(self): active_handle = self.get_active('Event') self.model.clear() self.callman.unregister_all() if active_handle: self.display_participants(active_handle) else: self.set_has_data(False)
class Descendant(Gramplet): """ Gramplet to display descendants of the active person. """ def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.WIDGET.show() def build_gui(self): """ Build the GUI interface. """ self.view = Gtk.TreeView() self.view.set_tooltip_column(3) titles = [(_('Name'), 0, 230), (_('Birth'), 2, 100), ('', NOSORT, 1), ('', NOSORT, 1), # tooltip ('', NOSORT, 100)] # handle self.model = ListModel(self.view, titles, list_mode="tree", event_func=self.cb_double_click, right_click=self.cb_right_click) return self.view def get_has_data(self, active_handle): """ Return True if the gramplet has data, else return False. """ if active_handle: person = self.dbstate.db.get_person_from_handle(active_handle) if person: for family_handle in person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(family_handle) if family: for child_ref in family.get_child_ref_list(): return True return False def cb_double_click(self, treeview): """ Handle double click on treeview. """ (model, iter_) = treeview.get_selection().get_selected() if not iter_: return try: handle = model.get_value(iter_, 4) person = self.dbstate.db.get_person_from_handle(handle) EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass def cb_right_click(self, treeview, event): """ Handle right click on treeview. """ (model, iter_) = treeview.get_selection().get_selected() sensitivity = 1 if iter_ else 0 menu = Gtk.Menu() menu.set_title(_('Descendent Menu')) entries = [ (_("Edit"), lambda obj: self.cb_double_click(treeview), sensitivity), (None, None, 0), (_("Copy all"), lambda obj: self.on_copy_all(treeview), 1), ] for stock_id, callback, sensitivity in entries: item = Gtk.ImageMenuItem(stock_id) if callback: item.connect("activate", callback) item.set_sensitive(sensitivity) item.show() menu.append(item) self.menu = menu self.menu.popup(None, None, None, None, event.button, event.time) def on_copy_all(self, treeview): """ Copy tree to clipboard. """ model = treeview.get_model() text = model_to_text(model, [0, 1], level=1) text_to_clipboard(text) def db_changed(self): self.update() def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Person') if active_handle: self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def main(self): active_handle = self.get_active('Person') self.model.clear() if active_handle: self.add_to_tree(None, active_handle) self.view.expand_all() self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def add_to_tree(self, parent_id, person_handle): """ Add a person to the tree. """ person = self.dbstate.db.get_person_from_handle(person_handle) name = name_displayer.display(person) birth = get_birth_or_fallback(self.dbstate.db, person) death = get_death_or_fallback(self.dbstate.db, person) birth_text = birth_date = birth_sort = '' if birth: birth_date = get_date(birth) birth_sort = '%012d' % birth.get_date_object().get_sort_value() birth_text = _('%(abbr)s %(date)s') % \ {'abbr': birth.type.get_abbreviation(), 'date': birth_date} death_date = death_sort = death_text = '' if death: death_date = get_date(death) death_sort = '%012d' % death.get_date_object().get_sort_value() death_text = _('%(abbr)s %(date)s') % \ {'abbr': death.type.get_abbreviation(), 'date': death_date} tooltip = name + '\n' + birth_text + '\n' + death_text item_id = self.model.add([name, birth_date, birth_sort, tooltip, person_handle], node=parent_id) for family_handle in person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(family_handle) for child_ref in family.get_child_ref_list(): self.add_to_tree(item_id, child_ref.ref) return item_id
class Ancestor(Gramplet): """ Gramplet to display ancestors of the active person. """ def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.WIDGET.show() def build_gui(self): """ Build the GUI interface. """ self.view = Gtk.TreeView() self.view.set_tooltip_column(3) titles = [ (_('Name'), 0, 230), (_('Birth'), 2, 100), ('', NOSORT, 1), ('', NOSORT, 1), # tooltip ('', NOSORT, 100) ] # handle self.model = ListModel(self.view, titles, list_mode="tree", event_func=self.cb_double_click, right_click=self.cb_right_click) return self.view def get_has_data(self, active_handle): """ Return True if the gramplet has data, else return False. """ if active_handle: person = self.dbstate.db.get_person_from_handle(active_handle) family_handle = person.get_main_parents_family_handle() if family_handle: family = self.dbstate.db.get_family_from_handle(family_handle) if family and (family.get_father_handle() or family.get_mother_handle()): return True return False def cb_double_click(self, treeview): """ Handle double click on treeview. """ (model, iter_) = treeview.get_selection().get_selected() if not iter_: return try: handle = model.get_value(iter_, 4) person = self.dbstate.db.get_person_from_handle(handle) EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass def cb_right_click(self, treeview, event): """ Handle right click on treeview. """ (model, iter_) = treeview.get_selection().get_selected() sensitivity = 1 if iter_ else 0 menu = Gtk.Menu() menu.set_reserve_toggle_size(False) entries = [ (_("Edit"), lambda obj: self.cb_double_click(treeview), sensitivity), (None, None, 0), (_("Copy all"), lambda obj: self.on_copy_all(treeview), 1), ] for title, callback, sensitivity in entries: item = Gtk.MenuItem(label=title) if callback: item.connect("activate", callback) else: item = Gtk.SeparatorMenuItem() item.set_sensitive(sensitivity) item.show() menu.append(item) self.menu = menu self.menu.popup(None, None, None, None, event.button, event.time) def on_copy_all(self, treeview): """ Copy tree to clipboard. """ model = treeview.get_model() text = model_to_text(model, [0, 1], level=1) text_to_clipboard(text) def db_changed(self): self.update() def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Person') if active_handle: self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def main(self): active_handle = self.get_active('Person') self.model.clear() if active_handle: self.add_to_tree(1, None, active_handle) self.view.expand_all() self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def add_to_tree(self, depth, parent_id, person_handle): """ Add a person to the tree. """ if depth > config.get('behavior.generation-depth'): return person = self.dbstate.db.get_person_from_handle(person_handle) name = name_displayer.display(person) birth = get_birth_or_fallback(self.dbstate.db, person) death = get_death_or_fallback(self.dbstate.db, person) birth_text = birth_date = birth_sort = '' if birth: birth_date = get_date(birth) birth_sort = '%012d' % birth.get_date_object().get_sort_value() birth_text = _('%(abbr)s %(date)s') % \ {'abbr': birth.type.get_abbreviation(), 'date': birth_date} death_date = death_sort = death_text = '' if death: death_date = get_date(death) death_sort = '%012d' % death.get_date_object().get_sort_value() death_text = _('%(abbr)s %(date)s') % \ {'abbr': death.type.get_abbreviation(), 'date': death_date} tooltip = name + '\n' + birth_text + '\n' + death_text label = _('%(depth)s. %(name)s') % {'depth': depth, 'name': name} item_id = self.model.add( [label, birth_date, birth_sort, tooltip, person_handle], node=parent_id) family_handle = person.get_main_parents_family_handle() if family_handle: family = self.dbstate.db.get_family_from_handle(family_handle) if family: father_handle = family.get_father_handle() if father_handle: self.add_to_tree(depth + 1, item_id, father_handle) mother_handle = family.get_mother_handle() if mother_handle: self.add_to_tree(depth + 1, item_id, mother_handle) return item_id
class Ancestor(Gramplet): def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.WIDGET.show() def build_gui(self): """ Build the GUI interface. """ self.view = Gtk.TreeView() self.view.set_tooltip_column(3) titles = [(_('Name'), 0, 230), (_('Birth'), 2, 100), ('', NOSORT, 1), ('', NOSORT, 1), # tooltip ('', NOSORT, 100)] # handle self.model = ListModel(self.view, titles, list_mode="tree", event_func=self.cb_double_click) return self.view def get_has_data(self, active_handle): """ Return True if the gramplet has data, else return False. """ if active_handle: person = self.dbstate.db.get_person_from_handle(active_handle) if person: family_handle = person.get_main_parents_family_handle() family = self.dbstate.db.get_family_from_handle(family_handle) if family and (family.get_father_handle() or family.get_mother_handle()): return True return False def cb_double_click(self, treeview): """ Handle double click on treeview. """ (model, iter_) = treeview.get_selection().get_selected() if not iter_: return try: handle = model.get_value(iter_, 4) person = self.dbstate.db.get_person_from_handle(handle) EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass def db_changed(self): self.update() def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Person') if active_handle: self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def main(self): active_handle = self.get_active('Person') self.model.clear() if active_handle: self.add_to_tree(1, None, active_handle) self.view.expand_all() self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def add_to_tree(self, depth, parent_id, person_handle): if depth > config.get('behavior.generation-depth'): return person = self.dbstate.db.get_person_from_handle(person_handle) name = name_displayer.display(person) birth = get_birth_or_fallback(self.dbstate.db, person) death = get_death_or_fallback(self.dbstate.db, person) birth_text = birth_date = birth_sort = '' if birth: birth_date = get_date(birth) birth_sort = '%012d' % birth.get_date_object().get_sort_value() birth_text = _('%(abbr)s %(date)s') % \ {'abbr': birth.type.get_abbreviation(), 'date': birth_date} death_date = death_sort = death_text = '' if death: death_date = get_date(death) death_sort = '%012d' % death.get_date_object().get_sort_value() death_text = _('%(abbr)s %(date)s') % \ {'abbr': death.type.get_abbreviation(), 'date': death_date} tooltip = name + '\n' + birth_text + '\n' + death_text label = _('%(depth)s. %(name)s') % {'depth': depth, 'name': name} item_id = self.model.add([label, birth_date, birth_sort, tooltip, person_handle], node=parent_id) family_handle = person.get_main_parents_family_handle() family = self.dbstate.db.get_family_from_handle(family_handle) if family: if family.get_father_handle(): self.add_to_tree(depth + 1, item_id, family.get_father_handle()) if family.get_mother_handle(): self.add_to_tree(depth + 1, item_id, family.get_mother_handle()) return item_id
class PersonChildren(Children): """ Displays the children of a person. """ def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected child.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [( '', NOSORT, 50, ), (_('Child'), 1, 250), (_('Birth Date'), 3, 100), ('', 3, 100), (_('Death Date'), 5, 100), ('', 5, 100), (_('Spouse'), 6, 250)] self.model = ListModel(top, titles, event_func=self.edit_person) return top def db_changed(self): self.dbstate.db.connect('person-update', self.update) def active_changed(self, handle): self.update() def main(self): active_handle = self.get_active('Person') self.model.clear() if active_handle: self.display_person(active_handle) else: self.set_has_data(False) def update_has_data(self): active_handle = self.get_active('Person') if active_handle: active = self.dbstate.db.get_person_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) else: self.set_has_data(False) def get_has_data(self, active_person): """ Return True if the gramplet has data, else return False. """ if active_person is None: return False for family_handle in active_person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(family_handle) if family and family.get_child_ref_list(): return True return False def display_person(self, active_handle): """ Display the children of the active person. """ active_person = self.dbstate.db.get_person_from_handle(active_handle) for family_handle in active_person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(family_handle) self.display_family(family, active_person) self.set_has_data(self.model.count > 0) def display_family(self, family, active_person): """ Display the children of given family. """ spouse_handle = find_spouse(active_person, family) if spouse_handle: spouse = self.dbstate.db.get_person_from_handle(spouse_handle) else: spouse = None for child_ref in family.get_child_ref_list(): child = self.dbstate.db.get_person_from_handle(child_ref.ref) self.add_child(child, spouse) def add_child(self, child, spouse): """ Add a child to the model. """ name = name_displayer.display(child) if spouse: spouse = name_displayer.display(spouse) spouse = spouse or '' birth = get_birth_or_fallback(self.dbstate.db, child) birth_date, birth_sort, birth_place = self.get_date_place(birth) death = get_death_or_fallback(self.dbstate.db, child) death_date, death_sort, death_place = self.get_date_place(death) self.model.add((child.get_handle(), name, birth_date, birth_sort, death_date, death_sort, spouse))
class DuplicatePeopleToolMatches(ManagedWindow): def __init__(self, dbstate, uistate, track, the_list, the_map, callback): ManagedWindow.__init__(self, uistate, track, self.__class__) self.dellist = set() self.list = the_list self.map = the_map self.length = len(self.list) self.update = callback self.db = dbstate.db self.dbstate = dbstate self.uistate = uistate top = Glade(toplevel="mergelist") window = top.toplevel self.set_window(window, top.get_object('title'), _('Potential Merges')) self.setup_configs('interface.duplicatepeopletoolmatches', 500, 350) self.mlist = top.get_object("mlist") top.connect_signals({ "destroy_passed_object": self.close, "on_do_merge_clicked": self.on_do_merge_clicked, "on_help_show_clicked": self.on_help_clicked, "on_delete_show_event": self.close, "on_merge_ok_clicked": self.__dummy, "on_help_clicked": self.__dummy, "on_delete_merge_event": self.__dummy, "on_delete_event": self.__dummy, }) self.db.connect("person-delete", self.person_delete) mtitles = [(_('Rating'), 3, 75), (_('First Person'), 1, 200), (_('Second Person'), 2, 200), ('', -1, 0)] self.list = ListModel(self.mlist, mtitles, event_func=self.on_do_merge_clicked) self.redraw() self.show() def build_menu_names(self, obj): return (_("Merge candidates"), _("Merge persons")) def on_help_clicked(self, obj): """Display the relevant portion of Gramps manual""" display_help(WIKI_HELP_PAGE, WIKI_HELP_SEC) def redraw(self): list = [] for p1key, p1data in self.map.items(): if p1key in self.dellist: continue (p2key, c) = p1data if p2key in self.dellist: continue if p1key == p2key: continue list.append((c, p1key, p2key)) self.list.clear() for (c, p1key, p2key) in list: c1 = "%5.2f" % c c2 = "%5.2f" % (100 - c) p1 = self.db.get_person_from_handle(p1key) p2 = self.db.get_person_from_handle(p2key) if not p1 or not p2: continue pn1 = name_displayer.display(p1) pn2 = name_displayer.display(p2) self.list.add([c1, pn1, pn2, c2], (p1key, p2key)) def on_do_merge_clicked(self, obj): store, iter = self.list.selection.get_selected() if not iter: return (self.p1, self.p2) = self.list.get_object(iter) MergePerson(self.dbstate, self.uistate, self.track, self.p1, self.p2, self.on_update, True) def on_update(self): if self.db.has_person_handle(self.p1): titanic = self.p2 else: titanic = self.p1 self.dellist.add(titanic) self.update() self.redraw() def update_and_destroy(self, obj): self.update(1) self.close() def person_delete(self, handle_list): """ deal with person deletes outside of the tool """ self.dellist.update(handle_list) self.redraw() def __dummy(self, obj): """dummy callback, needed because a shared glade file is used for both toplevel windows and all signals must be handled. """ pass
class Descendant(Gramplet): def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET) self.gui.WIDGET.show() def build_gui(self): """ Build the GUI interface. """ self.view = Gtk.TreeView() self.view.set_tooltip_column(3) titles = [(_('Name'), 0, 230), (_('Birth'), 2, 100), ('', NOSORT, 1), ('', NOSORT, 1), # tooltip ('', NOSORT, 100)] # handle self.model = ListModel(self.view, titles, list_mode="tree", event_func=self.cb_double_click, right_click=self.cb_right_click) return self.view def get_has_data(self, active_handle): """ Return True if the gramplet has data, else return False. """ if active_handle: person = self.dbstate.db.get_person_from_handle(active_handle) if person: for family_handle in person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(family_handle) if family: for child_ref in family.get_child_ref_list(): return True return False def cb_double_click(self, treeview): """ Handle double click on treeview. """ (model, iter_) = treeview.get_selection().get_selected() if not iter_: return try: handle = model.get_value(iter_, 4) person = self.dbstate.db.get_person_from_handle(handle) EditPerson(self.dbstate, self.uistate, [], person) except WindowActiveError: pass def cb_right_click(self, treeview, event): """ Handle right click on treeview. """ (model, iter_) = treeview.get_selection().get_selected() sensitivity = 1 if iter_ else 0 menu = Gtk.Menu() menu.set_title(_('Descendent Menu')) entries = [ (_("Edit"), lambda obj: self.cb_double_click(treeview), sensitivity), (None, None, 0), (_("Copy all"), lambda obj: self.on_copy_all(treeview), 1), ] for stock_id, callback, sensitivity in entries: item = Gtk.ImageMenuItem(stock_id) if callback: item.connect("activate", callback) item.set_sensitive(sensitivity) item.show() menu.append(item) self.menu = menu self.menu.popup(None, None, None, None, event.button, event.time) def on_copy_all(self, treeview): model = treeview.get_model() text = model_to_text(model, [0, 1], level=1) text_to_clipboard(text) def db_changed(self): self.update() def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Person') if active_handle: self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def main(self): active_handle = self.get_active('Person') self.model.clear() if active_handle: self.add_to_tree(None, active_handle) self.view.expand_all() self.set_has_data(self.get_has_data(active_handle)) else: self.set_has_data(False) def add_to_tree(self, parent_id, person_handle): person = self.dbstate.db.get_person_from_handle(person_handle) name = name_displayer.display(person) birth = get_birth_or_fallback(self.dbstate.db, person) death = get_death_or_fallback(self.dbstate.db, person) birth_text = birth_date = birth_sort = '' if birth: birth_date = get_date(birth) birth_sort = '%012d' % birth.get_date_object().get_sort_value() birth_text = _('%(abbr)s %(date)s') % \ {'abbr': birth.type.get_abbreviation(), 'date': birth_date} death_date = death_sort = death_text = '' if death: death_date = get_date(death) death_sort = '%012d' % death.get_date_object().get_sort_value() death_text = _('%(abbr)s %(date)s') % \ {'abbr': death.type.get_abbreviation(), 'date': death_date} tooltip = name + '\n' + birth_text + '\n' + death_text item_id = self.model.add([name, birth_date, birth_sort, tooltip, person_handle], node=parent_id) for family_handle in person.get_family_handle_list(): family = self.dbstate.db.get_family_from_handle(family_handle) for child_ref in family.get_child_ref_list(): self.add_to_tree(item_id, child_ref.ref) return item_id
class MediaBrowser(Gramplet): """ Displays an object tree and a media preview for a person. """ def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET) self.gui.WIDGET.show() def build_gui(self): """ Build the GUI interface. """ top = Gtk.HBox() self.photo = Photo() self.photo.show() view = Gtk.TreeView() titles = [(_('Object'), 1, 250)] self.model = ListModel(view, titles, list_mode="tree", select_func=self.row_selected) top.pack_start(view, True, True, 0) top.pack_start(self.photo, True, False, 5) top.show_all() return top def db_changed(self): self.dbstate.db.connect('person-update', self.update) self.update() def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Person') active = self.dbstate.db.get_person_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) def main(self): active_handle = self.get_active('Person') active = self.dbstate.db.get_person_from_handle(active_handle) self.model.clear() self.photo.set_image(None) if active: self.display_data(active) else: self.set_has_data(False) def display_data(self, person): """ Display the object tree for the active person. """ self.add_media(person) self.add_events(person) self.add_sources(person) self.set_has_data(self.model.count > 0) def add_events(self, obj, parent_node=None): """ Add event nodes to the model. """ for event_ref in obj.get_event_ref_list(): handle = event_ref.ref name, event = navigation_label(self.dbstate.db, 'Event', handle) node = self.model.add([name], node=parent_node) self.add_sources(event, node) self.add_media(event, node) def add_sources(self, obj, parent_node=None): """ Add source nodes to the model. """ for citation_handle in obj.get_citation_list(): citation = self.dbstate.db.get_citation_from_handle(citation_handle) handle = citation.get_reference_handle() name, src = navigation_label(self.dbstate.db, 'Source', handle) node = self.model.add([name], node=parent_node) self.add_media(src, node) def add_media(self, obj, parent_node=None): """ Add media object nodes to the model. """ for media_ref in obj.get_media_list(): handle = media_ref.ref name, media = navigation_label(self.dbstate.db, 'Media', handle) full_path = media_path_full(self.dbstate.db, media.get_path()) rect = media_ref.get_rectangle() self.model.add([name], info=media_ref, node=parent_node) def row_selected(self, selection): """ Change the image when a row is selected. """ selected = self.model.get_selected_objects() if selected: if selected[0]: self.load_image(selected[0]) else: self.photo.set_image(None) else: self.photo.set_image(None) def load_image(self, media_ref): """ Display an image from the given media reference. """ media = self.dbstate.db.get_object_from_handle(media_ref.ref) full_path = media_path_full(self.dbstate.db, media.get_path()) mime_type = media.get_mime_type() rectangle = media_ref.get_rectangle() self.photo.set_image(full_path, mime_type, rectangle) def get_has_data(self, person): """ Return True if the gramplet has data, else return False. """ if person is None: return False elif person.get_event_ref_list(): return True elif person.get_citation_list(): return True elif person.get_media_list(): return True return False
class PersonResidence(Gramplet): """ Displays residence events for a person. """ def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add(self.gui.WIDGET) self.gui.WIDGET.show() def build_gui(self): """ Build the GUI interface. """ tip = _('Double-click on a row to edit the selected event.') self.set_tooltip(tip) top = Gtk.TreeView() titles = [('', NOSORT, 50,), (_('Date'), 1, 200), (_('Place'), 2, 200)] self.model = ListModel(top, titles, event_func=self.edit_event) return top def db_changed(self): self.dbstate.db.connect('person-update', self.update) def active_changed(self, handle): self.update() def update_has_data(self): active_handle = self.get_active('Person') if active_handle: active = self.dbstate.db.get_person_from_handle(active_handle) self.set_has_data(self.get_has_data(active)) else: self.set_has_data(False) def get_has_data(self, active_person): """ Return True if the gramplet has data, else return False. """ if active_person: for event_ref in active_person.get_event_ref_list(): if int(event_ref.get_role()) == EventRoleType.PRIMARY: event = self.dbstate.db.get_event_from_handle(event_ref.ref) if int(event.get_type()) == EventType.RESIDENCE: return True return False def main(self): # return false finishes self.model.clear() active_handle = self.get_active('Person') if active_handle: active_person = self.dbstate.db.get_person_from_handle(active_handle) if active_person: self.display_person(active_person) else: self.set_has_data(False) else: self.set_has_data(False) def display_person(self, active_person): """ Display the residence events of the active person. """ count = 0 for event_ref in active_person.get_event_ref_list(): if int(event_ref.get_role()) == EventRoleType.PRIMARY: event = self.dbstate.db.get_event_from_handle(event_ref.ref) if int(event.get_type()) == EventType.RESIDENCE: self.add_residence(event) count += 1 self.set_has_data(count > 0) def add_residence(self, event): """ Add a residence event to the model. """ date = get_date(event) place = '' handle = event.get_place_handle() if handle: place = place_displayer.display_event(self.dbstate.db, event) self.model.add((event.get_handle(), date, place)) def edit_event(self, treeview): """ Edit the selected event. """ model, iter_ = treeview.get_selection().get_selected() if iter_: handle = model.get_value(iter_, 0) try: event = self.dbstate.db.get_event_from_handle(handle) EditEvent(self.dbstate, self.uistate, [], event) except WindowActiveError: pass