speed improvements until object selector is functional

svn: r6175
This commit is contained in:
Don Allingham 2006-03-19 03:25:31 +00:00
parent 06928f21af
commit 32bfafecc9
11 changed files with 176 additions and 107 deletions

View File

@ -1,3 +1,20 @@
2006-03-18 Don Allingham <don@gramps-project.org>
* 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 <don@gramps-project.org>
* src/Editors/_EditFamily.py: convert father to use SelectPerson instead
of ObjectSelector

View File

@ -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)

View File

@ -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,32 +421,49 @@ 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
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())
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 len(child_birth_years) > 0:
filter_spec.set_birth_year(min(child_birth_years))
filter_spec.set_birth_criteria(PersonFilterSpec.BEFORE)
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())
# 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:
@ -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())

View File

@ -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()

View File

@ -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):

View File

@ -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):

View File

@ -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

View File

@ -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)
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(n)
self.temp_sname_sub[surname].append(handle)
except:
self.temp_sname_sub[surname] = [n]
node = cursor.next()
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

View File

@ -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"""
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)
if 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 = ""

View File

@ -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):

View File

@ -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)