diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index e7940c3e1..803f9cbf7 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,10 @@ +2005-06-01 Don Allingham + * src/PeopleModel.py: Improve rebuid times by using database cursor, + caching sort names, and replacing loops with map/lamba + * src/PeopleView.py: prevent goto_active_person reentrancy, use get_selected_objects + instead of selected_foreach, combine row_changed and set_dnd_target into the same + callback, rebuild only affected surname on person-update if pissible + 2005-06-01 Alex Roitman * src/plugins/Makefile.am: Don't ship NavWebPage yet. * src/po/template.po: Update for 2.0.2. diff --git a/gramps2/src/EditPerson.py b/gramps2/src/EditPerson.py index c31a39a33..d65e112ec 100644 --- a/gramps2/src/EditPerson.py +++ b/gramps2/src/EditPerson.py @@ -620,7 +620,7 @@ class EditPerson: self.close_child_windows() self.remove_itself_from_winsmenu() self.window.destroy() - + def add_itself_to_winsmenu(self): self.parent.child_windows[self.orig_handle] = self win_menu_label = self.name_display.display(self.person) diff --git a/gramps2/src/PeopleModel.py b/gramps2/src/PeopleModel.py index 5f046c4ce..4560b58b9 100644 --- a/gramps2/src/PeopleModel.py +++ b/gramps2/src/PeopleModel.py @@ -29,6 +29,7 @@ from gettext import gettext as _ import time import locale import cgi +import sets #------------------------------------------------------------------------- # @@ -84,6 +85,7 @@ class PeopleModel(gtk.GenericTreeModel): self.visible = {} self.top_visible = {} self.invert_result = invert_result + self.sortnames = {} self.rebuild_data(data_filter) def rebuild_data(self,data_filter=None,skip=None): @@ -111,38 +113,44 @@ class PeopleModel(gtk.GenericTreeModel): else: keys = self.db.get_person_handles(sort_handles=False) - for person_handle in keys: - if person_handle == skip: - continue - person = self.db.get_person_from_handle(person_handle) - 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) + flist = sets.Set(keys) + if skip and skip in flist: + flist.remove(skip) - if self.temp_sname_sub.has_key(surname): - self.temp_sname_sub[surname].append(person_handle) - else: - self.temp_sname_sub[surname] = [person_handle] + self.sortnames = {} + cursor = self.db.get_person_cursor() + node = cursor.next() + while node: + if node[0] in flist: + primary_name = node[1][_NAME_COL] + if primary_name.group_as: + surname = primary_name.group_as + else: + surname = self.db.get_name_group_mapping(primary_name.surname) + self.sortnames[node[0]] = primary_name.sname + + if self.temp_sname_sub.has_key(surname): + self.temp_sname_sub[surname].append(node[0]) + else: + self.temp_sname_sub[surname] = [node[0]] + node = cursor.next() + cursor.close() self.temp_top_path2iter = self.temp_sname_sub.keys() self.temp_top_path2iter.sort(locale.strcoll) for name in self.temp_top_path2iter: + self.build_sub_entry(name) - slist = [] - for handle in self.temp_sname_sub[name]: - n = self.db.person_map.get(handle)[_NAME_COL].get_sort_name() - slist.append((n,handle)) - slist.sort(self.byname) - entries = map(lambda x: x[1], slist) - val = 0 - for person_handle in entries: - tpl = (name,val) - self.temp_iter2path[person_handle] = tpl - self.temp_path2iter[tpl] = person_handle - val += 1 + def build_sub_entry(self,name): + slist = map(lambda x: (self.sortnames[x],x),self.temp_sname_sub[name]) + slist.sort(self.byname) + entries = map(lambda x: x[1], slist) + val = 0 + for person_handle in entries: + tpl = (name,val) + self.temp_iter2path[person_handle] = tpl + self.temp_path2iter[tpl] = person_handle + val += 1 def assign_data(self): self.top_path2iter = self.temp_top_path2iter diff --git a/gramps2/src/PeopleView.py b/gramps2/src/PeopleView.py index 37d375604..16d4a9b97 100644 --- a/gramps2/src/PeopleView.py +++ b/gramps2/src/PeopleView.py @@ -88,13 +88,13 @@ class PeopleView: self.person_tree = self.parent.gtop.get_widget("person_tree") self.person_tree.set_rules_hint(True) self.renderer = gtk.CellRendererText() + self.inactive = False self.columns = [] self.build_columns() self.person_selection = self.person_tree.get_selection() self.person_selection.set_mode(gtk.SELECTION_MULTIPLE) self.person_selection.connect('changed',self.row_changed) - self.person_selection.connect('changed',self.set_dnd_target) self.person_tree.connect('row_activated', self.alpha_event) self.person_tree.connect('button-press-event', self.on_plist_button_press) @@ -113,20 +113,6 @@ class PeopleView: sel_data.set(DdTargets.PERSON_LINK_LIST.drag_type,8, pickle.dumps(selected_ids)) - def set_dnd_target(self,obj): - selected_ids = self.get_selected_objects() - - if len(selected_ids) == 1: - self.person_tree.drag_source_set(BUTTON1_MASK, - [DdTargets.PERSON_LINK.target()], - ACTION_COPY) - elif len(selected_ids) > 1: - self.person_tree.drag_source_set(BUTTON1_MASK, - [DdTargets.PERSON_LINK_LIST.target()], - ACTION_COPY) - - - def sort_clicked(self,obj): for col in self.columns: if obj == col: @@ -173,13 +159,12 @@ class PeopleView: self.parent.filter_invert.get_active()) self.person_tree.set_model(self.person_model) - def blist(self, store, path, node, id_list): - idval = self.person_model.get_value(node, PeopleModel.COLUMN_INT_ID) - id_list.append(idval) - def get_selected_objects(self): + (mode,paths) = self.person_selection.get_selected_rows() mlist = [] - self.person_selection.selected_foreach(self.blist,mlist) + for path in paths: + node = self.person_model.on_get_iter(path) + mlist.append(self.person_model.on_get_value(node, PeopleModel.COLUMN_INT_ID)) return mlist def row_changed(self,obj): @@ -189,24 +174,29 @@ class PeopleView: selected, set the active person to None""" selected_ids = self.get_selected_objects() - try: person = self.parent.db.get_person_from_handle(selected_ids[0]) self.parent.change_active_person(person) except: self.parent.change_active_person(None) + if len(selected_ids) == 1: + self.person_tree.drag_source_set(BUTTON1_MASK, + [DdTargets.PERSON_LINK.target()], + ACTION_COPY) + elif len(selected_ids) > 1: + self.person_tree.drag_source_set(BUTTON1_MASK, + [DdTargets.PERSON_LINK_LIST.target()], + ACTION_COPY) + def change_db(self,db): self.build_columns() - self.person_model = PeopleModel.PeopleModel(db,self.DataFilter) - self.person_tree.set_model(self.person_model) - db.connect('person-add', self.person_added) db.connect('person-update', self.person_updated) db.connect('person-delete', self.person_removed) db.connect('person-rebuild', self.redisplay_person_list) self.apply_filter() - + def remove_from_person_list(self,person): """Remove the selected person from the list. A person object is expected, not an ID""" @@ -239,8 +229,9 @@ class PeopleView: self.goto_active_person() def goto_active_person(self): - if not self.parent.active_person: + if not self.parent.active_person or self.inactive: return + self.inactive = True p = self.parent.active_person try: path = self.person_model.on_get_path(p.get_handle()) @@ -250,6 +241,7 @@ class PeopleView: self.person_tree.expand_row(top_path,0) current = self.person_model.on_get_iter(path) + selected = self.person_selection.path_is_selected(path) if current != p.get_handle() or not selected: self.person_selection.unselect_all() @@ -259,6 +251,7 @@ class PeopleView: self.person_selection.unselect_all() print "Person not currently available due to filter" self.parent.active_person = p + self.inactive = False def alpha_event(self,*obj): self.parent.load_person(self.parent.active_person) @@ -280,9 +273,9 @@ class PeopleView: fwd_sensitivity = self.parent.hindex + 1 < len(self.parent.history) mlist = self.get_selected_objects() if mlist: - sel_sensitivity = 1 + sel_sensitivity = True else: - sel_sensitivity = 0 + sel_sensitivity = False merge_sensitivity = len(mlist) == 2 entries = [ (gtk.STOCK_GO_BACK,self.parent.back_clicked,back_sensitivity), @@ -365,7 +358,17 @@ class PeopleView: pnode = self.person_model.get_iter(pathval) # calculate the new data - self.person_model.calculate_data(self.DataFilter) + + if person.primary_name.group_as: + surname = person.primary_name.group_as + else: + surname = self.parent.db.get_name_group_mapping(person.primary_name.surname) + + + if oldpath[0] == surname: + self.person_model.build_sub_entry(surname) + else: + self.person_model.calculate_data(self.DataFilter) # find the path of the person in the new data build newpath = self.person_model.temp_iter2path[node] @@ -404,5 +407,4 @@ class PeopleView: pnode = self.person_model.get_iter(path) self.person_model.row_inserted(path,pnode) - #self.parent.change_active_person(person) self.goto_active_person() diff --git a/gramps2/src/gramps_main.py b/gramps2/src/gramps_main.py index 8ca3d0665..4d735ca37 100755 --- a/gramps2/src/gramps_main.py +++ b/gramps2/src/gramps_main.py @@ -1749,9 +1749,9 @@ class Gramps(GrampsDBCallback.GrampsDBCallback): "Please upgrade to the corresponding version or use XML for porting data between different database versions.") self.db.set_save_path(name) + res = self.db.get_researcher() owner = GrampsCfg.get_researcher() - if res.get_name() == "" and owner.get_name(): self.db.set_researcher(owner)