optimization and cleaning of the base model for flat treeviews
svn: r12723
This commit is contained in:
@@ -4,7 +4,6 @@ pkgdatadir = $(datadir)/@PACKAGE@/DisplayModels
|
||||
|
||||
pkgdata_PYTHON = \
|
||||
__init__.py \
|
||||
_BaseModel.py \
|
||||
_EventModel.py \
|
||||
_FamilyModel.py \
|
||||
_MediaModel.py \
|
||||
|
||||
@@ -1,357 +0,0 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# $Id$
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import locale
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GNOME/GTK modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from Filters import SearchFilter
|
||||
import Config
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# NodeMap
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class NodeMap(object):
|
||||
"""
|
||||
Provide the Path to Iter mappings for a TreeView model. The implementation
|
||||
provides a list of nodes and a dictionary of handles. The datalist provides
|
||||
the path (index) to iter (handle) mapping, while the the indexmap provides
|
||||
the handle to index mappings
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Create a new instance, clearing the datalist and indexmap
|
||||
"""
|
||||
self.data_list = []
|
||||
self.index_map = {}
|
||||
|
||||
def set_path_map(self, dlist):
|
||||
"""
|
||||
Takes a list of handles and builds the index map from it.
|
||||
"""
|
||||
self.data_list = dlist
|
||||
i = 0
|
||||
self.index_map = {}
|
||||
for key in self.data_list:
|
||||
self.index_map[key] = i
|
||||
i +=1
|
||||
|
||||
def clear_map(self):
|
||||
"""
|
||||
Clears out the data_list and the index_map
|
||||
"""
|
||||
self.data_list = []
|
||||
self.index_map = {}
|
||||
|
||||
def get_path(self, handle):
|
||||
"""
|
||||
Return the path from the passed handle. This is accomplished by
|
||||
indexing into the index_map to get the index (path)
|
||||
"""
|
||||
return self.index_map.get(handle)
|
||||
|
||||
def get_handle(self, path):
|
||||
"""
|
||||
Return the handle from the path. The path is assumed to be an integer.
|
||||
This is accomplished by indexing into the data_list
|
||||
"""
|
||||
return self.data_list[path]
|
||||
|
||||
def delete_by_index(self, index):
|
||||
"""
|
||||
Deletes the item at the specified path, then rebuilds the index_map,
|
||||
subtracting one from each item greater than the deleted index.
|
||||
"""
|
||||
handle = self.data_list[index]
|
||||
del self.data_list[index]
|
||||
del self.index_map[handle]
|
||||
|
||||
for key in self.index_map:
|
||||
if self.index_map[key] > index:
|
||||
self.index_map[key] -= 1
|
||||
|
||||
def find_next_handle(self, handle):
|
||||
"""
|
||||
Finds the next handle based off the passed handle. This is accomplished
|
||||
by finding the index of associated with the handle, adding one to find
|
||||
the next index, then finding the handle associated with the next index.
|
||||
"""
|
||||
try:
|
||||
return self.data_list[self.index_map.get(handle)+1]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Return the number of entries in the map.
|
||||
"""
|
||||
return len(self.data_list)
|
||||
|
||||
def get_first_handle(self):
|
||||
"""
|
||||
Return the first handle in the map.
|
||||
"""
|
||||
return self.data_list[0]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# BaseModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class BaseModel(gtk.GenericTreeModel):
|
||||
|
||||
def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING,
|
||||
tooltip_column=None, search=None, skip=set(),
|
||||
sort_map=None):
|
||||
gtk.GenericTreeModel.__init__(self)
|
||||
self.prev_handle = None
|
||||
self.prev_data = None
|
||||
self.set_property("leak_references",False)
|
||||
self.db = db
|
||||
if sort_map:
|
||||
self.sort_map = [ f for f in sort_map if f[0]]
|
||||
col = self.sort_map[scol][1]
|
||||
self.sort_func = self.smap[col]
|
||||
else:
|
||||
self.sort_func = self.smap[scol]
|
||||
self.sort_col = scol
|
||||
self.skip = skip
|
||||
|
||||
self.total = 0
|
||||
self.displayed = 0
|
||||
|
||||
self.node_map = NodeMap()
|
||||
|
||||
if search:
|
||||
if search[0]:
|
||||
self.search = search[1]
|
||||
self.rebuild_data = self._rebuild_filter
|
||||
else:
|
||||
if search[1]:
|
||||
# we have search[1] = (index, text_unicode, inversion)
|
||||
col = search[1][0]
|
||||
text = search[1][1]
|
||||
inv = search[1][2]
|
||||
func = lambda x: self.on_get_value(x, col) or u""
|
||||
self.search = SearchFilter(func, text, inv)
|
||||
else:
|
||||
self.search = None
|
||||
self.rebuild_data = self._rebuild_search
|
||||
else:
|
||||
self.search = None
|
||||
self.rebuild_data = self._rebuild_search
|
||||
|
||||
self.reverse = (order == gtk.SORT_DESCENDING)
|
||||
self.tooltip_column = tooltip_column
|
||||
|
||||
Config.client.notify_add("/apps/gramps/preferences/todo-color",
|
||||
self.update_todo)
|
||||
Config.client.notify_add("/apps/gramps/preferences/custom-marker-color",
|
||||
self.update_custom)
|
||||
Config.client.notify_add("/apps/gramps/preferences/complete-color",
|
||||
self.update_complete)
|
||||
|
||||
self.complete_color = Config.get(Config.COMPLETE_COLOR)
|
||||
self.todo_color = Config.get(Config.TODO_COLOR)
|
||||
self.custom_color = Config.get(Config.CUSTOM_MARKER_COLOR)
|
||||
self.rebuild_data()
|
||||
|
||||
def update_todo(self,client,cnxn_id,entry,data):
|
||||
self.todo_color = Config.get(Config.TODO_COLOR)
|
||||
|
||||
def update_custom(self,client,cnxn_id,entry,data):
|
||||
self.custom_color = Config.get(Config.CUSTOM_MARKER_COLOR)
|
||||
|
||||
def update_complete(self,client,cnxn_id,entry,data):
|
||||
self.complete_color = Config.get(Config.COMPLETE_COLOR)
|
||||
|
||||
def set_sort_column(self,col):
|
||||
self.sort_func = self.smap[col]
|
||||
|
||||
def sort_keys(self):
|
||||
cursor = self.gen_cursor()
|
||||
self.sort_data = []
|
||||
data = cursor.next()
|
||||
|
||||
self.total = 0
|
||||
while data:
|
||||
self.sort_data.append((self.sort_func(data[1]),data[0]))
|
||||
self.total += 1
|
||||
data = cursor.next()
|
||||
cursor.close()
|
||||
|
||||
self.sort_data.sort(lambda x, y: locale.strcoll(x[0], y[0]),
|
||||
reverse=self.reverse)
|
||||
|
||||
return [ x[1] for x in self.sort_data ]
|
||||
|
||||
def _rebuild_search(self,ignore=None):
|
||||
""" function called when view must be build, given a search text
|
||||
in the top search bar
|
||||
"""
|
||||
self.total = 0
|
||||
if self.db.is_open():
|
||||
if self.search and self.search.text:
|
||||
dlist = [h for h in self.sort_keys()\
|
||||
if self.search.match(h,self.db) and \
|
||||
h not in self.skip and h != ignore]
|
||||
else:
|
||||
dlist = [h for h in self.sort_keys() \
|
||||
if h not in self.skip and h != ignore]
|
||||
self.displayed = len(dlist)
|
||||
self.node_map.set_path_map(dlist)
|
||||
else:
|
||||
self.displayed = 0
|
||||
self.node_map.clear_map()
|
||||
|
||||
def _rebuild_filter(self, ignore=None):
|
||||
""" function called when view must be build, given filter options
|
||||
in the filter sidebar
|
||||
"""
|
||||
self.total = 0
|
||||
if self.db.is_open():
|
||||
if self.search:
|
||||
dlist = self.search.apply(self.db,
|
||||
[ k for k in self.sort_keys()\
|
||||
if k != ignore])
|
||||
else:
|
||||
dlist = [ k for k in self.sort_keys() \
|
||||
if k != ignore ]
|
||||
|
||||
self.displayed = len(dlist)
|
||||
self.node_map.set_path_map(dlist)
|
||||
else:
|
||||
self.displayed = 0
|
||||
self.node_map.clear_map()
|
||||
|
||||
def add_row_by_handle(self, handle):
|
||||
if not self.search or \
|
||||
(self.search and self.search.match(handle, self.db)):
|
||||
|
||||
data = self.map(handle)
|
||||
self.sort_data.append((self.sort_func(data), handle))
|
||||
self.sort_data.sort(lambda x, y: locale.strcoll(x[0], y[0]),
|
||||
reverse=self.reverse)
|
||||
self.node_map.set_path_map([ x[1] for x in self.sort_data ])
|
||||
|
||||
index = self.node_map.get_path(handle)
|
||||
if index is not None:
|
||||
node = self.get_iter(index)
|
||||
self.row_inserted(index, node)
|
||||
|
||||
def delete_row_by_handle(self, handle):
|
||||
index = self.node_map.get_path(handle)
|
||||
|
||||
# remove from sort array
|
||||
i = 0
|
||||
for (key, node) in self.sort_data:
|
||||
if handle == node:
|
||||
del self.sort_data[i]
|
||||
break
|
||||
i += 1
|
||||
|
||||
self.node_map.delete_by_index(index)
|
||||
self.row_deleted(index)
|
||||
|
||||
def update_row_by_handle(self, handle):
|
||||
index = self.node_map.get_path(handle)
|
||||
node = self.get_iter(index)
|
||||
self.row_changed(index, node)
|
||||
|
||||
def on_get_flags(self):
|
||||
"""returns the GtkTreeModelFlags for this particular type of model"""
|
||||
return gtk.TREE_MODEL_LIST_ONLY | gtk.TREE_MODEL_ITERS_PERSIST
|
||||
|
||||
def on_get_n_columns(self):
|
||||
return 1
|
||||
|
||||
def on_get_path(self, node):
|
||||
"""returns the tree path (a tuple of indices at the various
|
||||
levels) for a particular node."""
|
||||
return self.node_map.get_path(node)
|
||||
|
||||
def on_get_column_type(self,index):
|
||||
if index == self.tooltip_column:
|
||||
return object
|
||||
return str
|
||||
|
||||
def on_get_iter(self, path):
|
||||
try:
|
||||
return self.node_map.get_handle(path[0])
|
||||
except:
|
||||
return None
|
||||
|
||||
def on_get_value(self, node, col):
|
||||
try:
|
||||
if node != self.prev_handle:
|
||||
self.prev_data = self.map(str(node))
|
||||
self.prev_handle = node
|
||||
return self.fmap[col](self.prev_data)
|
||||
except:
|
||||
return u''
|
||||
|
||||
def on_iter_next(self, node):
|
||||
"""returns the next node at this level of the tree"""
|
||||
return self.node_map.find_next_handle(node)
|
||||
|
||||
def on_iter_children(self, node):
|
||||
"""Return the first child of the node"""
|
||||
if node is None and len(self.node_map):
|
||||
return self.node_map.get_first_handle()
|
||||
return None
|
||||
|
||||
def on_iter_has_child(self, node):
|
||||
"""returns true if this node has children"""
|
||||
if node is None:
|
||||
return len(self.node_map) > 0
|
||||
return False
|
||||
|
||||
def on_iter_n_children(self, node):
|
||||
if node is None:
|
||||
return len(self.node_map)
|
||||
return 0
|
||||
|
||||
def on_iter_nth_child(self, node, n):
|
||||
if node is None:
|
||||
return self.node_map.get_handle(n)
|
||||
return None
|
||||
|
||||
def on_iter_parent(self, node):
|
||||
"""returns the parent of this node"""
|
||||
return None
|
||||
@@ -44,7 +44,7 @@ import ToolTips
|
||||
import GrampsLocale
|
||||
import DateHandler
|
||||
import gen.lib
|
||||
from _BaseModel import BaseModel
|
||||
from gui.views.treemodels.flatbasemodel import FlatBaseModel
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -64,7 +64,7 @@ COLUMN_CHANGE = 10
|
||||
# EventModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class EventModel(BaseModel):
|
||||
class EventModel(FlatBaseModel):
|
||||
|
||||
def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None,
|
||||
skip=set(), sort_map=None):
|
||||
@@ -91,7 +91,7 @@ class EventModel(BaseModel):
|
||||
self.column_handle,
|
||||
self.column_tooltip,
|
||||
]
|
||||
BaseModel.__init__(self, db, scol, order, tooltip_column=8,
|
||||
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=8,
|
||||
search=search, skip=skip, sort_map=sort_map)
|
||||
|
||||
def on_get_n_columns(self):
|
||||
|
||||
@@ -48,14 +48,14 @@ from BasicUtils import name_displayer
|
||||
import gen.lib
|
||||
import gen.utils
|
||||
|
||||
from _BaseModel import BaseModel
|
||||
from gui.views.treemodels.flatbasemodel import FlatBaseModel
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# FamilyModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class FamilyModel(BaseModel):
|
||||
class FamilyModel(FlatBaseModel):
|
||||
|
||||
_MARKER_COL = 13
|
||||
|
||||
@@ -88,7 +88,7 @@ class FamilyModel(BaseModel):
|
||||
self.column_marker_color,
|
||||
]
|
||||
self.marker_color_column = 9
|
||||
BaseModel.__init__(self, db, scol, order, tooltip_column=6,
|
||||
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=6,
|
||||
search=search, skip=skip, sort_map=sort_map)
|
||||
|
||||
def on_get_n_columns(self):
|
||||
|
||||
@@ -46,14 +46,14 @@ import ToolTips
|
||||
import GrampsLocale
|
||||
import DateHandler
|
||||
import gen.lib
|
||||
from _BaseModel import BaseModel
|
||||
from gui.views.treemodels.flatbasemodel import FlatBaseModel
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# MediaModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class MediaModel(BaseModel):
|
||||
class MediaModel(FlatBaseModel):
|
||||
|
||||
def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None,
|
||||
skip=set(), sort_map=None):
|
||||
@@ -80,7 +80,7 @@ class MediaModel(BaseModel):
|
||||
self.sort_date,
|
||||
self.column_handle,
|
||||
]
|
||||
BaseModel.__init__(self, db, scol, order, tooltip_column=7,
|
||||
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=7,
|
||||
search=search, skip=skip, sort_map=sort_map)
|
||||
|
||||
def on_get_n_columns(self):
|
||||
|
||||
@@ -39,7 +39,7 @@ import gtk
|
||||
# GRAMPS modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from _BaseModel import BaseModel
|
||||
from gui.views.treemodels.flatbasemodel import FlatBaseModel
|
||||
from gen.lib import (Note, NoteType, MarkerType, StyledText)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -47,7 +47,7 @@ from gen.lib import (Note, NoteType, MarkerType, StyledText)
|
||||
# NoteModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class NoteModel(BaseModel):
|
||||
class NoteModel(FlatBaseModel):
|
||||
"""
|
||||
"""
|
||||
def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None,
|
||||
@@ -72,7 +72,7 @@ class NoteModel(BaseModel):
|
||||
self.column_marker_color
|
||||
]
|
||||
self.marker_color_column = 5
|
||||
BaseModel.__init__(self, db, scol, order, search=search,
|
||||
FlatBaseModel.__init__(self, db, scol, order, search=search,
|
||||
skip=skip, sort_map=sort_map)
|
||||
|
||||
def on_get_n_columns(self):
|
||||
|
||||
@@ -43,14 +43,14 @@ import gtk
|
||||
import const
|
||||
import ToolTips
|
||||
import GrampsLocale
|
||||
from _BaseModel import BaseModel
|
||||
from gui.views.treemodels.flatbasemodel import FlatBaseModel
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# PlaceModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class PlaceModel(BaseModel):
|
||||
class PlaceModel(FlatBaseModel):
|
||||
|
||||
HANDLE_COL = 12
|
||||
|
||||
@@ -89,7 +89,7 @@ class PlaceModel(BaseModel):
|
||||
self.column_street,
|
||||
self.column_handle,
|
||||
]
|
||||
BaseModel.__init__(self, db, scol, order, tooltip_column=13,
|
||||
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=13,
|
||||
search=search, skip=skip, sort_map=sort_map)
|
||||
|
||||
def on_get_n_columns(self):
|
||||
|
||||
@@ -42,14 +42,14 @@ import gtk
|
||||
#-------------------------------------------------------------------------
|
||||
import gen.lib
|
||||
import GrampsLocale
|
||||
from _BaseModel import BaseModel
|
||||
from gui.views.treemodels.flatbasemodel import FlatBaseModel
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# RepositoryModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class RepositoryModel(BaseModel):
|
||||
class RepositoryModel(FlatBaseModel):
|
||||
|
||||
def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None,
|
||||
skip=set(), sort_map=None):
|
||||
@@ -91,7 +91,7 @@ class RepositoryModel(BaseModel):
|
||||
self.column_handle,
|
||||
]
|
||||
|
||||
BaseModel.__init__(self, db, scol, order, tooltip_column=14,
|
||||
FlatBaseModel.__init__(self, db, scol, order, tooltip_column=14,
|
||||
search=search, skip=skip, sort_map=sort_map)
|
||||
|
||||
def on_get_n_columns(self):
|
||||
|
||||
@@ -43,14 +43,14 @@ import gtk
|
||||
import const
|
||||
import ToolTips
|
||||
import GrampsLocale
|
||||
from _BaseModel import BaseModel
|
||||
from gui.views.treemodels.flatbasemodel import FlatBaseModel
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# SourceModel
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class SourceModel(BaseModel):
|
||||
class SourceModel(FlatBaseModel):
|
||||
|
||||
def __init__(self,db,scol=0, order=gtk.SORT_ASCENDING,search=None,
|
||||
skip=set(), sort_map=None):
|
||||
@@ -74,7 +74,7 @@ class SourceModel(BaseModel):
|
||||
self.column_pubinfo,
|
||||
self.sort_change,
|
||||
]
|
||||
BaseModel.__init__(self,db,scol, order,tooltip_column=7,search=search,
|
||||
FlatBaseModel.__init__(self,db,scol, order,tooltip_column=7,search=search,
|
||||
skip=skip, sort_map=sort_map)
|
||||
|
||||
def on_get_n_columns(self):
|
||||
|
||||
Reference in New Issue
Block a user