integrated treeview/model into objectselector.
svn: r5897
This commit is contained in:
parent
bc81ae7f5f
commit
80a0ab047d
@ -1,3 +1,12 @@
|
||||
2006-02-08 Richard Taylor <rjt-gramps@thegrindstone.me.uk>
|
||||
* src/EditFamily.py, src/Models/_FastFilterModel.py,
|
||||
src/Models/_FastModel.py, src/ObjectSelector/_FilterFrameBase.py,
|
||||
src/ObjectSelector/_ObjectFrameBase.py, src/ObjectSelector/_ObjectSelectorWindow.py,
|
||||
src/ObjectSelector/_PersonFilterFrame.py, src/ObjectSelector/_PersonFrame.py,
|
||||
src/ObjectSelector/_PersonPreviewFrame.py, src/ObjectSelector/_PersonTreeFrame.py,
|
||||
src/TreeViews/_PersonTreeView.py: Integrated new treeview/model code into ObjectSelector
|
||||
|
||||
|
||||
2006-02-07 Don Allingham <don@gramps-project.org>
|
||||
* src/DisplayModels.py: gobject.TYPE_STRING -> str
|
||||
* src/EditFamily.py: privacy widget
|
||||
|
@ -355,27 +355,23 @@ class EditFamily(DisplayState.ManagedWindow):
|
||||
self.load_parent(handle, self.mbox, self.mbirth,
|
||||
self.mdeath, self.mbutton)
|
||||
|
||||
def on_change_mother(self, selector_window, select_result):
|
||||
print select_result
|
||||
if select_result.is_person():
|
||||
def on_change_mother(self, selector_window, obj):
|
||||
if obj.__class__ == RelLib.Person:
|
||||
try:
|
||||
gid = select_result.get_gramps_id()
|
||||
person = self.dbstate.db.get_person_from_gramps_id(gid)
|
||||
person = obj
|
||||
self.family.set_mother_handle(person.get_handle())
|
||||
self.update_mother(person.get_handle())
|
||||
except:
|
||||
log.warn(
|
||||
"Failed to update mother: \n"
|
||||
"gramps_id returned from selector was: %s\n"
|
||||
"person returned from get_person_from_gramps_id: %s"
|
||||
% (select_result.get_gramps_id(),
|
||||
repr(self.dbstate.db.get_person_from_gramps_id(
|
||||
select_result.get_gramps_id()))))
|
||||
"obj returned from selector was: %s\n"
|
||||
% (repr(obj),))
|
||||
raise
|
||||
else:
|
||||
log.warn(
|
||||
"Object selector returned a result of type = %s, it should "
|
||||
"have been of type PERSON." % (str(select_result.get_object_type())))
|
||||
"Object selector returned obj.__class__ = %s, it should "
|
||||
"have been of type %s." % (obj.__class__.__name__,
|
||||
RelLib.Person.__name__))
|
||||
|
||||
selector_window.close()
|
||||
|
||||
@ -408,24 +404,23 @@ class EditFamily(DisplayState.ManagedWindow):
|
||||
selector.connect('add-object',self.on_change_mother)
|
||||
|
||||
|
||||
def on_change_father(self, selector_window, select_result):
|
||||
if select_result.is_person():
|
||||
def on_change_father(self, selector_window, obj):
|
||||
if obj.__class__ == RelLib.Person:
|
||||
try:
|
||||
gid = select_result.get_gramps_id()
|
||||
person = self.dbstate.db.get_person_from_gramps_id(gid)
|
||||
person = obj
|
||||
self.family.set_father_handle(person.get_handle())
|
||||
self.update_father(person.get_handle())
|
||||
except:
|
||||
log.warn("Failed to update father: \n"
|
||||
"gramps_id returned from selector was: %s\n"
|
||||
"person returned from get_person_from_gramps_id: %s"
|
||||
% (select_result.get_gramps_id(),
|
||||
repr(self.dbstate.db.get_person_from_gramps_id(
|
||||
select_result.get_gramps_id()))))
|
||||
"obj returned from selector was: %s\n"
|
||||
% (repr(obj),))
|
||||
raise
|
||||
|
||||
else:
|
||||
log.warn("Object selector returned a result of type = %s, it should "
|
||||
"have been of type PERSON." % (str(select_result.get_object_type())))
|
||||
log.warn(
|
||||
"Object selector returned obj.__class__ = %s, it should "
|
||||
"have been of type %s." % (obj.__class__.__name__,
|
||||
RelLib.Person.__name__))
|
||||
|
||||
selector_window.close()
|
||||
|
||||
|
@ -45,17 +45,29 @@ class FastFilterModel(gtk.GenericTreeModel):
|
||||
self._db = db
|
||||
self._data_filter = data_filter
|
||||
self._fetch_func = self._get_fetch_func(db)
|
||||
|
||||
self._keys = []
|
||||
self._length = 0
|
||||
|
||||
self._build_data()
|
||||
|
||||
def _build_data(self):
|
||||
if not self._data_filter.is_empty():
|
||||
self._keys = self._data_filter.apply(self._db)
|
||||
else:
|
||||
else:
|
||||
return
|
||||
|
||||
self._length = len(self._keys)
|
||||
|
||||
|
||||
# Helper methods to enable treeviews to tell if the model is
|
||||
# a tree or a list.
|
||||
|
||||
def is_tree(self):
|
||||
return not self.is_list()
|
||||
|
||||
def is_list(self):
|
||||
return self.on_get_flags()>k.TREE_MODEL_LIST_ONLY
|
||||
|
||||
|
||||
# Methods that must be implemented by subclasses.
|
||||
def _get_fetch_func(self,db):
|
||||
@ -84,16 +96,29 @@ class FastFilterModel(gtk.GenericTreeModel):
|
||||
Fetch the real object from the database.
|
||||
"""
|
||||
|
||||
record = None
|
||||
|
||||
# We only have one column
|
||||
if column is 0:
|
||||
record = self._fetch_func(self._keys[rowref[0]])
|
||||
if column is 0 and self._length > 0:
|
||||
log.debug("on_get_value: rowref = %s", (repr(rowref)))
|
||||
|
||||
# This should never return none, but there is a subtle bug
|
||||
# somewhere that I can't find and sometimes it does.
|
||||
if record is None:
|
||||
log.warn("Failed to fetch a record from the cursor rowref = %s" % (str(rowref)))
|
||||
try:
|
||||
record = self._fetch_func(self._keys[rowref[0]])
|
||||
|
||||
# This should never return none, but there is a subtle bug
|
||||
# somewhere that I can't find and sometimes it does.
|
||||
if record is None:
|
||||
log.warn("Failed to fetch a record from the "\
|
||||
"cursor rowref = %s" % (str(rowref)))
|
||||
except:
|
||||
log.warn("Failed to fetch record, rowref = %s"\
|
||||
" len(self._keys) = %d "\
|
||||
" self._length = %d " % (repr(rowref),
|
||||
len(self._keys),
|
||||
self._length),
|
||||
exc_info=True)
|
||||
|
||||
return (record,rowref)
|
||||
return (record,rowref)
|
||||
|
||||
def on_iter_next(self, rowref):
|
||||
"""
|
||||
|
@ -50,6 +50,14 @@ class FastModel(gtk.GenericTreeModel):
|
||||
|
||||
self._num_children_cache = {}
|
||||
|
||||
# Helper methods to enable treeviews to tell if the model is
|
||||
# a tree or a list.
|
||||
|
||||
def is_tree(self):
|
||||
return not self.is_list()
|
||||
|
||||
def is_list(self):
|
||||
return self.on_get_flags()>k.TREE_MODEL_LIST_ONLY
|
||||
|
||||
# Methods that must be implemented by subclasses.
|
||||
|
||||
|
@ -33,7 +33,10 @@ class FilterFrameBase(gtk.Frame):
|
||||
__gsignals__ = {
|
||||
'apply-filter': (gobject.SIGNAL_RUN_LAST,
|
||||
gobject.TYPE_NONE,
|
||||
(gobject.TYPE_PYOBJECT,))
|
||||
(gobject.TYPE_PYOBJECT,)),
|
||||
'clear-filter': (gobject.SIGNAL_RUN_LAST,
|
||||
gobject.TYPE_NONE,
|
||||
())
|
||||
}
|
||||
|
||||
__default_border_width = 5
|
||||
@ -56,16 +59,23 @@ class FilterFrameBase(gtk.Frame):
|
||||
self._control_col = 2
|
||||
|
||||
|
||||
# Apply
|
||||
# Apply / Clear
|
||||
|
||||
apply_button = gtk.Button(stock=gtk.STOCK_APPLY)
|
||||
apply_button.connect('clicked',self.on_apply)
|
||||
clear_button = gtk.Button(stock=gtk.STOCK_CLEAR)
|
||||
clear_button.connect('clicked',self.on_clear)
|
||||
|
||||
button_box = gtk.HBox()
|
||||
button_box.pack_start(apply_button,False,False)
|
||||
button_box.pack_start(clear_button,False,False)
|
||||
|
||||
|
||||
# Outer box
|
||||
|
||||
outer_box = gtk.VBox()
|
||||
outer_box.pack_start(self._table,True,True)
|
||||
outer_box.pack_start(apply_button,False,False)
|
||||
outer_box.pack_start(button_box,False,False)
|
||||
outer_box.set_border_width(self.__class__.__default_border_width/2)
|
||||
outer_box.set_spacing(self.__class__.__default_border_width/2)
|
||||
|
||||
@ -83,7 +93,12 @@ class FilterFrameBase(gtk.Frame):
|
||||
"""Build a GenericFilter object from the settings in the filter controls and
|
||||
emit a 'apply-filter' signal with the GenericFilter object as the parameter."""
|
||||
|
||||
pass
|
||||
raise NotImplementedError("subclass of FilterFrameBase must implement on_apply")
|
||||
|
||||
def on_clear(self,button):
|
||||
"""Clear all the filter widgets and emit a 'clear-filter' signal."""
|
||||
|
||||
raise NotImplementedError("subclass of FilterFrameBase must implement on_apply")
|
||||
|
||||
if gtk.pygtk_version < (2,8,0):
|
||||
gobject.type_register(FilterFrameBase)
|
||||
|
@ -82,11 +82,20 @@ class ObjectFrameBase(gtk.Frame):
|
||||
self.add(pane_align)
|
||||
|
||||
|
||||
def set_preview(self,treeselection,id_field):
|
||||
def set_preview(self,treeselection):
|
||||
(model, iter) = treeselection.get_selected()
|
||||
if iter and model.get_value(iter,id_field):
|
||||
self._preview_frame.set_sensitive(True)
|
||||
self._preview_frame.set_object_from_id(model.get_value(iter,id_field))
|
||||
if iter:
|
||||
(obj,rowref) = model.get_value(iter,0)
|
||||
if len(rowref) > 1 or model.is_list():
|
||||
if obj:
|
||||
self._preview_frame.set_sensitive(True)
|
||||
self._preview_frame.set_object(obj)
|
||||
else:
|
||||
self._preview_frame.set_sensitive(False)
|
||||
self._preview_frame.clear_object()
|
||||
else:
|
||||
self._preview_frame.set_sensitive(False)
|
||||
self._preview_frame.clear_object()
|
||||
else:
|
||||
self._preview_frame.set_sensitive(False)
|
||||
self._preview_frame.clear_object()
|
||||
|
@ -33,7 +33,6 @@ from gettext import gettext as _
|
||||
|
||||
import _Factories
|
||||
from _Constants import ObjectTypes
|
||||
from _ObjectSelectorResult import ObjectSelectorResult
|
||||
|
||||
from DisplayState import ManagedWindow
|
||||
import const
|
||||
@ -317,14 +316,8 @@ class ObjectSelectorWindow(gtk.Window,ManagedWindow):
|
||||
self._add_button.set_sensitive(False)
|
||||
|
||||
|
||||
def get_result(self):
|
||||
result = ObjectSelectorResult()
|
||||
result.set_object_type(self._current_object_type)
|
||||
result.set_gramps_id(self._object_frames[self._current_object_type].selected_id)
|
||||
return result
|
||||
|
||||
def on_add(self,button=None):
|
||||
self.emit('add-object',self.get_result())
|
||||
def on_add(self,widget=None,object=None):
|
||||
self.emit('add-object',object)
|
||||
|
||||
def on_selection_changed(self,widget,text,handle):
|
||||
if handle:
|
||||
|
@ -44,28 +44,33 @@ class PersonFilterFrame(FilterFrameBase):
|
||||
def __init__(self,filter_spec=None,label="Filter"):
|
||||
FilterFrameBase.__init__(self,filter_spec,label)
|
||||
|
||||
self._checkboxes = []
|
||||
|
||||
# Gramps ID
|
||||
self._id_check = gtk.CheckButton()
|
||||
self._checkboxes.append(self._id_check)
|
||||
id_label = gtk.Label("Gramps ID")
|
||||
id_label.set_alignment(xalign=0,yalign=0.5)
|
||||
|
||||
self._id_edit = gtk.Entry()
|
||||
self._id_edit.set_sensitive(False)
|
||||
|
||||
self._id_check.connect('toggled',lambda b: self._id_edit.set_sensitive(self._id_check.get_active()))
|
||||
|
||||
# Name
|
||||
self._name_check = gtk.CheckButton()
|
||||
self._checkboxes.append(self._name_check)
|
||||
|
||||
name_label = gtk.Label("Name")
|
||||
name_label.set_alignment(xalign=0,yalign=0.5)
|
||||
|
||||
self._name_edit = gtk.Entry()
|
||||
self._name_edit.set_sensitive(False)
|
||||
|
||||
self._name_check.connect('toggled',lambda b: self._name_edit.set_sensitive(self._name_check.get_active()))
|
||||
|
||||
# Gender
|
||||
self._gender_check = gtk.CheckButton()
|
||||
self._checkboxes.append(self._gender_check)
|
||||
|
||||
gender_label = gtk.Label("Gender")
|
||||
gender_label.set_alignment(xalign=0,yalign=0.5)
|
||||
|
||||
@ -85,29 +90,26 @@ class PersonFilterFrame(FilterFrameBase):
|
||||
self._gender_combo.pack_start(label_cell, True)
|
||||
self._gender_combo.add_attribute(label_cell, 'text', 0)
|
||||
self._gender_combo.set_active(2)
|
||||
self._gender_combo.set_sensitive(False)
|
||||
|
||||
self._gender_check.connect('toggled',lambda b: self._gender_combo.set_sensitive(self._gender_check.get_active()))
|
||||
|
||||
# Birth
|
||||
self._birth_check = gtk.CheckButton()
|
||||
self._birth_check.set_alignment(xalign=0,yalign=0)
|
||||
self._checkboxes.append(self._birth_check)
|
||||
|
||||
|
||||
b_label = gtk.Label("Birth Year")
|
||||
b_label.set_alignment(xalign=0,yalign=0)
|
||||
|
||||
self._b_edit = IntEdit()
|
||||
self._b_edit.set_sensitive(False)
|
||||
|
||||
self._b_before = gtk.RadioButton(group=None,label="Before")
|
||||
self._b_before.set_sensitive(False)
|
||||
|
||||
self._b_after = gtk.RadioButton(self._b_before,"After")
|
||||
self._b_after.set_sensitive(False)
|
||||
self._b_before.set_active(True)
|
||||
|
||||
self._b_unknown = gtk.CheckButton("Include Unknown")
|
||||
self._b_unknown.set_sensitive(False)
|
||||
self._b_unknown.set_active(False)
|
||||
|
||||
self._birth_check.connect('toggled',lambda b: self._b_edit.set_sensitive(self._birth_check.get_active()))
|
||||
@ -122,24 +124,20 @@ class PersonFilterFrame(FilterFrameBase):
|
||||
# Death
|
||||
|
||||
self._death_check = gtk.CheckButton()
|
||||
self._checkboxes.append(self._death_check)
|
||||
|
||||
|
||||
d_label = gtk.Label("Death Year")
|
||||
d_label.set_alignment(xalign=0,yalign=0)
|
||||
|
||||
self._d_edit = IntEdit()
|
||||
self._d_edit.set_sensitive(False)
|
||||
|
||||
self._d_before = gtk.RadioButton(group=None,label="Before")
|
||||
self._d_before.set_sensitive(False)
|
||||
|
||||
self._d_after = gtk.RadioButton(self._d_before,"After")
|
||||
self._d_after.set_sensitive(False)
|
||||
|
||||
self._d_before.set_active(True)
|
||||
self._d_before.set_sensitive(False)
|
||||
|
||||
self._d_unknown = gtk.CheckButton("Include Unknown")
|
||||
self._d_unknown.set_sensitive(False)
|
||||
self._d_unknown.set_active(False)
|
||||
|
||||
self._death_check.connect('toggled',lambda b: self._d_edit.set_sensitive(self._death_check.get_active()))
|
||||
@ -153,6 +151,8 @@ class PersonFilterFrame(FilterFrameBase):
|
||||
|
||||
# Filter
|
||||
self._filter_check = gtk.CheckButton()
|
||||
self._checkboxes.append(self._filter_check)
|
||||
|
||||
filter_label = gtk.Label("Filter")
|
||||
filter_label.set_alignment(xalign=0,yalign=0.5)
|
||||
|
||||
@ -196,15 +196,12 @@ class PersonFilterFrame(FilterFrameBase):
|
||||
self._filter_combo.pack_start(label_cell, True)
|
||||
self._filter_combo.add_attribute(label_cell, 'text', 1)
|
||||
self._filter_combo.set_active(0)
|
||||
self._filter_combo.set_sensitive(False)
|
||||
|
||||
self._filter_check.connect('toggled',lambda b: self._filter_combo.set_sensitive(self._filter_check.get_active()))
|
||||
|
||||
self._filter_entry_label = gtk.Label()
|
||||
self._filter_entry_label.set_sensitive(False)
|
||||
|
||||
self._filter_entry_edit = gtk.Entry()
|
||||
self._filter_entry_edit.set_sensitive(False)
|
||||
|
||||
# table layout
|
||||
|
||||
@ -279,9 +276,30 @@ class PersonFilterFrame(FilterFrameBase):
|
||||
self._table.attach(self._filter_combo,self._control_col,self._control_col+1,
|
||||
current_row,current_row+1,xoptions=gtk.EXPAND|gtk.FILL,yoptions=False)
|
||||
|
||||
self._reset_widgets()
|
||||
|
||||
if filter_spec is not None:
|
||||
self._set_filter(filter_spec)
|
||||
|
||||
def _reset_widgets(self):
|
||||
self._id_edit.set_sensitive(False)
|
||||
self._name_edit.set_sensitive(False)
|
||||
self._gender_combo.set_sensitive(False)
|
||||
self._b_edit.set_sensitive(False)
|
||||
self._b_before.set_sensitive(False)
|
||||
self._b_after.set_sensitive(False)
|
||||
self._b_unknown.set_sensitive(False)
|
||||
self._d_edit.set_sensitive(False)
|
||||
self._d_after.set_sensitive(False)
|
||||
self._d_before.set_sensitive(False)
|
||||
self._d_unknown.set_sensitive(False)
|
||||
self._filter_combo.set_sensitive(False)
|
||||
self._filter_entry_label.set_sensitive(False)
|
||||
self._filter_entry_edit.set_sensitive(False)
|
||||
for check in self._checkboxes:
|
||||
check.set_active(False)
|
||||
|
||||
|
||||
|
||||
def _set_filter(self,filter_spec):
|
||||
if filter_spec.include_gramps_id():
|
||||
@ -339,6 +357,9 @@ class PersonFilterFrame(FilterFrameBase):
|
||||
self._death_check.set_active(False)
|
||||
self._d_edit.set_text("")
|
||||
|
||||
def on_clear(self,button=None):
|
||||
self._reset_widgets()
|
||||
self.emit('clear-filter')
|
||||
|
||||
def on_apply(self,button=None):
|
||||
filter = GenericFilter.GenericFilter()
|
||||
|
@ -29,12 +29,15 @@ import gobject
|
||||
|
||||
from RelLib import Person
|
||||
from EditPerson import EditPerson
|
||||
from NameDisplay import displayer
|
||||
display_name = displayer.display
|
||||
|
||||
from _ObjectFrameBase import ObjectFrameBase
|
||||
from _PersonFilterFrame import PersonFilterFrame
|
||||
from _PersonPreviewFrame import PersonPreviewFrame
|
||||
from _PersonTreeFrame import PersonTreeFrame
|
||||
|
||||
|
||||
class PersonFrame(ObjectFrameBase):
|
||||
|
||||
__gproperties__ = {}
|
||||
@ -47,7 +50,7 @@ class PersonFrame(ObjectFrameBase):
|
||||
|
||||
'add-object': (gobject.SIGNAL_RUN_LAST,
|
||||
gobject.TYPE_NONE,
|
||||
())
|
||||
(gobject.TYPE_PYOBJECT,))
|
||||
|
||||
}
|
||||
|
||||
@ -67,30 +70,40 @@ class PersonFrame(ObjectFrameBase):
|
||||
|
||||
def handle_selection(treeselection):
|
||||
(model, iter) = treeselection.get_selected()
|
||||
if iter and model.get_value(iter,1):
|
||||
self.emit('selection-changed', "%s [%s]" % (
|
||||
str(model.get_value(iter,0)),
|
||||
str(model.get_value(iter,1))),
|
||||
model.get_value(iter,1))
|
||||
if iter:
|
||||
(person,rowref) = model.get_value(iter,0)
|
||||
if len(rowref) > 1 or model.is_list():
|
||||
if person:
|
||||
self.emit('selection-changed', "%s [%s]" % (
|
||||
display_name(person),
|
||||
person.get_gramps_id()),
|
||||
person.get_handle())
|
||||
else:
|
||||
self.emit('selection-changed',"No Selection","")
|
||||
else:
|
||||
self.emit('selection-changed',"No Selection","")
|
||||
else:
|
||||
self.emit('selection-changed',"No Selection","")
|
||||
|
||||
|
||||
self._tree_frame.get_selection().connect('changed',handle_selection)
|
||||
self._tree_frame.get_selection().connect('changed',self.set_preview,self.__class__.__person_id_field)
|
||||
self._tree_frame.get_selection().connect('changed',self.set_preview)
|
||||
self._tree_frame.get_tree().connect('row-activated',self._on_row_activated)
|
||||
|
||||
self._filter_frame.connect('apply-filter',lambda w,m: self._tree_frame.set_model(m))
|
||||
self._filter_frame.connect('clear-filter',lambda w: self._tree_frame.set_model(None))
|
||||
|
||||
# Now that the filter is connected we need to tell it to apply any
|
||||
# filter_spec that may have been passed to it. We can't apply the filter
|
||||
# until the connections have been made.
|
||||
self._filter_frame.on_apply()
|
||||
gobject.idle_add(self._filter_frame.on_apply)
|
||||
|
||||
def _on_row_activated(self,widget,path,col):
|
||||
(model, iter) = widget.get_selection().get_selected()
|
||||
if iter and model.get_value(iter,self.__class__.__person_id_field):
|
||||
self.emit('add-object')
|
||||
if iter:
|
||||
(o,rowref) = model.get_value(iter,0)
|
||||
if o:
|
||||
self.emit('add-object',o)
|
||||
|
||||
def new_object(self,button):
|
||||
person = Person()
|
||||
|
@ -130,13 +130,9 @@ class PersonPreviewFrame(gtk.Frame):
|
||||
escape(short(psrc.get_title())))
|
||||
|
||||
return s
|
||||
|
||||
def set_object_from_id(self,id):
|
||||
try:
|
||||
person = self._dbstate.db.get_person_from_gramps_id(id)
|
||||
if not person:
|
||||
return
|
||||
|
||||
def set_object(self,person):
|
||||
try:
|
||||
image_list = person.get_media_list()
|
||||
if image_list:
|
||||
mobj = self._dbstate.db.get_object_from_handle(image_list[0].ref)
|
||||
@ -152,6 +148,12 @@ class PersonPreviewFrame(gtk.Frame):
|
||||
log.warn("Failed to generate preview for person", exc_info=True)
|
||||
self.clear_object()
|
||||
|
||||
def set_object_from_id(self,id):
|
||||
person = self._dbstate.db.get_person_from_gramps_id(id)
|
||||
if person:
|
||||
self.set_object(person)
|
||||
|
||||
|
||||
def clear_object(self):
|
||||
self._image.set_from_file(os.path.join(const.rootDir,"person.svg"))
|
||||
self._label.set_markup("")
|
||||
|
@ -25,7 +25,9 @@ from gettext import gettext as _
|
||||
import gtk
|
||||
import gobject
|
||||
|
||||
from PeopleModel import PeopleModel
|
||||
#from PeopleModel import PeopleModel
|
||||
from TreeViews import PersonTreeView
|
||||
|
||||
import NameDisplay
|
||||
|
||||
column_names = [
|
||||
@ -60,32 +62,12 @@ class PersonTreeFrame(gtk.Frame):
|
||||
self._model = None
|
||||
self._data_filter = None
|
||||
|
||||
self._tree = gtk.TreeView()
|
||||
self._tree = PersonTreeView(dbstate.db)
|
||||
self._tree.set_rules_hint(True)
|
||||
self._tree.set_headers_visible(True)
|
||||
#self._tree.connect('key-press-event',self.key_press)
|
||||
|
||||
self._tree.connect('row-activated',self._on_row_activated)
|
||||
|
||||
|
||||
renderer = gtk.CellRendererText()
|
||||
|
||||
column = gtk.TreeViewColumn(_('Name'), renderer,text=0)
|
||||
column.set_resizable(True)
|
||||
column.set_min_width(225)
|
||||
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
|
||||
self._tree.append_column(column)
|
||||
|
||||
for pair in self._dbstate.db.get_person_column_order():
|
||||
if not pair[0]:
|
||||
continue
|
||||
name = column_names[pair[1]]
|
||||
column = gtk.TreeViewColumn(name, renderer, markup=pair[1])
|
||||
column.set_resizable(True)
|
||||
column.set_min_width(60)
|
||||
column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY)
|
||||
self._tree.append_column(column)
|
||||
|
||||
scrollwindow = gtk.ScrolledWindow()
|
||||
scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
scrollwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
|
||||
@ -106,113 +88,20 @@ class PersonTreeFrame(gtk.Frame):
|
||||
|
||||
def change_db(self,db):
|
||||
self.set_model()
|
||||
db.connect('person-add', self.person_added)
|
||||
db.connect('person-update', self.person_updated)
|
||||
db.connect('person-delete', self.person_removed)
|
||||
|
||||
def set_model(self,data_filter=None):
|
||||
|
||||
self._model = PeopleModel(self._dbstate.db,data_filter=data_filter)
|
||||
|
||||
self._tree.set_model(self._model)
|
||||
|
||||
if data_filter is None:
|
||||
self._tree.get_selection().unselect_all()
|
||||
self._tree.clear_filter()
|
||||
else:
|
||||
self._tree.set_filter(data_filter)
|
||||
|
||||
self._selection = self._tree.get_selection()
|
||||
|
||||
# expand the first row so that the tree is a sensible size.
|
||||
self._tree.expand_row((0,),False)
|
||||
|
||||
def person_added(self,handle_list):
|
||||
for node in handle_list:
|
||||
person = self._dbstate.db.get_person_from_handle(node)
|
||||
top = NameDisplay.displayer.name_grouping(self._dbstate.db,person)
|
||||
self._model.rebuild_data(self._data_filter)
|
||||
if not self._model.is_visable(node):
|
||||
continue
|
||||
if (not self._model.sname_sub.has_key(top) or
|
||||
len(self._model.sname_sub[top]) == 1):
|
||||
path = self._model.on_get_path(top)
|
||||
pnode = self._model.get_iter(path)
|
||||
self._model.row_inserted(path,pnode)
|
||||
path = self._model.on_get_path(node)
|
||||
pnode = self._model.get_iter(path)
|
||||
self._model.row_inserted(path,pnode)
|
||||
self._tree.expand_to_path(path)
|
||||
self._tree.set_cursor(path)
|
||||
|
||||
def person_removed(self,handle_list):
|
||||
for node in handle_list:
|
||||
person = self._dbstate.db.get_person_from_handle(node)
|
||||
if not self._model.is_visable(node):
|
||||
continue
|
||||
top = NameDisplay.displayer.name_grouping(self._dbstate.db,person)
|
||||
mylist = self._model.sname_sub.get(top,[])
|
||||
if mylist:
|
||||
try:
|
||||
path = self._model.on_get_path(node)
|
||||
self._model.row_deleted(path)
|
||||
if len(mylist) == 1:
|
||||
path = self._model.on_get_path(top)
|
||||
self._model.row_deleted(path)
|
||||
except KeyError:
|
||||
pass
|
||||
self._model.rebuild_data(self.DataFilter,skip=node)
|
||||
|
||||
def person_updated(self,handle_list):
|
||||
for node in handle_list:
|
||||
person = self._dbstate.db.get_person_from_handle(node)
|
||||
try:
|
||||
oldpath = self._model.iter2path[node]
|
||||
except:
|
||||
return
|
||||
pathval = self._model.on_get_path(node)
|
||||
pnode = self._model.get_iter(pathval)
|
||||
|
||||
# calculate the new data
|
||||
|
||||
surname = NameDisplay.displayer.name_grouping(self._dbstate.db,person)
|
||||
|
||||
if oldpath[0] == surname:
|
||||
self._model.build_sub_entry(surname)
|
||||
else:
|
||||
self._model.calculate_data(self.DataFilter)
|
||||
|
||||
# find the path of the person in the new data build
|
||||
newpath = self._model.temp_iter2path[node]
|
||||
|
||||
# if paths same, just issue row changed signal
|
||||
|
||||
if oldpath == newpath:
|
||||
self._model.row_changed(pathval,pnode)
|
||||
else:
|
||||
# paths different, get the new surname list
|
||||
|
||||
mylist = self._model.temp_sname_sub.get(oldpath[0],[])
|
||||
path = self._model.on_get_path(node)
|
||||
|
||||
# delete original
|
||||
self._model.row_deleted(pathval)
|
||||
|
||||
# delete top node of original if necessar
|
||||
if len(mylist)==0:
|
||||
self._model.row_deleted(pathval[0])
|
||||
|
||||
# determine if we need to insert a new top node',
|
||||
insert = not self._model.sname_sub.has_key(newpath[0])
|
||||
|
||||
# assign new data
|
||||
self._model.assign_data()
|
||||
|
||||
# insert new row if needed
|
||||
if insert:
|
||||
path = self._model.on_get_path(newpath[0])
|
||||
pnode = self._model.get_iter(path)
|
||||
self._model.row_inserted(path,pnode)
|
||||
|
||||
# insert new person
|
||||
path = self._model.on_get_path(node)
|
||||
pnode = self._model.get_iter(path)
|
||||
self._model.row_inserted(path,pnode)
|
||||
|
||||
def get_selection(self):
|
||||
return self._selection
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
from gettext import gettext as _
|
||||
import cgi
|
||||
|
||||
import gtk
|
||||
|
||||
@ -7,6 +8,8 @@ from Models import \
|
||||
PersonTreeModel, PersonListModel, PersonFilterModel
|
||||
|
||||
from NameDisplay import displayer
|
||||
from RelLib import Event
|
||||
import DateHandler
|
||||
import Utils
|
||||
|
||||
display_given = displayer.display_given
|
||||
@ -66,21 +69,24 @@ class PersonTreeView(gtk.TreeView):
|
||||
|
||||
def _object_id(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
if len(rowref) > 1:
|
||||
if ( len(rowref) > 1 or model.is_list() )and o is not None:
|
||||
cell.set_property('text', o.get_gramps_id())
|
||||
else:
|
||||
cell.set_property('text', "")
|
||||
|
||||
def _family_name(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
if len(rowref) > 1:
|
||||
cell.set_property('text', displayer(o))
|
||||
if (len(rowref) > 1 or model.is_list()) and o is not None:
|
||||
cell.set_property('text', "%s, %s"% (o.get_primary_name().surname,
|
||||
display_given(o)))
|
||||
elif o is not None:
|
||||
cell.set_property('text',o.get_primary_name().surname)
|
||||
else:
|
||||
cell.set_property('text',o.primary_name.surname)
|
||||
cell.set_property('text','')
|
||||
|
||||
def _gender(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
if len(rowref) > 1:
|
||||
if (len(rowref) > 1 or model.is_list()) and o is not None:
|
||||
cell.set_property('text', Utils.gender[o.gender])
|
||||
else:
|
||||
cell.set_property('text', "")
|
||||
@ -88,62 +94,62 @@ class PersonTreeView(gtk.TreeView):
|
||||
def _birth_date(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
cell_value = ''
|
||||
if len(rowref) > 1:
|
||||
if (len(rowref) > 1 or model.is_list()) and o is not None:
|
||||
b = o.get_birth_ref()
|
||||
if b:
|
||||
birth = self.db.get_event_from_handle(b.ref)
|
||||
birth = self._db.get_event_from_handle(b.ref)
|
||||
date_str = DateHandler.get_date(birth)
|
||||
if date_str != "":
|
||||
cell_value = cgi.escape(date_str)
|
||||
else:
|
||||
for er in o.get_event_ref_list():
|
||||
event = self.db.get_event_from_handle(er.ref)
|
||||
event = self._db.get_event_from_handle(er.ref)
|
||||
etype = event.get_type()[0]
|
||||
date_str = DateHandler.get_date(event)
|
||||
if (etype in [Event.BAPTISM, Event.CHRISTEN]
|
||||
and date_str != ""):
|
||||
return
|
||||
cell_value = "<i>" + cgi.escape(date_str) + "</i>"
|
||||
cell.set_property('text', cell_value)
|
||||
cell.set_property('markup', cell_value)
|
||||
|
||||
def _birth_place(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
if len(rowref) > 1:
|
||||
if (len(rowref) > 1 or model.is_list()) and o is not None:
|
||||
cell.set_property('text', "")
|
||||
else:
|
||||
cell.set_property('text', "")
|
||||
|
||||
def _death_date(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
if len(rowref) > 1:
|
||||
if (len(rowref) > 1 or model.is_list()) and o is not None:
|
||||
cell.set_property('text', "")
|
||||
else:
|
||||
cell.set_property('text', "")
|
||||
|
||||
def _death_place(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
if len(rowref) > 1:
|
||||
if (len(rowref) > 1 or model.is_list()) and o is not None:
|
||||
cell.set_property('text', "")
|
||||
else:
|
||||
cell.set_property('text', "")
|
||||
|
||||
def _last_change(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
if len(rowref) > 1:
|
||||
if (len(rowref) > 1 or model.is_list()) and o is not None:
|
||||
cell.set_property('text', "")
|
||||
else:
|
||||
cell.set_property('text', "")
|
||||
|
||||
def _death_cause(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
if len(rowref) > 1:
|
||||
if (len(rowref) > 1 or model.is_list()) and o is not None:
|
||||
cell.set_property('text', "")
|
||||
else:
|
||||
cell.set_property('text', "")
|
||||
|
||||
def _spouce(self, column, cell, model, iter, user_data=None):
|
||||
(o,rowref) = model.get_value(iter, 0)
|
||||
if len(rowref) > 1:
|
||||
if (len(rowref) > 1 or model.is_list()) and o is not None:
|
||||
cell.set_property('text', "")
|
||||
else:
|
||||
cell.set_property('text', "")
|
||||
|
Loading…
Reference in New Issue
Block a user