speed improvements until object selector is functional
svn: r6175
This commit is contained in:
parent
06928f21af
commit
32bfafecc9
17
ChangeLog
17
ChangeLog
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 = ""
|
||||
|
@ -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):
|
||||
|
15
src/Utils.py
15
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)
|
||||
|
Loading…
Reference in New Issue
Block a user