diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index 21937e38f..06ae24e87 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,20 @@ +2006-03-18 Don Allingham + * src/DataViews/_PersonView.py: use fixed width/height mode to + prevent unnecessary reads during initialization. Prevent double + loading of data from filter. + * src/GrampsDb/_GrampsDbBase.py: provide widths for person view columns + * src/RelLib/_Name.py: provide fast, shallow initialization of values + for quick access when only name functions are needed + * src/Editors/_EditFamily.py: Switch from ObjectSelector to SelectPerson + until the ObjectSelector cursor issues are resolved + * src/PeopleModel.py: Faster access to rebuilding data + * src/Utils.py: handle if locale.getpreferredencondings fails + * src/NameDisplay.py: speed up name display by using string join + * src/GenericFilter.py: provide match function as a temporary fix until + filters are redesigned + * src/SelectPerson.py: used fixed width/height mode + * src/PageView.py: suppress tooltips if requested + 2006-03-17 Don Allingham * src/Editors/_EditFamily.py: convert father to use SelectPerson instead of ObjectSelector diff --git a/gramps2/src/DataViews/_PersonView.py b/gramps2/src/DataViews/_PersonView.py index 0309f52fd..4c7d13ea7 100644 --- a/gramps2/src/DataViews/_PersonView.py +++ b/gramps2/src/DataViews/_PersonView.py @@ -148,6 +148,7 @@ class PersonView(PageView.PersonNavView): self.tree = gtk.TreeView() self.tree.set_rules_hint(True) self.tree.set_headers_visible(True) + self.tree.set_fixed_height_mode(True) self.tree.connect('key-press-event',self.key_press) scrollwindow = gtk.ScrolledWindow() @@ -247,7 +248,7 @@ class PersonView(PageView.PersonNavView): db.connect('person-update', self.person_updated) db.connect('person-delete', self.person_removed) db.connect('person-rebuild', self.build_tree) - self.build_tree() +# self.build_tree() self.generic_filter_widget.apply_filter() def goto_active_person(self,obj=None): @@ -349,7 +350,8 @@ class PersonView(PageView.PersonNavView): self.tree.set_model(self.model) if self.model.tooltip_column != None: - self.tooltips = TreeTips.TreeTips(self.tree,self.model.tooltip_column,True) + self.tooltips = TreeTips.TreeTips(self.tree, self.model.tooltip_column, + True) self.build_columns() self.dirty = False else: @@ -453,8 +455,8 @@ class PersonView(PageView.PersonNavView): column.set_resizable(True) #column.set_clickable(True) #column.connect('clicked',self.sort_clicked) - column.set_min_width(225) column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + column.set_fixed_width(225) self.tree.append_column(column) self.columns = [column] @@ -468,8 +470,8 @@ class PersonView(PageView.PersonNavView): except AttributeError: column = gtk.TreeViewColumn(name, self.renderer, markup=pair[1]) column.set_resizable(True) - column.set_min_width(60) - column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) + column.set_fixed_width(pair[2]) + column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) self.columns.append(column) self.tree.append_column(column) diff --git a/gramps2/src/Editors/_EditFamily.py b/gramps2/src/Editors/_EditFamily.py index 51827a976..317144169 100644 --- a/gramps2/src/Editors/_EditFamily.py +++ b/gramps2/src/Editors/_EditFamily.py @@ -236,6 +236,24 @@ class ChildEmbedList(EmbeddedList): except Errors.WindowActiveError: pass +class FastMaleFilter: + + def __init__(self,db): + self.db = db + + def match(self, handle): + value = self.db.get_raw_person_data(handle) + return value[2] == RelLib.Person.MALE + +class FastFemaleFilter: + + def __init__(self,db): + self.db = db + + def match(self, handle): + value = self.db.get_raw_person_data(handle) + return value[2] == RelLib.Person.FEMALE + #------------------------------------------------------------------------- # # EditFamily @@ -403,33 +421,50 @@ class EditFamily(EditPrimary): selector_window.close() - def mother_clicked(self,obj): + def mother_clicked(self, obj): handle = self.obj.get_mother_handle() if handle: self.obj.set_mother_handle(None) self.update_mother(None) else: - filter_spec = PersonFilterSpec() - filter_spec.set_gender(RelLib.Person.FEMALE) + from SelectPerson import SelectPerson + + data_filter = FastFemaleFilter(self.dbstate.db) + sel = SelectPerson(self.dbstate.db, "Select Mother", + filter=data_filter, + skip=self.obj.get_child_handle_list()) + person = sel.run() + + if person: + self.obj.set_mother_handle(person.handle) + self.update_mother(person.handle) + +# def mother_clicked(self,obj): +# handle = self.obj.get_mother_handle() +# if handle: +# self.obj.set_mother_handle(None) +# self.update_mother(None) +# else: +# filter_spec = PersonFilterSpec() +# filter_spec.set_gender(RelLib.Person.FEMALE) - child_birth_years = [] - for person_handle in self.obj.get_child_handle_list(): - person = self.db.get_person_from_handle(person_handle) - event_ref = person.get_birth_ref() - if event_ref and event_ref.ref: - event = self.db.get_event_from_handle(event_ref.ref) - child_birth_years.append(event.get_date_object().get_year()) +# child_birth_years = [] +# for person_handle in self.obj.get_child_handle_list(): +# person = self.db.get_person_from_handle(person_handle) +# event_ref = person.get_birth_ref() +# if event_ref and event_ref.ref: +# event = self.db.get_event_from_handle(event_ref.ref) +# child_birth_years.append(event.get_date_object().get_year()) - if len(child_birth_years) > 0: - filter_spec.set_birth_year(min(child_birth_years)) - filter_spec.set_birth_criteria(PersonFilterSpec.BEFORE) +# if len(child_birth_years) > 0: +# filter_spec.set_birth_year(min(child_birth_years)) +# filter_spec.set_birth_criteria(PersonFilterSpec.BEFORE) - selector = PersonSelector(self.dbstate,self.uistate, - self.track,filter_spec=filter_spec) - selector.connect('add-object',self.on_change_mother) +# selector = PersonSelector(self.dbstate,self.uistate, +# self.track,filter_spec=filter_spec) +# selector.connect('add-object',self.on_change_mother) - def on_change_father(self, selector_window, obj): if obj.__class__ == RelLib.Person: try: @@ -457,11 +492,8 @@ class EditFamily(EditPrimary): self.update_father(None) else: from SelectPerson import SelectPerson - import GenericFilter - data_filter = GenericFilter.GenericFilter() - data_filter.add_rule(GenericFilter.IsMale([])) - + data_filter = FastMaleFilter(self.dbstate.db) sel = SelectPerson(self.dbstate.db, "Select Father", filter=data_filter, skip=self.obj.get_child_handle_list()) diff --git a/gramps2/src/GenericFilter.py b/gramps2/src/GenericFilter.py index ccc1e160a..b6194501b 100644 --- a/gramps2/src/GenericFilter.py +++ b/gramps2/src/GenericFilter.py @@ -1913,6 +1913,9 @@ class GenericFilter: self.logical_op = 'and' self.invert = False + def match(self,handle): + return True + def is_empty(self): return len(self.flist) == 1 and self.flist[0].is_empty() diff --git a/gramps2/src/GrampsDb/_GrampsDbBase.py b/gramps2/src/GrampsDb/_GrampsDbBase.py index 96ad8726d..71343ee27 100644 --- a/gramps2/src/GrampsDb/_GrampsDbBase.py +++ b/gramps2/src/GrampsDb/_GrampsDbBase.py @@ -1708,7 +1708,8 @@ class GrampsDbBase(GrampsDBCallback): Returns the Person display common information stored in the database's metadata. """ - default = [(1,1),(1,2),(1,3),(0,4),(1,5),(0,6),(0,7),(0,8),(0,9,)] + default = [(1,1,100),(1,2,100),(1,3,150),(0,4,150),(1,5,150), + (0,6,150),(0,7,100),(0,8,100),(0,9,100)] return self._get_column_order(PERSON_COL_KEY,default) def _get_columns(self,key,default): diff --git a/gramps2/src/NameDisplay.py b/gramps2/src/NameDisplay.py index 2f50f615c..02b5a1882 100644 --- a/gramps2/src/NameDisplay.py +++ b/gramps2/src/NameDisplay.py @@ -102,16 +102,16 @@ class NameDisplay: else: last = name.patronymic - if name.suffix == "": - if name.prefix: - return "%s %s, %s" % (name.prefix, last, first) - else: - return "%s, %s" % (last, first) - else: + if name.suffix: if name.prefix: return "%s %s %s, %s" % (name.prefix, last, name.suffix, first) else: return "%s %s, %s" % (last, name.suffix, first) + else: + if name.prefix: + return "%s %s, %s" % (name.prefix, last, first) + else: + return "%s, %s" % (last, first) def _fnln(self,name,nickname=""): """ @@ -120,12 +120,8 @@ class NameDisplay: FirstName Patronymic SurnamePrefix Surname SurnameSuffix """ - first = name.first_name - if nickname: - first = '%s "%s"' % (first,nickname) - if name.patronymic: first = "%s %s" % (first, name.patronymic) @@ -134,16 +130,16 @@ class NameDisplay: else: last = name.surname - if name.suffix == "": - if name.prefix: - return "%s %s %s" % (first, name.prefix, last) - else: - return "%s %s" % (first, last) - else: + if name.suffix: if name.prefix: return "%s %s %s, %s" % (first, name.prefix, last, name.suffix) else: return "%s %s, %s" % (first, last, name.suffix) + else: + if name.prefix: + return "%s %s %s" % (first, name.prefix, last) + else: + return "%s %s" % (first, last) def _lnfn(self,name,nickname=u""): """ @@ -152,12 +148,6 @@ class NameDisplay: SurnamePrefix Surname, FirstName Patronymic SurnameSuffix """ - - first = name.first_name - - if name.patronymic: - first = "%s %s" % (first, name.patronymic) - if self.force_upper: last = name.surname.upper() else: @@ -166,20 +156,13 @@ class NameDisplay: if last: last += "," - if name.suffix: - if name.prefix: - return "%s %s %s %s" % (name.prefix, last, first, name.suffix) - else: - return "%s %s %s" % (last, first, name.suffix) - else: - if name.prefix: - return "%s %s %s" % (name.prefix, last, first) - else: - return "%s %s" % (last, first) - + return " ".join([x for x in [name.prefix, last, name.first_name, + name.patronymic, name.suffix]]) + fn_array = { Name.FNLN : _fnln, Name.PTFN : _ptfn, Name.FN : _empty, + Name.LNFN : _lnfn, } def sorted_name(self,name): diff --git a/gramps2/src/PageView.py b/gramps2/src/PageView.py index 0e671dedf..4b8c32a5d 100644 --- a/gramps2/src/PageView.py +++ b/gramps2/src/PageView.py @@ -42,6 +42,7 @@ import pango #---------------------------------------------------------------- import TreeTips import GenericFilter +import const NAVIGATION_NONE = -1 NAVIGATION_PERSON = 0 @@ -454,7 +455,7 @@ class ListView(PageView): self.list.set_model(self.model) self.selection = self.list.get_selection() - if self.model.tooltip_column != None: + if const.use_tips and self.model.tooltip_column != None: self.tooltips = TreeTips.TreeTips(self.list, self.model.tooltip_column,True) self.dirty = False diff --git a/gramps2/src/PeopleModel.py b/gramps2/src/PeopleModel.py index 7460ea4ba..b05c5c376 100644 --- a/gramps2/src/PeopleModel.py +++ b/gramps2/src/PeopleModel.py @@ -32,6 +32,8 @@ import sys import traceback import locale +import cPickle as pickle + try: set() except: @@ -131,9 +133,9 @@ class PeopleModel(gtk.GenericTreeModel): self.calculate_data(data_filter,skip) self.assign_data() - def calculate_data(self,data_filter=None,skip=[]): - if data_filter: - self.data_filter = data_filter + def calculate_data(self,dfilter=None,skip=[]): + if dfilter: + self.dfilter = dfilter self.temp_top_path2iter = [] self.temp_iter2path = {} self.temp_path2iter = {} @@ -142,37 +144,42 @@ class PeopleModel(gtk.GenericTreeModel): if not self.db.is_open(): return - if data_filter and not data_filter.is_empty(): - keys = data_filter.apply(self.db) - if self.invert_result: - handle_list = self.db.get_person_handles(sort_handles=False) - #TODO: Could be optimized by using a cursor - keys = [k for k in handle_list if k not in keys] - del handle_list - else: - keys = self.db.get_person_handles(sort_handles=False) - - self.sortnames = {} - cursor = self.db.get_person_cursor() - node = cursor.next() - ngn = NameDisplay.displayer.name_grouping_name nsn = NameDisplay.displayer.sorted_name - flist = set([key for key in keys if key not in skip]) + flist = set(skip) + self.sortnames = {} + + cursor = self.db.surnames.cursor() + node = cursor.first() while node: n,d = node - if n in flist: - primary_name = Name() - primary_name.unserialize(d[_NAME_COL]) - surname = ngn(self.db,primary_name) - self.sortnames[n] = nsn(primary_name) - try: - self.temp_sname_sub[surname].append(n) - except: - self.temp_sname_sub[surname] = [n] - node = cursor.next() + d = pickle.loads(d) + handle = d[0] + primary_name = Name(data=d[_NAME_COL]) + #surname = ngn(self.db,primary_name) + surname = n + + if not (handle in skip or (dfilter and not dfilter.match(handle))): + self.sortnames[handle] = nsn(primary_name) + self.temp_sname_sub[surname] = [handle] + + node = cursor.next_dup() + while node: + n,d = node + d = pickle.loads(d) + handle = d[0] + primary_name = Name(data=d[_NAME_COL]) + if not (handle in skip or (dfilter and not dfilter.match(handle))): + self.sortnames[handle] = nsn(primary_name) + try: + self.temp_sname_sub[surname].append(handle) + except: + self.temp_sname_sub[surname] = [handle] + node = cursor.next_dup() + + node = cursor.next_nodup() cursor.close() self.temp_top_path2iter = locale_sort(self.temp_sname_sub.keys()) @@ -184,9 +191,10 @@ class PeopleModel(gtk.GenericTreeModel): def build_sub_entry(self,name): self.prev_handle = None - slist = map(lambda x: (self.sortnames[x],x),self.temp_sname_sub[name]) - slist.sort(lambda f,s: locale.strcoll(f[0],s[0])) - entries = map(lambda x: x[1], slist) + slist = [ (locale.strxfrm(self.sortnames[x]),x) \ + for x in self.temp_sname_sub[name] ] + slist.sort() + entries = [ x[1] for x in slist ] val = 0 for person_handle in entries: @@ -513,12 +521,12 @@ COLUMN_DEFS = [ # these columns are hidden, and must always be last in the list (PeopleModel.column_tooltip, None, object), - (PeopleModel.column_sort_name, None, str), +# (PeopleModel.column_sort_name, None, str), (PeopleModel.column_int_id, None, str), ] # dynamic calculation of column indices, for use by various Views -COLUMN_INT_ID = 14 +COLUMN_INT_ID = 13 # indices into main column definition table COLUMN_DEF_LIST = 0 diff --git a/gramps2/src/RelLib/_Name.py b/gramps2/src/RelLib/_Name.py index f73b3b48f..85be808a2 100644 --- a/gramps2/src/RelLib/_Name.py +++ b/gramps2/src/RelLib/_Name.py @@ -63,12 +63,16 @@ class Name(PrivateSourceNote,DateBase): BIRTH = 2 MARRIED = 3 - def __init__(self,source=None): + def __init__(self,source=None,data=None): """creates a new Name instance, copying from the source if provided""" - PrivateSourceNote.__init__(self,source) - DateBase.__init__(self,source) - - if source: + if data: + (psn,date, + self.first_name,self.surname,self.suffix,self.title, + self.type,self.prefix,self.patronymic,self.sname, + self.group_as,self.sort_as,self.display_as) = data + elif source: + PrivateSourceNote.__init__(self,source) + DateBase.__init__(self,source) self.first_name = source.first_name self.surname = source.surname self.suffix = source.suffix @@ -81,6 +85,8 @@ class Name(PrivateSourceNote,DateBase): self.sort_as = source.sort_as self.display_as = source.display_as else: + PrivateSourceNote.__init__(self,source) + DateBase.__init__(self,source) self.first_name = "" self.surname = "" self.suffix = "" diff --git a/gramps2/src/SelectPerson.py b/gramps2/src/SelectPerson.py index 73515b3bf..d8b7efef2 100644 --- a/gramps2/src/SelectPerson.py +++ b/gramps2/src/SelectPerson.py @@ -76,20 +76,27 @@ class SelectPerson: self.top.set_transient_for(parent_window) def add_columns(self,tree): - column = gtk.TreeViewColumn(_('Name'), self.renderer,text=0) + tree.set_fixed_height_mode(True) + column = gtk.TreeViewColumn(_('Name'), self.renderer, text=0) column.set_resizable(True) column.set_clickable(True) column.set_sort_column_id(0) - column.set_min_width(225) + column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + column.set_fixed_width(225) tree.append_column(column) - column = gtk.TreeViewColumn(_('ID'), self.renderer,text=1) + + column = gtk.TreeViewColumn(_('ID'), self.renderer, text=1) column.set_resizable(True) column.set_clickable(True) column.set_sort_column_id(1) - column.set_min_width(75) + column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + column.set_fixed_width(75) tree.append_column(column) - column = gtk.TreeViewColumn(_('Birth date'), self.renderer,text=3) + + column = gtk.TreeViewColumn(_('Birth date'), self.renderer, text=3) column.set_clickable(True) + column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + column.set_fixed_width(160) tree.append_column(column) def select_function(self,store,path,iter,id_list): diff --git a/gramps2/src/Utils.py b/gramps2/src/Utils.py index 9367959f8..61ce1bbe0 100644 --- a/gramps2/src/Utils.py +++ b/gramps2/src/Utils.py @@ -31,6 +31,11 @@ import locale import sets from TransUtils import sgettext as _ +try: + set() +except: + from sets import Set as set + #------------------------------------------------------------------------- # # GNOME/GTK @@ -525,7 +530,7 @@ def find_file( filename): # Build list of elternate encodings encodings = [sys.getfilesystemencoding(), locale.getpreferredencoding(), 'UTF-8', 'ISO-8859-1'] - encodings = list(sets.Set(encodings)) + encodings = list(set(encodings)) for enc in encodings: try: fname = filename.encode(enc) @@ -547,8 +552,12 @@ def find_folder( filename): pass # Build list of elternate encodings - encodings = [sys.getfilesystemencoding(), locale.getpreferredencoding(), 'UTF-8', 'ISO-8859-1'] - encodings = list(sets.Set(encodings)) + try: + encodings = [sys.getfilesystemencoding(), locale.getpreferredencoding(), + 'UTF-8', 'ISO-8859-1'] + except: + encodings = [sys.getfilesystemencoding(), 'UTF-8', 'ISO-8859-1'] + encodings = list(set(encodings)) for enc in encodings: try: fname = filename.encode(enc)