* src/DisplayModels.py: use a dictionary to handle reverse

indices instead of list.index function. Drastically reduces
time are larger lists.
* src/GrampsDbBase.py: use cursors to build sorted key lists
* src/PeopleModel.py: fetch sort names out of database first
instead of continuously fetching from database during sort
* src/PeopleView.py: remove unnecessary apply_filter
* src/PlaceView.py: remove commented-out code
* src/ReadXML.py: add gtk event handling to allow screen to
update
* src/gramps.glade: use gramps.png for loading message window
* src/gramps_main.py: remove delete_abandoned_photos calls

* src/PeopleModel.py: Fixed rebuild_display
* src/ReadXML.py: Fixed calendar handling


svn: r3819
This commit is contained in:
Don Allingham 2004-12-19 22:55:41 +00:00
parent 6dea6f401e
commit 295e9a530f
11 changed files with 168 additions and 120 deletions

View File

@ -1,3 +1,21 @@
2004-12-19 Don Allingham <dallingham@users.sourceforge.net>
* src/DisplayModels.py: use a dictionary to handle reverse
indices instead of list.index function. Drastically reduces
time are larger lists.
* src/GrampsDbBase.py: use cursors to build sorted key lists
* src/PeopleModel.py: fetch sort names out of database first
instead of continuously fetching from database during sort
* src/PeopleView.py: remove unnecessary apply_filter
* src/PlaceView.py: remove commented-out code
* src/ReadXML.py: add gtk event handling to allow screen to
update
* src/gramps.glade: use gramps.png for loading message window
* src/gramps_main.py: remove delete_abandoned_photos calls
2004-12-16 Don Allingham <dallingham@users.sourceforge.net>
* src/PeopleModel.py: Fixed rebuild_display
* src/ReadXML.py: Fixed calendar handling
2004-12-16 Julio Sanchez <julio.sanchez@gmail.com> 2004-12-16 Julio Sanchez <julio.sanchez@gmail.com>
* src/po/es.po: forward port of the Spanish translations in STABLE, * src/po/es.po: forward port of the Spanish translations in STABLE,
plus many new translations plus many new translations

5
TODO
View File

@ -10,10 +10,6 @@
see http://sourceforge.net/mailarchive/forum.php?thread_id=3066997&forum_id=1993 see http://sourceforge.net/mailarchive/forum.php?thread_id=3066997&forum_id=1993
and http://sourceforge.net/mailarchive/forum.php?thread_id=3134931&forum_id=1993 and http://sourceforge.net/mailarchive/forum.php?thread_id=3134931&forum_id=1993
for the details. for the details.
* Make Date parsing locale dependent, like relationship calculator
* Add Confession as a standard event
* Now that the completeness flag exists, create filters that are using it
(both individual and family).
* Add autofill feature for City, Church parish, County, State and Country? * Add autofill feature for City, Church parish, County, State and Country?
* Move LDS temple info out of const.py and into an XML file * Move LDS temple info out of const.py and into an XML file
* Enhanced web page generator * Enhanced web page generator
@ -23,5 +19,4 @@
3 entries per page. 3 entries per page.
* Add slideshow generation ability to web page generator * Add slideshow generation ability to web page generator
* Enhance privacy handling * Enhance privacy handling
* Better name handling, especially of non-European style names
* And a whole lot more.... * And a whole lot more....

View File

@ -51,25 +51,37 @@ class BaseModel(gtk.GenericTreeModel):
def rebuild_data(self): def rebuild_data(self):
if self.db.is_open(): if self.db.is_open():
self.datalist = self.sort_keys() self.datalist = self.sort_keys()
i = 0
self.indexlist = {}
for key in self.datalist:
self.indexlist[key] = i
i += 1
else: else:
self.datalist = [] self.datalist = []
self.indexlist = []
def on_row_inserted(self,obj,path,node): def on_row_inserted(self,obj,path,node):
self.rebuild_data() self.rebuild_data()
def add_row_by_handle(self,handle): def add_row_by_handle(self,handle):
self.datalist = self.sort_keys() self.datalist = self.sort_keys()
index = self.datalist.index(handle) i = 0
self.indexlist = {}
for key in self.datalist:
self.indexlist[key] = i
i += 1
index = self.indexlist[handle]
node = self.get_iter(index) node = self.get_iter(index)
self.row_inserted(index,node) self.row_inserted(index,node)
def delete_row_by_handle(self,handle): def delete_row_by_handle(self,handle):
index = self.datalist.index(handle) index = self.indexlist[handle]
del self.datalist[index] del self.datalist[index]
del self.indexlist[handle]
self.row_deleted(index) self.row_deleted(index)
def update_row_by_handle(self,handle): def update_row_by_handle(self,handle):
index = self.datalist.index(handle) index = self.indexlist[handle]
node = self.get_iter(index) node = self.get_iter(index)
self.row_changed(index,node) self.row_changed(index,node)
@ -83,7 +95,7 @@ class BaseModel(gtk.GenericTreeModel):
def on_get_path(self, node): def on_get_path(self, node):
'''returns the tree path (a tuple of indices at the various '''returns the tree path (a tuple of indices at the various
levels) for a particular node.''' levels) for a particular node.'''
return self.datalist.index(node[0]) return self.indexlist[node[0]]
def on_get_column_type(self,index): def on_get_column_type(self,index):
return gobject.TYPE_STRING return gobject.TYPE_STRING
@ -103,7 +115,7 @@ class BaseModel(gtk.GenericTreeModel):
def on_iter_next(self, node): def on_iter_next(self, node):
'''returns the next node at this level of the tree''' '''returns the next node at this level of the tree'''
try: try:
return self.datalist[self.datalist.index(node)+1] return self.datalist[self.indexlist[node]+1]
except IndexError: except IndexError:
return None return None

View File

@ -676,10 +676,18 @@ class GrampsDbBase:
the database. If sort_handles is True, the list is sorted by surnames the database. If sort_handles is True, the list is sorted by surnames
""" """
if self.person_map: if self.person_map:
handle_list = self.person_map.keys()
if sort_handles: if sort_handles:
handle_list.sort(self._sortbyname) slist = []
return handle_list cursor = self.get_person_cursor()
data = cursor.first()
while data:
slist.append((data[1][3].sname,data[0]))
data = cursor.next()
cursor.close()
slist.sort()
return map(lambda x: x[1], slist)
else:
return self.person_map.keys()
return [] return []
def get_place_handles(self,sort_handles=True): def get_place_handles(self,sort_handles=True):
@ -689,10 +697,19 @@ class GrampsDbBase:
Place title. Place title.
""" """
if self.place_map: if self.place_map:
handle_list = self.place_map.keys()
if sort_handles: if sort_handles:
handle_list.sort(self._sortbyplace) slist = []
return handle_list cursor = self.get_place_cursor()
data = cursor.first()
while data:
slist.append((data[1][2],data[0]))
data = cursor.next()
cursor.close()
slist.sort()
val = map(lambda x: x[1], slist)
return val
else:
return self.place_map.keys()
return [] return []
def get_source_handles(self,sort_handles=True): def get_source_handles(self,sort_handles=True):

View File

@ -86,7 +86,9 @@ class PeopleModel(gtk.GenericTreeModel):
return return
if data_filter: if data_filter:
keys = self.data_filter.apply(self.db,self.db.get_person_handles(sort_handles=False)) handle_list = self.db.get_person_handles(sort_handles=False)
keys = data_filter.apply(self.db,handle_list)
del handle_list
else: else:
keys = self.db.get_person_handles(sort_handles=False) keys = self.db.get_person_handles(sort_handles=False)
@ -107,9 +109,14 @@ class PeopleModel(gtk.GenericTreeModel):
temp_top_path2iter = self.sname_sub.keys() temp_top_path2iter = self.sname_sub.keys()
temp_top_path2iter.sort(locale.strcoll) temp_top_path2iter.sort(locale.strcoll)
for name in temp_top_path2iter: for name in temp_top_path2iter:
slist = []
for handle in self.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 val = 0
entries = self.sname_sub[name]
entries.sort(self.byname)
for person_handle in entries: for person_handle in entries:
tpl = (name,val) tpl = (name,val)
temp_iter2path[person_handle] = tpl temp_iter2path[person_handle] = tpl
@ -120,18 +127,8 @@ class PeopleModel(gtk.GenericTreeModel):
self.iter2path = temp_iter2path self.iter2path = temp_iter2path
self.path2iter = temp_path2iter self.path2iter = temp_path2iter
self.db.set_people_view_maps(self.get_maps())
def get_maps(self):
return (self.top_path2iter,
self.iter2path,
self.path2iter,
self.sname_sub)
def byname(self,f,s): def byname(self,f,s):
n1 = self.db.person_map.get(str(f))[_NAME_COL].get_sort_name() return locale.strcoll(f[0],s[0])
n2 = self.db.person_map.get(str(s))[_NAME_COL].get_sort_name()
return locale.strcoll(n1,n2)
def on_get_flags(self): def on_get_flags(self):
'''returns the GtkTreeModelFlags for this particular type of model''' '''returns the GtkTreeModelFlags for this particular type of model'''

View File

@ -72,7 +72,7 @@ class PeopleView:
all.set_name(_("Entire Database")) all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([])) all.add_rule(GenericFilter.Everyone([]))
self.DataFilter = all self.DataFilter = None
self.pscroll = self.parent.gtop.get_widget("pscroll") self.pscroll = self.parent.gtop.get_widget("pscroll")
self.person_tree = self.parent.gtop.get_widget("person_tree") self.person_tree = self.parent.gtop.get_widget("person_tree")
self.person_tree.set_rules_hint(gtk.TRUE) self.person_tree.set_rules_hint(gtk.TRUE)
@ -87,9 +87,6 @@ class PeopleView:
self.person_tree.connect('button-press-event', self.person_tree.connect('button-press-event',
self.on_plist_button_press) self.on_plist_button_press)
def get_maps(self):
return self.person_model.get_maps()
def build_columns(self): def build_columns(self):
for column in self.columns: for column in self.columns:
self.person_tree.remove_column(column) self.person_tree.remove_column(column)
@ -147,9 +144,6 @@ class PeopleView:
self.build_columns() self.build_columns()
self.person_model = PeopleModel.PeopleModel(db,self.DataFilter) self.person_model = PeopleModel.PeopleModel(db,self.DataFilter)
self.sort_model = self.person_model self.sort_model = self.person_model
#self.sort_model = self.person_model.filter_new()
#self.sort_model.set_visible_column(PeopleModel.COLUMN_VIEW)
self.apply_filter()
self.person_tree.set_model(self.sort_model) self.person_tree.set_model(self.sort_model)
def remove_from_person_list(self,person): def remove_from_person_list(self,person):

View File

@ -70,7 +70,6 @@ class PlaceView:
self.parent = parent self.parent = parent
self.glade = glade self.glade = glade
self.list = glade.get_widget("place_list") self.list = glade.get_widget("place_list")
#self.list.set_property('fixed-height-mode',True)
self.list.connect('button-press-event',self.button_press) self.list.connect('button-press-event',self.button_press)
self.list.connect('key-press-event',self.key_press) self.list.connect('key-press-event',self.key_press)
self.selection = self.list.get_selection() self.selection = self.list.get_selection()

View File

@ -1142,6 +1142,8 @@ class GrampsParser:
def stop_family(self,*tag): def stop_family(self,*tag):
self.db.commit_family(self.family,self.trans,self.change) self.db.commit_family(self.family,self.trans,self.change)
self.family = None self.family = None
while gtk.events_pending():
gtk.main_iteration()
def stop_event(self,*tag): def stop_event(self,*tag):
self.event.name = self.event_type self.event.name = self.event_type
@ -1186,6 +1188,8 @@ class GrampsParser:
self.event.set_place_handle(self.placeobj.get_handle()) self.event.set_place_handle(self.placeobj.get_handle())
self.db.commit_place(self.placeobj,self.trans,self.change) self.db.commit_place(self.placeobj,self.trans,self.change)
self.placeobj = None self.placeobj = None
while gtk.events_pending():
gtk.main_iteration()
def stop_date(self,tag): def stop_date(self,tag):
if tag: if tag:
@ -1203,6 +1207,8 @@ class GrampsParser:
def stop_person(self,*tag): def stop_person(self,*tag):
self.db.commit_person(self.person,self.trans,self.change) self.db.commit_person(self.person,self.trans,self.change)
self.person = None self.person = None
while gtk.events_pending():
gtk.main_iteration()
def stop_description(self,tag): def stop_description(self,tag):
self.event.set_description(tag) self.event.set_description(tag)

View File

@ -31735,36 +31735,16 @@ Family name Given name
<widget class="GtkTable" id="table47"> <widget class="GtkTable" id="table47">
<property name="border_width">12</property> <property name="border_width">12</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="n_rows">2</property> <property name="n_rows">3</property>
<property name="n_columns">2</property> <property name="n_columns">2</property>
<property name="homogeneous">False</property> <property name="homogeneous">False</property>
<property name="row_spacing">0</property> <property name="row_spacing">6</property>
<property name="column_spacing">0</property> <property name="column_spacing">6</property>
<child>
<widget class="GtkImage" id="image2223">
<property name="visible">True</property>
<property name="stock">gtk-dialog-info</property>
<property name="icon_size">6</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
<child> <child>
<widget class="GtkLabel" id="label401"> <widget class="GtkLabel" id="label401">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">&lt;span size=&quot;larger&quot; weight=&quot;bold&quot;&gt;Loading Database&lt;/span&gt;</property> <property name="label" translatable="yes">&lt;span size=&quot;larger&quot; weight=&quot;bold&quot;&gt;Loading database&lt;/span&gt;</property>
<property name="use_underline">False</property> <property name="use_underline">False</property>
<property name="use_markup">True</property> <property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property> <property name="justify">GTK_JUSTIFY_LEFT</property>
@ -31808,6 +31788,49 @@ Family name Given name
<property name="y_options"></property> <property name="y_options"></property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkLabel" id="message">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkImage" id="image2223">
<property name="visible">True</property>
<property name="pixbuf">gramps.png</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
</widget> </widget>
</child> </child>
</widget> </widget>

View File

@ -77,10 +77,7 @@ import RecentFiles
from QuestionDialog import * from QuestionDialog import *
try: # First try python2.3 and later: this is the future
from bsddb import db from bsddb import db
except ImportError: # try python2.2
from bsddb3 import db
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -598,7 +595,8 @@ class Gramps:
item = gtk.MenuItem("_%d. %s [%s]" % item = gtk.MenuItem("_%d. %s [%s]" %
(num,person.get_primary_name().get_name(), (num,person.get_primary_name().get_name(),
person.get_gramps_id())) person.get_gramps_id()))
item.connect("activate",self.bookmark_callback,person.get_handle()) item.connect("activate",self.bookmark_callback,
person.get_handle())
item.show() item.show()
gomenu.append(item) gomenu.append(item)
num = num + 1 num = num + 1
@ -629,7 +627,9 @@ class Gramps:
break break
person = self.db.get_person_from_handle(pid) person = self.db.get_person_from_handle(pid)
item = gtk.MenuItem("%s. %s [%s]" % item = gtk.MenuItem("%s. %s [%s]" %
(hotkey,person.get_primary_name().get_name(),person.get_gramps_id())) (hotkey,
person.get_primary_name().get_name(),
person.get_gramps_id()))
item.connect("activate",self.back_clicked,num) item.connect("activate",self.back_clicked,num)
item.show() item.show()
backhistmenu.append(item) backhistmenu.append(item)
@ -657,7 +657,9 @@ class Gramps:
break break
person = self.db.get_person_from_handle(pid) person = self.db.get_person_from_handle(pid)
item = gtk.MenuItem("%s. %s [%s]" % item = gtk.MenuItem("%s. %s [%s]" %
(hotkey,person.get_primary_name().get_name(),person.get_gramps_id())) (hotkey,
person.get_primary_name().get_name(),
person.get_gramps_id()))
item.connect("activate",self.fwd_clicked,num) item.connect("activate",self.fwd_clicked,num)
item.show() item.show()
fwdhistmenu.append(item) fwdhistmenu.append(item)
@ -901,29 +903,18 @@ class Gramps:
def on_exit_activate(self,obj): def on_exit_activate(self,obj):
"""Prompt to save on exit if needed""" """Prompt to save on exit if needed"""
self.delete_abandoned_photos()
self.db.close() self.db.close()
gtk.main_quit() gtk.main_quit()
def quit(self): def quit(self):
"""Catch the reponse to the save on exit question""" """Catch the reponse to the save on exit question"""
self.delete_abandoned_photos()
self.db.close() self.db.close()
gtk.main_quit() gtk.main_quit()
def close_noquit(self): def close_noquit(self):
"""Close database and delete abandoned photos, no quit""" """Close database and delete abandoned photos, no quit"""
self.delete_abandoned_photos()
self.db.close() self.db.close()
def delete_abandoned_photos(self):
"""
We only want to delete local objects, not external objects, however, we
can delete any thumbnail images. The thumbnails may or may not exist, depending
on if the image was previewed.
"""
self.db.set_people_view_maps(self.people_view.get_maps())
def on_about_activate(self,obj): def on_about_activate(self,obj):
"""Displays the about box. Called from Help menu""" """Displays the about box. Called from Help menu"""
pixbuf = gtk.gdk.pixbuf_new_from_file(const.logo) pixbuf = gtk.gdk.pixbuf_new_from_file(const.logo)
@ -1026,7 +1017,8 @@ class Gramps:
def read_xml(self,filename): def read_xml(self,filename):
import ReadXML import ReadXML
filename = os.path.normpath(os.path.abspath(os.path.join(filename,const.xmlFile))) filename = os.path.normpath(
os.path.abspath(os.path.join(filename,const.xmlFile)))
try: try:
ReadXML.importData(self.db,filename,None) ReadXML.importData(self.db,filename,None)
@ -1602,9 +1594,10 @@ class Gramps:
if self.db.load(filename,self.load_progress) == 0: if self.db.load(filename,self.load_progress) == 0:
self.status_text('') self.status_text('')
return 0 return 0
self.status_text('') self.status_text('')
return self.post_load(name)
val = self.post_load(name)
return val
def setup_bookmarks(self): def setup_bookmarks(self):
self.bookmarks = Bookmarks.Bookmarks(self.db,self.db.get_bookmarks(), self.bookmarks = Bookmarks.Bookmarks(self.db,self.db.get_bookmarks(),

View File

@ -33,13 +33,6 @@ _findint = re.compile('^[^\d]*(\d+)[^\d]*')
def runTool(db,active_person,callback,parent): def runTool(db,active_person,callback,parent):
"""Changed person, family, object, source, and place ids""" """Changed person, family, object, source, and place ids"""
# FIXME: Remove when plugin is properly implemented
from QuestionDialog import OkDialog
OkDialog(_("Plugin unavailable"),
_("This plugin is not implemented yet. Please check the next version."),
parent.topWindow)
return
try: try:
ReorderIds(db,callback) ReorderIds(db,callback)
except: except:
@ -52,33 +45,31 @@ class ReorderIds:
self.db = db self.db = db
self.reorder(db.get_person_handle_map(),db.iprefix,db.build_person_display) self.reorder_person()
self.reorder(db.get_family_handle_map(),db.fprefix,None) self.reorder(db.get_family_handle_map(),db.fprefix,None)
self.reorder(db.get_object_map(),db.oprefix,None) self.reorder(db.get_object_map(),db.oprefix,None)
self.reorder(db.get_source_map(),db.sprefix,db.build_source_display) self.reorder(db.get_source_map(),db.sprefix,db.build_source_display)
self.reorder(db.get_place_handle_map(),db.pprefix,db.build_place_display) self.reorder(db.get_place_handle_map(),db.pprefix,db.build_place_display)
Utils.history_broken()
callback(1) callback(1)
def reorder(self,data_map,prefix,update): def reorder_person():
"""Try to extract the old integer out of the id, and reuse it
if possible. Otherwise, blindly renumber those that can't."""
dups = [] dups = []
newids = {} newids = {}
key_list = [] key_list = []
# search all ids in the map # search all ids in the map
for x in data_map.keys(): cursor = self.db.get_person_cursor()
key_list.append(x) data = cursor.first()
while data:
(handle,sdata) = data
for handle in key_list: gramps_id = sdata[1]
# attempt to extract integer, if we can't, treat it as a # attempt to extract integer, if we can't, treat it as a
# duplicate # duplicate
match = _findint.match(handle) match = _findint.match(gramps_id)
if match: if match:
# get the integer, build the new handle. Make sure it # get the integer, build the new handle. Make sure it
# hasn't already been chosen. If it has, put this # hasn't already been chosen. If it has, put this
@ -86,42 +77,45 @@ class ReorderIds:
try: try:
index = match.groups()[0] index = match.groups()[0]
newhandle = prefix % int(index) newgramps_id = prefix % int(index)
if newhandle == handle: if newgramps_id == gramps_id:
newids[newhandle] = handle newids[newgramps_id] = gramps_id
continue continue
elif data_map.has_key(newhandle): elif data_map.has_key(newgramps_id):
dups.append(handle) dups.append(handle)
else: else:
data = data_map[handle] data = data_map[gramps_id]
data_map[newhandle] = data data_map[newgramps_id] = data
newids[newhandle] = handle newids[newgramps_id] = gramps_id
data.set_handle(newhandle) data.set_gramps_id(newgramps_id)
del data_map[handle] del data_map[gramps_id]
if update: if update:
update(newhandle,handle) update(newgramps_id,gramps_id)
except: except:
dups.append(handle) dups.append(handle)
else: else:
dups.append(handle) dups.append(handle)
data = cursor.next()
# go through the duplicates, looking for the first availble # go through the duplicates, looking for the first availble
# handle that matches the new scheme. # handle that matches the new scheme.
index = 0 index = 0
for handle in dups: for gramps_id in dups:
while 1: while 1:
newhandle = prefix % index newgramps_id = prefix % index
if not newids.has_key(newhandle): if not newids.has_key(newgramps_id):
break break
index = index + 1 index = index + 1
newids[newhandle] = newhandle newids[newgramps_id] = newgramps_id
data = data_map[handle] data = data_map[gramps_id]
data.set_handle(newhandle) data.set_gramps_id(newgramps_id)
data_map[newhandle] = data data_map[newgramps_id] = data
if update: if update:
update(newhandle,handle) update(newgramps_id,gramps_id)
del data_map[handle] del data_map[gramps_id]
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #