diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index 623a59d9f..22b890d86 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,19 @@ +2004-09-30 Don Allingham + * src/DisplayModels.py: change 0 to False + * src/EditPerson.py: copy current name info to name editor when invoking + * src/GrampsBSDDB.py: provide default name to group mapping + * src/GrampsDbBase.py: provide default name to group mapping + * src/GrampsInMemDB.py: provide default name to group mapping + * src/NameEdit.py: prompt for making name mapping override the default + or purely for the active name + * src/PeopleModel.py: handle name grouping + * src/PeopleView.py: handle name grouping + * src/QuestionDialog.py: Add QuestionDialog2 to allow two answers to + a dialog (instead of one being cancel) + * src/RelLib.py: grouping documentation + * src/gramps.glade: move button on EditPerson dialog + * src/gramps_main.py: goto active person after a redisplay + 2004-09-29 Alex Roitman * src/TipOfDay.py: Be tolerant to whitespace; allow markup in the tips, enable random sequence of tips on each startup. diff --git a/gramps2/src/DisplayModels.py b/gramps2/src/DisplayModels.py index 1a476f2b8..468abaef2 100644 --- a/gramps2/src/DisplayModels.py +++ b/gramps2/src/DisplayModels.py @@ -124,7 +124,7 @@ class BaseModel(gtk.GenericTreeModel): def on_iter_n_children(self,node): if node == None: return len(self.datalist) - return False + return 0 def on_iter_nth_child(self,node,n): if node == None: diff --git a/gramps2/src/EditPerson.py b/gramps2/src/EditPerson.py index 9bc0fa89f..e212bc440 100644 --- a/gramps2/src/EditPerson.py +++ b/gramps2/src/EditPerson.py @@ -426,7 +426,7 @@ class EditPerson: "on_update_url_clicked" : self.on_update_url_clicked, "on_web_go_clicked" : self.on_web_go_clicked, "on_gender_activate" : self.on_gender_activate, - "on_givenName_focus_out_event": self.on_givenName_focus_out_event, + "on_given_focus_out" : self.on_given_focus_out_event, "on_help_person_clicked" : self.on_help_clicked, }) @@ -608,7 +608,7 @@ class EditPerson: def on_gender_activate (self, button): self.should_guess_gender = False - def on_givenName_focus_out_event (self, entry, event): + def on_given_focus_out_event (self, entry, event): if not self.should_guess_gender: return @@ -1624,7 +1624,6 @@ class EditPerson: if not self.person.get_gramps_id(): self.person.set_gramps_id(self.db.find_next_person_gramps_id()) self.db.commit_person(self.person, trans) - print "id",self.person.get_gramps_id() n = self.person.get_primary_name().get_regular_name() self.db.transaction_commit(trans,_("Edit Person (%s)") % n) if self.callback: @@ -1652,6 +1651,14 @@ class EditPerson: def on_edit_name_clicked(self,obj): import NameEdit + + ntype = unicode(self.ntype_field.child.get_text()) + self.pname.set_type(const.NameTypesMap.find_value(ntype)) + self.pname.set_suffix(unicode(self.suffix.get_text())) + self.pname.set_surname_prefix(unicode(self.prefix.get_text())) + self.pname.set_first_name(unicode(self.given.get_text())) + self.pname.set_title(unicode(self.title.get_text())) + NameEdit.NameEditor(self,self.pname,self.update_name,self.window) def update_name(self,name): diff --git a/gramps2/src/GrampsBSDDB.py b/gramps2/src/GrampsBSDDB.py index 0b6dc3443..68d5b7973 100644 --- a/gramps2/src/GrampsBSDDB.py +++ b/gramps2/src/GrampsBSDDB.py @@ -29,7 +29,7 @@ from GrampsDbBase import * from bsddb import dbshelve, db def find_surname(key,data): - return str(data[3].get_group_as()) + return str(data[3].get_surname()) def find_idmap(key,data): return str(data[1]) @@ -77,6 +77,10 @@ class GrampsBSDDB(GrampsDbBase): self.surnames.set_flags(db.DB_DUP) self.surnames.open(name, "surnames", db.DB_HASH, flags=db.DB_CREATE) + self.name_group = db.DB(self.env) + self.name_group.set_flags(db.DB_DUP) + self.name_group.open(name, "name_group", db.DB_HASH, flags=db.DB_CREATE) + self.id_trans = db.DB(self.env) self.id_trans.set_flags(db.DB_DUP) self.id_trans.open(name, "idtrans", db.DB_HASH, flags=db.DB_CREATE) @@ -119,6 +123,7 @@ class GrampsBSDDB(GrampsDbBase): return 1 def close(self): + self.name_group.close() self.person_map.close() self.family_map.close() self.place_map.close() @@ -153,6 +158,13 @@ class GrampsBSDDB(GrampsDbBase): self.env = None self.metadata = None + def set_name_group_mapping(self,name,group): + name = str(name) + if not group and self.name_group.has_key(name): + self.name_group.delete(name) + else: + self.name_group[name] = group + def get_surname_list(self): names = self.surnames.keys() a = {} diff --git a/gramps2/src/GrampsDbBase.py b/gramps2/src/GrampsDbBase.py index 4506af72e..5841b75b6 100644 --- a/gramps2/src/GrampsDbBase.py +++ b/gramps2/src/GrampsDbBase.py @@ -97,6 +97,7 @@ class GrampsDbBase: self.event_map = None self.eventnames = None self.metadata = None + self.name_group = None self.undo_callback = None self.redo_callback = None self.modified = 0 @@ -108,6 +109,7 @@ class GrampsDbBase: self.bookmarks = [] self.path = "" self.place2title = {} + self.name_groups = {} def load(self,name,callback): """ @@ -554,6 +556,25 @@ class GrampsDbBase: self.commit_media_object(obj,transaction) return index + def get_name_group_mapping(self,name): + """ + Returns the default grouping name for a surname + """ + return self.name_group.get(str(name),name) + + def get_name_group_keys(self): + """ + Returns the defined names that have been assigned to a default grouping + """ + return [unicode(k) for k in self.name_group.keys()] + + def set_name_group_mapping(self,name,group): + """ + Sets the default grouping name for a surname. Needs to be overridden in the + derived class. + """ + assert False, "Needs to be overridden in the derived class" + def get_people_view_maps(self): """ Allows the saving people display data into the database metadata. diff --git a/gramps2/src/GrampsInMemDB.py b/gramps2/src/GrampsInMemDB.py index 76f1b4945..e9413f5aa 100644 --- a/gramps2/src/GrampsInMemDB.py +++ b/gramps2/src/GrampsInMemDB.py @@ -36,6 +36,7 @@ class GrampsInMemDB(GrampsDbBase): """creates a new GrampsDB""" GrampsDbBase.__init__(self) self.person_map = {} + self.name_group = {} self.family_map = {} self.place_map = {} self.source_map = {} @@ -57,6 +58,12 @@ class GrampsInMemDB(GrampsDbBase): def close(self): pass + def set_name_group_mapping(self,name,group): + if group == None and self.name_group.has_key(name): + del self.name_group[name] + else: + self.name_group[name] = group + def get_surname_list(self): a = {} for person_id in self.get_person_handles(sort_handles=False): diff --git a/gramps2/src/NameEdit.py b/gramps2/src/NameEdit.py index c183a7d86..968c48221 100644 --- a/gramps2/src/NameEdit.py +++ b/gramps2/src/NameEdit.py @@ -139,30 +139,38 @@ class NameEditor: self.flowed.set_active(1) self.display_as.set_active(name.get_display_as()) self.sort_as.set_active(name.get_display_as()) - self.group_as.set_text(name.get_group_as()) + grp_as = name.get_group_as() + if grp_as: + self.group_as.set_text(name.get_group_as()) + else: + self.group_as.set_text(name.get_surname()) else: self.display_as.set_active(0) self.sort_as.set_active(0) if parent_window: self.window.set_transient_for(parent_window) + self.surname_field.connect('changed',self.update_group_as) self.add_itself_to_menu() - self.surname_field.connect('changed',self.on_family_changed) self.window.show() + def update_group_as(self,obj): + if not self.group_over.get_active(): + if self.name.get_group_as() != self.name.get_surname(): + val = self.name.get_group_as() + else: + val = self.db.get_name_group_mapping(self.surname_field.get_text()) + self.group_as.set_text(val) + def on_group_over_toggled(self,obj): if obj.get_active(): self.group_as.set_sensitive(gtk.TRUE) self.group_as.set_editable(gtk.TRUE) else: - self.group_as.set_text(self.surname_field.get_text()) + self.group_as.set_text(self.db.get_name_group_mapping(self.surname_field.get_text())) self.group_as.set_sensitive(gtk.FALSE) self.group_as.set_editable(gtk.FALSE) - def on_family_changed(self,obj): - if self.group_over.get_active() == gtk.FALSE: - self.group_as.set_text(self.surname_field.get_text()) - def on_delete_event(self,*obj): self.close_child_windows() self.remove_itself_from_menu() @@ -232,6 +240,9 @@ class NameEditor: self.name.set_source_reference_list(self.srcreflist) + grp_as = self.group_as.get_text() + srn = self.surname_field.get_text() + if self.name.get_display_as() != self.display_as.get_active(): self.name.set_display_as(self.display_as.get_active()) self.parent.lists_changed = 1 @@ -241,13 +252,25 @@ class NameEditor: self.parent.lists_changed = 1 if self.group_over.get_active() == gtk.FALSE: - if self.name.get_group_as() != self.surname_field.get_text(): - self.name.set_group_as("") - self.parent.lists_changed = 1 - elif self.name.get_group_as() != self.group_as.get_text(): - self.name.set_group_as(self.group_as.get_text()) + self.name.set_group_as("") self.parent.lists_changed = 1 - + elif self.name.get_group_as() != grp_as: + if grp_as not in self.db.get_name_group_keys(): + from QuestionDialog import QuestionDialog2 + q = QuestionDialog2(_("Group all people with the same name?"), + _("You have the choice of grouping all people with the " + "name of %(surname)s with the name of %(group_name)s, or " + "just mapping this particular name.") % {'surname' : srn, 'group_name':grp_as}, + _("Group all"), + _("Group this name only")) + val = q.run() + if val: + self.name.set_group_as("") + self.db.set_name_group_mapping(srn,grp_as) + else: + self.name.set_group_as(grp_as) + self.parent.lists_changed = 1 + self.update_name(first,last,suffix,title,mtype,note,format,priv) self.parent.lists_changed = 1 diff --git a/gramps2/src/PeopleModel.py b/gramps2/src/PeopleModel.py index bea2fbb21..ae5a522d1 100644 --- a/gramps2/src/PeopleModel.py +++ b/gramps2/src/PeopleModel.py @@ -73,17 +73,17 @@ class PeopleModel(gtk.GenericTreeModel): self.visible = {} self.top_visible = {} - maps = self.db.get_people_view_maps() - if maps[0] != None and len(maps[0]) != 0: - self.top_path2iter = maps[0] - self.iter2path = maps[1] - self.path2iter = maps[2] - self.sname_sub = maps[3] - else: - self.rebuild_data() +# maps = self.db.get_people_view_maps() +# print +# if maps[0] != None and len(maps[0]) != 0: +# self.top_path2iter = maps[0] +# self.iter2path = maps[1] +# self.path2iter = maps[2] +# self.sname_sub = maps[3] +# else: + self.rebuild_data() def rebuild_data(self): - self.top_path2iter = [] self.iter2path = {} self.path2iter = {} @@ -97,25 +97,29 @@ class PeopleModel(gtk.GenericTreeModel): for person_handle in self.db.get_person_handles(sort_handles=False): person = self.db.get_person_from_handle(person_handle) - surname = unicode(person.get_primary_name().get_group_as()) + grp_as = person.get_primary_name().get_group_as() + sn = person.get_primary_name().get_surname() + if grp_as: + surname = grp_as + else: + surname = self.db.get_name_group_mapping(sn) if self.sname_sub.has_key(surname): self.sname_sub[surname].append(person_handle) else: self.sname_sub[surname] = [person_handle] - name_list = self.db.get_surname_list() - for name in name_list: - if self.sname_sub.has_key(name): - self.top_path2iter.append(name) - val = 0 - entries = self.sname_sub[name] - entries.sort(self.byname) - for person_handle in entries: - tpl = (name,val) - self.iter2path[person_handle] = tpl - self.path2iter[tpl] = person_handle - val += 1 + self.top_path2iter = self.sname_sub.keys() + self.top_path2iter.sort() + for name in self.top_path2iter: + val = 0 + entries = self.sname_sub[name] + entries.sort(self.byname) + for person_handle in entries: + tpl = (name,val) + self.iter2path[person_handle] = tpl + self.path2iter[tpl] = person_handle + val += 1 self.db.set_people_view_maps(self.get_maps()) def get_maps(self): @@ -141,14 +145,13 @@ class PeopleModel(gtk.GenericTreeModel): levels) for a particular node.''' try: return (self.top_path2iter.index(node),) - except ValueError: + except: (surname,index) = self.iter2path[node] return (self.top_path2iter.index(surname),index) def on_get_column_type(self,index): # return column data-type, from table - t = COLUMN_DEFS[index][COLUMN_DEF_TYPE] - return t + return COLUMN_DEFS[index][COLUMN_DEF_TYPE] def on_get_iter(self, path): try: @@ -213,8 +216,8 @@ class PeopleModel(gtk.GenericTreeModel): if node == None: return len(self.sname_sub) if self.sname_sub.has_key(node) and len(self.sname_sub[node]) > 0: - return gtk.TRUE - return gtk.FALSE + return True + return False def on_iter_n_children(self,node): if node == None: @@ -228,7 +231,6 @@ class PeopleModel(gtk.GenericTreeModel): if node == None: return self.top_path2iter[n] try: - path = self.top_path2iter.index(node) return self.path2iter[(node,n)] except: return None diff --git a/gramps2/src/PeopleView.py b/gramps2/src/PeopleView.py index 88333202a..0c2b3b359 100644 --- a/gramps2/src/PeopleView.py +++ b/gramps2/src/PeopleView.py @@ -192,7 +192,8 @@ class PeopleView: return p = self.parent.active_person path = self.person_model.on_get_path(p.get_handle()) - top_path = self.person_model.on_get_path(p.get_primary_name().get_surname()) + top_name = self.parent.db.get_name_group_mapping(p.get_primary_name().get_group_name()) + top_path = self.person_model.on_get_path(top_name) self.person_tree.expand_row(top_path,0) self.person_selection.select_path(path) self.person_tree.scroll_to_cell(path,None,1,0.5,0) @@ -201,6 +202,9 @@ class PeopleView: self.parent.load_person(self.parent.active_person) def apply_filter(self,current_model=None): + self.build_tree() + return + self.person_model.rebuild_data() self.parent.status_text(_('Updating display...')) keys = self.DataFilter.apply(self.parent.db, diff --git a/gramps2/src/QuestionDialog.py b/gramps2/src/QuestionDialog.py index 26ba46d30..ee9d847cc 100644 --- a/gramps2/src/QuestionDialog.py +++ b/gramps2/src/QuestionDialog.py @@ -73,6 +73,31 @@ class QuestionDialog: task() self.top.destroy() +class QuestionDialog2: + def __init__(self,msg1,msg2,label_msg1,label_msg2,parent=None): + self.xml = gtk.glade.XML(const.errdialogsFile,"questiondialog","gramps") + self.top = self.xml.get_widget('questiondialog') + self.top.set_title('') + + label1 = self.xml.get_widget('label1') + label1.set_text('%s' % msg1) + label1.set_use_markup(gtk.TRUE) + + label2 = self.xml.get_widget('label2') + label2.set_text(msg2) + label2.set_use_markup(gtk.TRUE) + + self.xml.get_widget('okbutton').set_label(label_msg1) + self.xml.get_widget('no').set_label(label_msg2) + self.top.show() + if parent: + self.top.set_transient_for(parent) + + def run(self): + response = self.top.run() + self.top.destroy() + return (response == gtk.RESPONSE_ACCEPT) + class OptionDialog: def __init__(self,msg1,msg2,btnmsg1,task1,btnmsg2,task2,parent=None): self.xml = gtk.glade.XML(const.errdialogsFile,"optiondialog","gramps") diff --git a/gramps2/src/RelLib.py b/gramps2/src/RelLib.py index 0858809a9..be9433239 100644 --- a/gramps2/src/RelLib.py +++ b/gramps2/src/RelLib.py @@ -62,7 +62,6 @@ CONF_NORMAL = 2 CONF_LOW = 1 CONF_VERY_LOW = 0 - #------------------------------------------------------------------------- # # Class definitions @@ -101,9 +100,16 @@ class PrimaryObject: self.change = 0 def get_change_time(self): + """ + Returns the time that the data was last changed. The value in the format + returned by the time.time() command. + """ return self.change def get_change_display(self): + """ + Returns a string representation of the last change time. + """ if self.change: return time.asctime(time.localtime(self.change)) else: @@ -1868,6 +1874,12 @@ class Name(DataObj): self.group_as = name def get_group_as(self): + """ + Returns the grouping name, which is used to group equivalent surnames. + """ + return self.group_as + + def get_group_name(self): """ Returns the grouping name, which is used to group equivalent surnames. """ diff --git a/gramps2/src/gramps.glade b/gramps2/src/gramps.glade index 912798957..cc059343d 100644 --- a/gramps2/src/gramps.glade +++ b/gramps2/src/gramps.glade @@ -7980,7 +7980,7 @@ Other True - 2 + 1 1 False 0 @@ -8673,27 +8673,6 @@ Other - - - True - True - True - True - 0 - - True - * - False - - - 2 - 5 - 2 - 3 - - - - True @@ -8956,50 +8935,6 @@ Other - - - True - The person's given name - True - True - True - True - 0 - - True - * - False - - - - 2 - 4 - 1 - 2 - - - - - - - True - True - Edit... - True - GTK_RELIEF_NORMAL - True - - - - 4 - 5 - 1 - 2 - fill - - - - True @@ -9021,6 +8956,71 @@ Other + + + + True + True + True + True + 0 + + True + * + False + + + 2 + 4 + 2 + 3 + + + + + + + True + True + Edit... + True + GTK_RELIEF_NORMAL + True + + + + 4 + 5 + 2 + 3 + fill + + + + + + + True + The person's given name + True + True + True + True + 0 + + True + * + False + + + + 2 + 5 + 1 + 2 + + + 0 @@ -25220,7 +25220,7 @@ Other GTK_BUTTONBOX_END - + True True True diff --git a/gramps2/src/gramps_main.py b/gramps2/src/gramps_main.py index af4e42201..5e35c5173 100755 --- a/gramps2/src/gramps_main.py +++ b/gramps2/src/gramps_main.py @@ -1458,16 +1458,11 @@ class Gramps: def update_after_edit(self,epo,change=1): if epo: - if change or self.db.get_number_of_people() <= 1: - self.people_view.redisplay_person_list(epo.person) - else: - iter = self.people_view.person_model.get_iter((0,)) - id = epo.person.get_handle() - path = self.people_view.person_model.on_get_path(id) - self.people_view.person_model.row_changed(path,iter) + self.people_view.redisplay_person_list(epo.person) self.family_view.load_family() self.update_display(0) - + self.goto_active_person() + def update_after_merge(self,person,old_id): if person: self.people_view.redisplay_person_list(person)