2008-02-14 Raphael Ackermann <raphael.ackermann@gmail.com>
* src/ObjectSelector/* : #1744: src/ObjectSelector is not used anmyore * src/TreeViews/* : #1744: src/TreeViews is not used anmyore * src/Treetips.py : changed class comment. pep8 fix for doc: ''' --> """ * src/plugins/SoundGen.py: remove ... in menu. imports cleanup svn: r10033
This commit is contained in:
parent
6050aa8c3d
commit
311aa7b15d
@ -1,3 +1,9 @@
|
|||||||
|
2008-02-14 Raphael Ackermann <raphael.ackermann@gmail.com>
|
||||||
|
* src/ObjectSelector/* : #1744: src/ObjectSelector is not used anmyore
|
||||||
|
* src/TreeViews/* : #1744: src/TreeViews is not used anmyore
|
||||||
|
* src/Treetips.py : changed class comment. pep8 fix for doc: ''' --> """
|
||||||
|
* src/plugins/SoundGen.py: remove ... in menu. imports cleanup
|
||||||
|
|
||||||
2008-02-14 Peter Landgren <peter.talken@telia.com>
|
2008-02-14 Peter Landgren <peter.talken@telia.com>
|
||||||
* src/plugins/DefaultGramplets.py: fixed two strings to be translatabel
|
* src/plugins/DefaultGramplets.py: fixed two strings to be translatabel
|
||||||
|
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
# This is the src/RelLib level Makefile for Gramps
|
|
||||||
# We could use GNU make's ':=' syntax for nice wildcard use,
|
|
||||||
# but that is not necessarily portable.
|
|
||||||
# If not using GNU make, then list all .py files individually
|
|
||||||
|
|
||||||
pkgdatadir = $(datadir)/@PACKAGE@/ObjectSelector
|
|
||||||
|
|
||||||
pkgdata_PYTHON = \
|
|
||||||
_Constants.py\
|
|
||||||
_Factories.py\
|
|
||||||
_FamilyFilterFrame.py\
|
|
||||||
_FamilyFrame.py\
|
|
||||||
_FamilyPreviewFrame.py\
|
|
||||||
_FamilyTreeFrame.py\
|
|
||||||
_FilterFrameBase.py\
|
|
||||||
_FilterSpecBase.py\
|
|
||||||
__init__.py\
|
|
||||||
_ObjectFrameBase.py\
|
|
||||||
_ObjectSelectorWindow.py\
|
|
||||||
_PersonFilterFrame.py\
|
|
||||||
_PersonFilterSpec.py\
|
|
||||||
_PersonFrame.py\
|
|
||||||
_PersonPreviewFrame.py\
|
|
||||||
_PersonTreeFrame.py\
|
|
||||||
_PreviewFrameBase.py\
|
|
||||||
_TreeFrameBase.py
|
|
||||||
|
|
||||||
pkgpyexecdir = @pkgpyexecdir@/ObjectSelector
|
|
||||||
pkgpythondir = @pkgpythondir@/ObjectSelector
|
|
||||||
|
|
||||||
# Clean up all the byte-compiled files
|
|
||||||
MOSTLYCLEANFILES = *pyc *pyo
|
|
||||||
|
|
||||||
GRAMPS_PY_MODPATH = "../"
|
|
||||||
|
|
||||||
pycheck:
|
|
||||||
(export PYTHONPATH=$(GRAMPS_PY_MODPATH); \
|
|
||||||
pychecker $(pkgdata_PYTHON));
|
|
@ -1,33 +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$
|
|
||||||
|
|
||||||
|
|
||||||
class ObjectTypes(object):
|
|
||||||
|
|
||||||
PERSON = 0
|
|
||||||
FAMILY = 1
|
|
||||||
SOURCE = 2
|
|
||||||
EVENT = 3
|
|
||||||
MEDIA = 4
|
|
||||||
PLACE = 5
|
|
||||||
REPOSITORY = 6
|
|
||||||
REFERENCE = 7
|
|
@ -1,36 +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$
|
|
||||||
|
|
||||||
from _Constants import ObjectTypes
|
|
||||||
|
|
||||||
from _PersonFrame import PersonFrame
|
|
||||||
from _FamilyFrame import FamilyFrame
|
|
||||||
|
|
||||||
|
|
||||||
class ObjectFrameFactory(object):
|
|
||||||
__frame_creators = {ObjectTypes.PERSON: PersonFrame,
|
|
||||||
ObjectTypes.FAMILY: FamilyFrame}
|
|
||||||
|
|
||||||
def get_frame(self,object_type,dbstate,uistate,filter_spec=None):
|
|
||||||
return self.__class__.__frame_creators[object_type](dbstate,uistate,filter_spec)
|
|
||||||
|
|
||||||
|
|
@ -1,91 +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$
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
|
|
||||||
from GrampsWidgets import IntEdit
|
|
||||||
from _FilterFrameBase import FilterFrameBase
|
|
||||||
|
|
||||||
class FamilyFilterFrame(FilterFrameBase):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
}
|
|
||||||
|
|
||||||
__default_border_width = 5
|
|
||||||
|
|
||||||
def __init__(self,filter_spec=None,label="Filter"):
|
|
||||||
FilterFrameBase.__init__(self,filter_spec,label)
|
|
||||||
|
|
||||||
# Gramps ID
|
|
||||||
self._id_check,self._id_label,self._id_edit = \
|
|
||||||
self.make_text_widget("Gramps ID")
|
|
||||||
|
|
||||||
# Name
|
|
||||||
self._name_check,self._name_label,self._name_edit = \
|
|
||||||
self.make_text_widget("Name")
|
|
||||||
|
|
||||||
# Mar
|
|
||||||
self._mar_check, self._m_edit, \
|
|
||||||
self._m_before, self._m_after, \
|
|
||||||
self._m_unknown = self.make_year_widget("Marriage Year")
|
|
||||||
|
|
||||||
# Filter
|
|
||||||
default_filters = []
|
|
||||||
|
|
||||||
# don't currently support filters that need an attribute.
|
|
||||||
filters = [ filter for filter in default_filters if \
|
|
||||||
not hasattr(filter,'labels') or len(filter.labels) == 0 ]
|
|
||||||
|
|
||||||
self._filter_list = gtk.ListStore(gobject.TYPE_STRING, object)
|
|
||||||
|
|
||||||
for filter in filters:
|
|
||||||
self._filter_list.append([filter.name,filter])
|
|
||||||
|
|
||||||
self._filter_check,self._filter_label,self._filter_combo = \
|
|
||||||
self.make_combo_widget("Filter",self._filter_list)
|
|
||||||
|
|
||||||
self._reset_widgets()
|
|
||||||
|
|
||||||
if filter_spec is not None:
|
|
||||||
self._set_filter(filter_spec)
|
|
||||||
|
|
||||||
|
|
||||||
def _set_filter(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def on_apply(self,button):
|
|
||||||
pass
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(FamilyFilterFrame)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
w = gtk.Window()
|
|
||||||
f = FamilyFilterFrame()
|
|
||||||
w.add(f)
|
|
||||||
w.show_all()
|
|
||||||
|
|
||||||
gtk.main()
|
|
@ -1,97 +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$
|
|
||||||
|
|
||||||
#for debug, remove later
|
|
||||||
import sys
|
|
||||||
sys.path.append("..")
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
|
|
||||||
from _ObjectFrameBase import ObjectFrameBase
|
|
||||||
from _FamilyFilterFrame import FamilyFilterFrame
|
|
||||||
from _FamilyPreviewFrame import FamilyPreviewFrame
|
|
||||||
from _FamilyTreeFrame import FamilyTreeFrame
|
|
||||||
|
|
||||||
class FamilyFrame(ObjectFrameBase):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
'selection-changed' : (gobject.SIGNAL_RUN_LAST,
|
|
||||||
gobject.TYPE_NONE,
|
|
||||||
(gobject.TYPE_STRING,
|
|
||||||
gobject.TYPE_STRING)),
|
|
||||||
|
|
||||||
'add-object': (gobject.SIGNAL_RUN_LAST,
|
|
||||||
gobject.TYPE_NONE,
|
|
||||||
())
|
|
||||||
}
|
|
||||||
|
|
||||||
__person_id_field = 0
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
dbstate,
|
|
||||||
uistate,
|
|
||||||
filter_spec=None):
|
|
||||||
|
|
||||||
ObjectFrameBase.__init__(self,
|
|
||||||
dbstate=dbstate,
|
|
||||||
uistate=uistate,
|
|
||||||
filter_frame = FamilyFilterFrame(filter_spec=filter_spec),
|
|
||||||
preview_frame = FamilyPreviewFrame(dbstate),
|
|
||||||
tree_frame = FamilyTreeFrame(dbstate))
|
|
||||||
|
|
||||||
|
|
||||||
self._tree_frame.get_selection().connect('changed',self._handle_selection)
|
|
||||||
self._tree_frame.get_selection().connect('changed',self.set_preview,self.__class__.__person_id_field)
|
|
||||||
self._tree_frame.get_tree().connect('row-activated',self._on_row_activated)
|
|
||||||
|
|
||||||
def new_object(self,button):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _handle_selection(self,treeselection):
|
|
||||||
(model, iter) = treeselection.get_selected()
|
|
||||||
if iter and model.get_value(iter,self.__class__.__person_id_field):
|
|
||||||
self.emit('selection-changed', "%s / %s [%s]" % (
|
|
||||||
str(model.get_value(iter,1)),
|
|
||||||
str(model.get_value(iter,2)),
|
|
||||||
str(model.get_value(iter,0))),
|
|
||||||
model.get_value(iter,self.__class__.__person_id_field))
|
|
||||||
else:
|
|
||||||
self.emit('selection-changed',"No Selection","")
|
|
||||||
|
|
||||||
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 gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(FamilyFrame)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
pass
|
|
@ -1,126 +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$
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
from logging import getLogger
|
|
||||||
log = getLogger(".ObjectSelector")
|
|
||||||
|
|
||||||
import ImgManip
|
|
||||||
import const
|
|
||||||
|
|
||||||
from _PreviewFrameBase import PreviewFrameBase
|
|
||||||
|
|
||||||
class FamilyPreviewFrame(PreviewFrameBase):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
}
|
|
||||||
|
|
||||||
__default_border_width = 5
|
|
||||||
|
|
||||||
def __init__(self,dbstate,label="Preview"):
|
|
||||||
PreviewFrameBase.__init__(self,label)
|
|
||||||
self._dbstate = dbstate
|
|
||||||
align = gtk.Alignment()
|
|
||||||
|
|
||||||
# Image
|
|
||||||
self._image_l = gtk.Image()
|
|
||||||
self._image_r = gtk.Image()
|
|
||||||
|
|
||||||
image_box = gtk.HBox()
|
|
||||||
image_box.pack_start(self._image_l)
|
|
||||||
image_box.pack_start(self._image_r)
|
|
||||||
|
|
||||||
# Text
|
|
||||||
label = gtk.Label()
|
|
||||||
label.set_use_markup(True)
|
|
||||||
label.set_line_wrap(True)
|
|
||||||
label.set_justify(gtk.JUSTIFY_LEFT)
|
|
||||||
label.set_alignment(xalign=0.1,yalign=0.1)
|
|
||||||
label.set_markup("<b>Father:</b> Joe Blogs\n"
|
|
||||||
"<b>Mother:</b> Joe Blogs\n"
|
|
||||||
"<b>m:</b> 1906\n")
|
|
||||||
|
|
||||||
# box
|
|
||||||
box = gtk.VBox()
|
|
||||||
box.pack_start(image_box,False,False)
|
|
||||||
box.pack_start(label)
|
|
||||||
|
|
||||||
# align
|
|
||||||
|
|
||||||
align.add(box)
|
|
||||||
align.set_padding(self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width)
|
|
||||||
align.set(0.5,0.5,
|
|
||||||
1.0,1.0)
|
|
||||||
|
|
||||||
self.add(align)
|
|
||||||
|
|
||||||
self.clear_object()
|
|
||||||
|
|
||||||
def set_object_from_id(self,id):
|
|
||||||
try:
|
|
||||||
family = self._dbstate.db.get_family_from_gramps_id(id)
|
|
||||||
|
|
||||||
image = [self._image_l, self._image_r]
|
|
||||||
image_no = 0
|
|
||||||
for person_handle in (family.get_father_handle(),family.get_mother_handle()):
|
|
||||||
person = self._dbstate.db.get_person_from_handle(person_handle)
|
|
||||||
if not person:
|
|
||||||
return
|
|
||||||
|
|
||||||
image_list = person.get_media_list()
|
|
||||||
if image_list:
|
|
||||||
mobj = self._dbstate.db.get_object_from_handle(image_list[0].ref)
|
|
||||||
if mobj.get_mime_type()[0:5] == "image":
|
|
||||||
pixbuf = ImgManip.get_thumbnail_image(mobj.get_path())
|
|
||||||
image[image_no].set_from_pixbuf(pixbuf)
|
|
||||||
image_no += 1
|
|
||||||
else:
|
|
||||||
self._image_l.set_from_file(os.path.join(const.IMAGE_DIR,"person.svg"))
|
|
||||||
self._image_r.set_from_file(os.path.join(const.IMAGE_DIR,"person.svg"))
|
|
||||||
|
|
||||||
except:
|
|
||||||
log.warn("Failed to generate preview for family", exc_info=True)
|
|
||||||
self.clear_object()
|
|
||||||
|
|
||||||
def clear_object(self):
|
|
||||||
self._image_l.set_from_file(os.path.join(const.IMAGE_DIR,"person.svg"))
|
|
||||||
self._image_r.set_from_file(os.path.join(const.IMAGE_DIR,"person.svg"))
|
|
||||||
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(FamilyPreviewFrame)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
w = gtk.Window()
|
|
||||||
f = PersonPreviewFrame()
|
|
||||||
w.add(f)
|
|
||||||
w.show_all()
|
|
||||||
|
|
||||||
gtk.main()
|
|
@ -1,105 +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$
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
|
|
||||||
from DisplayModels import FamilyModel
|
|
||||||
|
|
||||||
from _TreeFrameBase import TreeFrameBase
|
|
||||||
|
|
||||||
class FamilyTreeFrame(TreeFrameBase):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
}
|
|
||||||
|
|
||||||
__default_border_width = 5
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self,dbstate):
|
|
||||||
TreeFrameBase.__init__(self)
|
|
||||||
|
|
||||||
self._selection = None
|
|
||||||
self._model = None
|
|
||||||
|
|
||||||
self._dbstate = dbstate
|
|
||||||
|
|
||||||
self._list = gtk.TreeView()
|
|
||||||
self._list.set_rules_hint(True)
|
|
||||||
self._list.set_headers_visible(True)
|
|
||||||
self._list.set_headers_clickable(True)
|
|
||||||
|
|
||||||
#self._list.connect('button-press-event',self._button_press)
|
|
||||||
#self._list.connect('key-press-event',self._key_press)
|
|
||||||
|
|
||||||
# Add columns
|
|
||||||
columns = [['ID',0],
|
|
||||||
['Father',1],
|
|
||||||
['Mother',2],
|
|
||||||
['Type',3],
|
|
||||||
['Change',4]]
|
|
||||||
|
|
||||||
for field in columns:
|
|
||||||
column = gtk.TreeViewColumn(field[0], gtk.CellRendererText(), text=field[1])
|
|
||||||
column.set_resizable(True)
|
|
||||||
column.set_min_width(75)
|
|
||||||
column.set_clickable(True)
|
|
||||||
self._list.append_column(column)
|
|
||||||
|
|
||||||
scrollwindow = gtk.ScrolledWindow()
|
|
||||||
scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
|
||||||
scrollwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
|
|
||||||
|
|
||||||
scrollwindow.add(self._list)
|
|
||||||
|
|
||||||
self._selection = self._list.get_selection()
|
|
||||||
|
|
||||||
self.add(scrollwindow)
|
|
||||||
|
|
||||||
self.set_model(self._dbstate.db)
|
|
||||||
|
|
||||||
def set_model(self,db):
|
|
||||||
|
|
||||||
self._model = FamilyModel(db)
|
|
||||||
|
|
||||||
self._list.set_model(self._model)
|
|
||||||
|
|
||||||
self._selection = self._list.get_selection()
|
|
||||||
|
|
||||||
def get_selection(self):
|
|
||||||
return self._selection
|
|
||||||
|
|
||||||
def get_tree(self):
|
|
||||||
return self._list
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(FamilyTreeFrame)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
w = ObjectSelectorWindow()
|
|
||||||
w.show_all()
|
|
||||||
w.connect("destroy", gtk.main_quit)
|
|
||||||
|
|
||||||
gtk.main()
|
|
@ -1,247 +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$
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
|
|
||||||
from GrampsWidgets import IntEdit
|
|
||||||
|
|
||||||
class FilterFrameBase(gtk.Frame):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
'apply-filter': (gobject.SIGNAL_RUN_LAST,
|
|
||||||
gobject.TYPE_NONE,
|
|
||||||
(gobject.TYPE_PYOBJECT,)),
|
|
||||||
'clear-filter': (gobject.SIGNAL_RUN_LAST,
|
|
||||||
gobject.TYPE_NONE,
|
|
||||||
())
|
|
||||||
}
|
|
||||||
|
|
||||||
__default_border_width = 5
|
|
||||||
|
|
||||||
def __init__(self,filter_spec=None,label="Filter"):
|
|
||||||
gtk.Frame.__init__(self,label)
|
|
||||||
|
|
||||||
|
|
||||||
self._checkboxes = []
|
|
||||||
self._active_widgets = []
|
|
||||||
|
|
||||||
self._current_row = 0
|
|
||||||
|
|
||||||
self._filter_spec = filter_spec
|
|
||||||
|
|
||||||
box = gtk.EventBox()
|
|
||||||
align = gtk.Alignment()
|
|
||||||
|
|
||||||
# table layout
|
|
||||||
|
|
||||||
self._table = gtk.Table(3,6,False)
|
|
||||||
self._table.set_row_spacings(5)
|
|
||||||
self._table.set_col_spacings(5)
|
|
||||||
|
|
||||||
self._label_col = 0
|
|
||||||
self._check_col = 1
|
|
||||||
self._control_col = 2
|
|
||||||
|
|
||||||
|
|
||||||
# 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.HButtonBox()
|
|
||||||
button_box.set_layout(gtk.BUTTONBOX_SPREAD)
|
|
||||||
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(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)
|
|
||||||
|
|
||||||
align.add(outer_box)
|
|
||||||
align.set_padding(self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width)
|
|
||||||
|
|
||||||
|
|
||||||
box.add(align)
|
|
||||||
self.add(box)
|
|
||||||
|
|
||||||
|
|
||||||
def _reset_widgets(self):
|
|
||||||
for widget in self._active_widgets:
|
|
||||||
widget.set_sensitive(False)
|
|
||||||
for check in self._checkboxes:
|
|
||||||
check.set_active(False)
|
|
||||||
|
|
||||||
def on_clear(self,button=None):
|
|
||||||
self._reset_widgets()
|
|
||||||
self.emit('clear-filter')
|
|
||||||
|
|
||||||
def make_text_widget(self,widget_label):
|
|
||||||
"""create a text edit widget with a label and check box."""
|
|
||||||
|
|
||||||
check_col=self._check_col
|
|
||||||
label_col=self._label_col
|
|
||||||
control_col=self._control_col
|
|
||||||
|
|
||||||
check = gtk.CheckButton()
|
|
||||||
self._checkboxes.append(check)
|
|
||||||
|
|
||||||
label = gtk.Label(widget_label)
|
|
||||||
label.set_alignment(xalign=0,yalign=0.5)
|
|
||||||
|
|
||||||
edit = gtk.Entry()
|
|
||||||
self._active_widgets.append(edit)
|
|
||||||
|
|
||||||
check.connect('toggled',lambda b: edit.set_sensitive(check.get_active()))
|
|
||||||
|
|
||||||
self._table.attach(check,check_col,check_col+1, self._current_row,
|
|
||||||
self._current_row+1,xoptions=False,yoptions=False)
|
|
||||||
self._table.attach(label,label_col,label_col+1, self._current_row,
|
|
||||||
self._current_row+1,xoptions=gtk.FILL,
|
|
||||||
yoptions=False)
|
|
||||||
self._table.attach(edit,control_col,control_col+1, self._current_row,
|
|
||||||
self._current_row+1,xoptions=gtk.EXPAND|gtk.FILL,
|
|
||||||
yoptions=False)
|
|
||||||
self._current_row += 1
|
|
||||||
|
|
||||||
return(check,label,edit)
|
|
||||||
|
|
||||||
def make_combo_widget(self,widget_label,list_model):
|
|
||||||
"""create a combo widget with a label and check box."""
|
|
||||||
check_col=self._check_col
|
|
||||||
label_col=self._label_col
|
|
||||||
control_col=self._control_col
|
|
||||||
|
|
||||||
check = gtk.CheckButton()
|
|
||||||
self._checkboxes.append(check)
|
|
||||||
|
|
||||||
label = gtk.Label(widget_label)
|
|
||||||
label.set_alignment(xalign=0,yalign=0.5)
|
|
||||||
|
|
||||||
combo = gtk.ComboBox(list_model)
|
|
||||||
self._active_widgets.append(combo)
|
|
||||||
|
|
||||||
label_cell = gtk.CellRendererText()
|
|
||||||
|
|
||||||
combo.pack_start(label_cell, True)
|
|
||||||
combo.add_attribute(label_cell, 'text', 0)
|
|
||||||
combo.set_active(2)
|
|
||||||
|
|
||||||
check.connect('toggled',lambda b: combo.set_sensitive(check.get_active()))
|
|
||||||
|
|
||||||
self._table.attach(check,check_col,check_col+1,
|
|
||||||
self._current_row,self._current_row+1,
|
|
||||||
xoptions=False,yoptions=False)
|
|
||||||
self._table.attach(label,label_col,label_col+1, self._current_row,
|
|
||||||
self._current_row+1,xoptions=gtk.FILL,
|
|
||||||
yoptions=False)
|
|
||||||
self._table.attach(combo,control_col,control_col+1, self._current_row,
|
|
||||||
self._current_row+1,xoptions=gtk.EXPAND|gtk.FILL,
|
|
||||||
yoptions=False)
|
|
||||||
self._current_row += 1
|
|
||||||
|
|
||||||
return (check,label,combo)
|
|
||||||
|
|
||||||
def make_year_widget(self,widget_label):
|
|
||||||
"""Create a widget with a year edit entry, a before and after check box.
|
|
||||||
Including a check box to enable and disable all the widgets."""
|
|
||||||
check_col=self._check_col
|
|
||||||
label_col=self._label_col
|
|
||||||
control_col=self._control_col
|
|
||||||
|
|
||||||
check = gtk.CheckButton()
|
|
||||||
check.set_alignment(xalign=0,yalign=0)
|
|
||||||
self._checkboxes.append(check)
|
|
||||||
|
|
||||||
label = gtk.Label(widget_label)
|
|
||||||
label.set_alignment(xalign=0,yalign=0)
|
|
||||||
|
|
||||||
edit = IntEdit()
|
|
||||||
self._active_widgets.append(edit)
|
|
||||||
|
|
||||||
before = gtk.RadioButton(group=None,label="Before")
|
|
||||||
self._active_widgets.append(before)
|
|
||||||
|
|
||||||
after = gtk.RadioButton(before,"After")
|
|
||||||
self._active_widgets.append(after)
|
|
||||||
before.set_active(True)
|
|
||||||
|
|
||||||
unknown = gtk.CheckButton("Include Unknown")
|
|
||||||
self._active_widgets.append(unknown)
|
|
||||||
unknown.set_active(False)
|
|
||||||
|
|
||||||
check.connect('toggled',lambda b: edit.set_sensitive(check.get_active()))
|
|
||||||
check.connect('toggled',lambda b: before.set_sensitive(check.get_active()))
|
|
||||||
check.connect('toggled',lambda b: after.set_sensitive(check.get_active()))
|
|
||||||
#check.connect('toggled',lambda b: unknown.set_sensitive(check.get_active()))
|
|
||||||
|
|
||||||
inner_box = gtk.HBox()
|
|
||||||
inner_box.pack_start(before)
|
|
||||||
inner_box.pack_start(after)
|
|
||||||
|
|
||||||
|
|
||||||
self._table.attach(check,check_col,check_col+1, self._current_row,
|
|
||||||
self._current_row+1,xoptions=False,yoptions=False)
|
|
||||||
self._table.attach(label,label_col,label_col+1, self._current_row,
|
|
||||||
self._current_row+1,xoptions=gtk.FILL,
|
|
||||||
yoptions=False)
|
|
||||||
self._table.attach(edit,control_col,control_col+1, self._current_row,
|
|
||||||
self._current_row+1,xoptions=gtk.EXPAND|gtk.FILL,
|
|
||||||
yoptions=False)
|
|
||||||
|
|
||||||
self._current_row +=1
|
|
||||||
self._table.attach(inner_box,control_col,control_col+1,
|
|
||||||
self._current_row,self._current_row+1,
|
|
||||||
xoptions=gtk.EXPAND|gtk.FILL,yoptions=False)
|
|
||||||
|
|
||||||
self._current_row +=1
|
|
||||||
self._table.attach(unknown,control_col,control_col+1,
|
|
||||||
self._current_row,self._current_row+1,
|
|
||||||
xoptions=gtk.EXPAND|gtk.FILL,yoptions=False)
|
|
||||||
self._current_row +=1
|
|
||||||
|
|
||||||
return (check, edit, before, after, unknown)
|
|
||||||
|
|
||||||
|
|
||||||
def on_apply(self,button):
|
|
||||||
"""Build a GenericFilter object from the settings in the filter
|
|
||||||
controls and emit a 'apply-filter' signal with the GenericFilter object
|
|
||||||
as the parameter."""
|
|
||||||
|
|
||||||
raise NotImplementedError("subclass of FilterFrameBase must implement on_apply")
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(FilterFrameBase)
|
|
||||||
|
|
||||||
|
|
@ -1,36 +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$
|
|
||||||
|
|
||||||
|
|
||||||
class FilterSpecBase(object):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self._gramps_id = None
|
|
||||||
|
|
||||||
def set_gramps_id(self,gramps_id):
|
|
||||||
self._gramps_id = gramps_id
|
|
||||||
|
|
||||||
def get_gramps_id(self):
|
|
||||||
return self._gramps_id
|
|
||||||
|
|
||||||
def include_gramps_id(self):
|
|
||||||
return self._gramps_id is not None
|
|
@ -1,112 +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$
|
|
||||||
|
|
||||||
#for debug, remove later
|
|
||||||
import sys
|
|
||||||
sys.path.append("..")
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
|
|
||||||
class ObjectFrameBase(gtk.Frame):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {}
|
|
||||||
|
|
||||||
__default_border_width = 5
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
dbstate,
|
|
||||||
uistate,
|
|
||||||
filter_frame,
|
|
||||||
preview_frame,
|
|
||||||
tree_frame):
|
|
||||||
|
|
||||||
gtk.Frame.__init__(self)
|
|
||||||
|
|
||||||
self._dbstate = dbstate
|
|
||||||
self._uistate = uistate
|
|
||||||
self._filter_frame = filter_frame
|
|
||||||
self._preview_frame = preview_frame
|
|
||||||
self._tree_frame = tree_frame
|
|
||||||
|
|
||||||
self._preview_frame.set_sensitive(False)
|
|
||||||
|
|
||||||
# Create the widgets for each of the object types
|
|
||||||
|
|
||||||
vbox = gtk.VBox()
|
|
||||||
vbox.show()
|
|
||||||
|
|
||||||
vbox2 = gtk.VBox()
|
|
||||||
vbox2.show()
|
|
||||||
|
|
||||||
pane = gtk.HPaned()
|
|
||||||
pane.show()
|
|
||||||
|
|
||||||
vbox.pack_start(self._preview_frame,True,True)
|
|
||||||
vbox.pack_start(self._filter_frame,True,True)
|
|
||||||
vbox2.pack_start(self._tree_frame,True,True)
|
|
||||||
|
|
||||||
pane.pack1(vbox2,True,False)
|
|
||||||
pane.pack2(vbox,False,True)
|
|
||||||
|
|
||||||
pane_align = gtk.Alignment()
|
|
||||||
pane_align.add(pane)
|
|
||||||
pane_align.set_padding(self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width)
|
|
||||||
pane_align.set(0.5,0.5,1,1)
|
|
||||||
pane_align.show()
|
|
||||||
|
|
||||||
self.add(pane_align)
|
|
||||||
|
|
||||||
|
|
||||||
def set_preview(self,treeselection):
|
|
||||||
(model, iter) = treeselection.get_selected()
|
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
def get_selection(self):
|
|
||||||
return self._tree_frame.get_selection()
|
|
||||||
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(ObjectFrameBase)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
pass
|
|
@ -1,351 +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$
|
|
||||||
|
|
||||||
#for debug, remove later
|
|
||||||
import sys
|
|
||||||
sys.path.append("..")
|
|
||||||
sys.path.append(".")
|
|
||||||
sys.path.append("ObjectSelector")
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
from gettext import gettext as _
|
|
||||||
|
|
||||||
import _Factories
|
|
||||||
from _Constants import ObjectTypes
|
|
||||||
|
|
||||||
from ManagedWindow import ManagedWindow
|
|
||||||
import const
|
|
||||||
|
|
||||||
class _ObjectTypeWidgets(object):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.frame = None
|
|
||||||
self.sel_label = None
|
|
||||||
self.selected_obj = None
|
|
||||||
self.new_button = None
|
|
||||||
|
|
||||||
def show(self):
|
|
||||||
self.frame.show_all()
|
|
||||||
self.sel_label.show_all()
|
|
||||||
self.new_button.show()
|
|
||||||
|
|
||||||
def hide(self):
|
|
||||||
self.frame.hide_all()
|
|
||||||
self.sel_label.hide_all()
|
|
||||||
self.new_button.hide()
|
|
||||||
|
|
||||||
def set_selected_obj(self,obj):
|
|
||||||
self.selected_obj = obj
|
|
||||||
|
|
||||||
OBJECT_LIST = [ObjectTypes.PERSON, ObjectTypes.FAMILY,
|
|
||||||
ObjectTypes.SOURCE, ObjectTypes.EVENT,
|
|
||||||
ObjectTypes.MEDIA, ObjectTypes.PLACE,
|
|
||||||
ObjectTypes.REPOSITORY]
|
|
||||||
|
|
||||||
class ObjectSelectorWindow(gtk.Window,ManagedWindow):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
'add-object' : (gobject.SIGNAL_RUN_LAST,
|
|
||||||
gobject.TYPE_NONE,
|
|
||||||
(gobject.TYPE_PYOBJECT,)),
|
|
||||||
}
|
|
||||||
|
|
||||||
__default_border_width = 5
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
dbstate,
|
|
||||||
uistate,
|
|
||||||
track,
|
|
||||||
title = _("Select Object"),
|
|
||||||
filter_spec = None,
|
|
||||||
default_object_type = ObjectTypes.PERSON,
|
|
||||||
object_list = OBJECT_LIST):
|
|
||||||
|
|
||||||
# Init the display manager
|
|
||||||
ManagedWindow.__init__(self,uistate,track,self)
|
|
||||||
|
|
||||||
# Init the Window
|
|
||||||
gtk.Window.__init__(self)
|
|
||||||
|
|
||||||
self._dbstate = dbstate
|
|
||||||
self._uistate = dbstate
|
|
||||||
self._track = track
|
|
||||||
self._object_list = object_list
|
|
||||||
self._current_object_type = None
|
|
||||||
|
|
||||||
# Create objects to hold the information about
|
|
||||||
# each object type
|
|
||||||
self._object_frames = {}
|
|
||||||
for object_type in object_list:
|
|
||||||
self._object_frames[object_type] = _ObjectTypeWidgets()
|
|
||||||
|
|
||||||
self.set_title(title)
|
|
||||||
|
|
||||||
# Selected object label
|
|
||||||
|
|
||||||
new_button_box = gtk.VBox()
|
|
||||||
new_button_box.show()
|
|
||||||
|
|
||||||
for object_type in object_list:
|
|
||||||
new_button = gtk.Button(stock=gtk.STOCK_NEW)
|
|
||||||
|
|
||||||
self._object_frames[object_type].new_button = new_button
|
|
||||||
new_button_box.pack_start(new_button)
|
|
||||||
|
|
||||||
label = gtk.Label("<b>Selected:</b>")
|
|
||||||
label.set_use_markup(True)
|
|
||||||
label.set_alignment(xalign=0.9,yalign=0.5)
|
|
||||||
label.set_padding(self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width)
|
|
||||||
|
|
||||||
label.show()
|
|
||||||
|
|
||||||
sel_frame = gtk.Frame()
|
|
||||||
sel_frame.set_shadow_type(gtk.SHADOW_IN)
|
|
||||||
sel_frame.set_border_width(self.__class__.__default_border_width*2)
|
|
||||||
|
|
||||||
sel_label_box = gtk.HBox()
|
|
||||||
sel_label_box.show()
|
|
||||||
|
|
||||||
for object_type in object_list:
|
|
||||||
sel_label = gtk.Label("No Selected Object")
|
|
||||||
sel_label.set_alignment(xalign=0,yalign=0.5)
|
|
||||||
sel_label_box.pack_start(sel_label)
|
|
||||||
|
|
||||||
self._object_frames[object_type].sel_label = sel_label
|
|
||||||
|
|
||||||
sel_frame.add(sel_label_box)
|
|
||||||
sel_frame.show()
|
|
||||||
|
|
||||||
label_box = gtk.HBox()
|
|
||||||
label_box.pack_start(new_button_box,False,False)
|
|
||||||
label_box.pack_start(label,False,False)
|
|
||||||
label_box.pack_start(sel_frame,True,True)
|
|
||||||
label_box.show()
|
|
||||||
|
|
||||||
# Object select
|
|
||||||
obj_label = gtk.Label("<b>Show</b>")
|
|
||||||
obj_label.set_use_markup(True)
|
|
||||||
obj_label.set_alignment(xalign=0.9,yalign=0.5)
|
|
||||||
obj_label.set_padding(self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width)
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
person_pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(const.IMAGE_DIR,"person.svg"))
|
|
||||||
flist_pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(const.IMAGE_DIR,"flist.svg"))
|
|
||||||
|
|
||||||
self._tool_list = gtk.ListStore(gtk.gdk.Pixbuf,
|
|
||||||
gobject.TYPE_STRING,
|
|
||||||
gobject.TYPE_INT)
|
|
||||||
|
|
||||||
d={ObjectTypes.PERSON: [person_pixbuf,'People',ObjectTypes.PERSON],
|
|
||||||
ObjectTypes.FAMILY: [flist_pixbuf,'Families',ObjectTypes.FAMILY],
|
|
||||||
ObjectTypes.EVENT: [person_pixbuf,'Events',ObjectTypes.EVENT]}
|
|
||||||
|
|
||||||
self._object_type_column = 2
|
|
||||||
|
|
||||||
except gobject.GError:
|
|
||||||
self._tool_list = gtk.ListStore(gobject.TYPE_STRING,
|
|
||||||
gobject.TYPE_INT)
|
|
||||||
|
|
||||||
d={ObjectTypes.PERSON: ['People',ObjectTypes.PERSON],
|
|
||||||
ObjectTypes.FAMILY: ['Families',ObjectTypes.FAMILY],
|
|
||||||
ObjectTypes.EVENT: ['Events',ObjectTypes.EVENT]}
|
|
||||||
|
|
||||||
self._object_type_column = 1
|
|
||||||
|
|
||||||
|
|
||||||
for object_type in self._object_list:
|
|
||||||
self._tool_list.append(d[object_type])
|
|
||||||
|
|
||||||
self._tool_combo = gtk.ComboBox(self._tool_list)
|
|
||||||
|
|
||||||
icon_cell = gtk.CellRendererPixbuf()
|
|
||||||
label_cell = gtk.CellRendererText()
|
|
||||||
|
|
||||||
self._tool_combo.pack_start(icon_cell, True)
|
|
||||||
self._tool_combo.pack_start(label_cell, True)
|
|
||||||
|
|
||||||
self._tool_combo.add_attribute(icon_cell, 'pixbuf', 0)
|
|
||||||
self._tool_combo.add_attribute(label_cell, 'text', 1)
|
|
||||||
|
|
||||||
self._tool_combo.set_active(0)
|
|
||||||
|
|
||||||
self._tool_combo.connect('changed', lambda c: self._set_object_type(self._tool_list.get_value(c.get_active_iter(),2)))
|
|
||||||
|
|
||||||
tool_box = gtk.HBox()
|
|
||||||
tool_box.pack_start(obj_label,False,False)
|
|
||||||
tool_box.pack_start(self._tool_combo,False,False)
|
|
||||||
|
|
||||||
# only show the object_list if there is more than
|
|
||||||
# one object_type requested.
|
|
||||||
if len(self._object_list) > 1:
|
|
||||||
self._tool_combo.show()
|
|
||||||
obj_label.show()
|
|
||||||
tool_box.show()
|
|
||||||
|
|
||||||
# Top box
|
|
||||||
|
|
||||||
top_box = gtk.HBox()
|
|
||||||
top_box.pack_start(tool_box,False,False)
|
|
||||||
top_box.pack_start(label_box,True,True)
|
|
||||||
top_box.show()
|
|
||||||
|
|
||||||
# Create the widgets for each of the object types
|
|
||||||
|
|
||||||
# Object frame box
|
|
||||||
|
|
||||||
frame_box = gtk.HBox()
|
|
||||||
frame_box.show()
|
|
||||||
|
|
||||||
|
|
||||||
for object_type in object_list:
|
|
||||||
|
|
||||||
self._object_frames[object_type].frame = \
|
|
||||||
_Factories.ObjectFrameFactory().get_frame(object_type,dbstate,uistate,filter_spec)
|
|
||||||
|
|
||||||
# connect signals
|
|
||||||
self._object_frames[object_type].frame.connect(
|
|
||||||
'selection-changed',
|
|
||||||
lambda widget,text,selected_object,label: label.set_text(text),
|
|
||||||
self._object_frames[object_type].sel_label)
|
|
||||||
|
|
||||||
self._object_frames[object_type].frame.connect(
|
|
||||||
'selection-changed',
|
|
||||||
lambda widget,text,selected_object,current_object: current_object.set_selected_obj(selected_object),
|
|
||||||
self._object_frames[object_type])
|
|
||||||
|
|
||||||
self._object_frames[object_type].frame.connect(
|
|
||||||
'selection-changed',
|
|
||||||
self.on_selection_changed)
|
|
||||||
|
|
||||||
self._object_frames[object_type].frame.connect(
|
|
||||||
'add-object',
|
|
||||||
self.on_add)
|
|
||||||
|
|
||||||
self._object_frames[object_type].new_button.connect(
|
|
||||||
'clicked',
|
|
||||||
self._object_frames[object_type].frame.new_object)
|
|
||||||
|
|
||||||
frame_box.pack_start(self._object_frames[object_type].frame,True,True)
|
|
||||||
|
|
||||||
|
|
||||||
# Bottom buttons
|
|
||||||
self._add_button = gtk.Button(stock=gtk.STOCK_ADD)
|
|
||||||
self._add_button.set_sensitive(False)
|
|
||||||
self._add_button.show()
|
|
||||||
|
|
||||||
self._add_button.connect("clicked", self.on_add)
|
|
||||||
|
|
||||||
cancel_button = gtk.Button(stock=gtk.STOCK_CANCEL)
|
|
||||||
cancel_button.show()
|
|
||||||
|
|
||||||
cancel_button.connect_object("clicked", self._close_window, self)
|
|
||||||
|
|
||||||
bottom_button_bar = gtk.HButtonBox()
|
|
||||||
bottom_button_bar.set_layout(gtk.BUTTONBOX_SPREAD)
|
|
||||||
bottom_button_bar.set_spacing(self.__class__.__default_border_width/2)
|
|
||||||
bottom_button_bar.set_border_width(self.__class__.__default_border_width)
|
|
||||||
bottom_button_bar.add(cancel_button)
|
|
||||||
bottom_button_bar.add(self._add_button)
|
|
||||||
bottom_button_bar.show()
|
|
||||||
|
|
||||||
box = gtk.VBox()
|
|
||||||
box.pack_start(top_box,False,False)
|
|
||||||
box.pack_start(frame_box,True,True)
|
|
||||||
box.pack_start(bottom_button_bar,False,False)
|
|
||||||
box.show()
|
|
||||||
|
|
||||||
align = gtk.Alignment()
|
|
||||||
align.set_padding(self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width)
|
|
||||||
align.set(0.5,0.5,1,1)
|
|
||||||
align.add(box)
|
|
||||||
align.show()
|
|
||||||
|
|
||||||
self.add(align)
|
|
||||||
|
|
||||||
self._set_object_type(default_object_type)
|
|
||||||
self.set_default_size(700,300)
|
|
||||||
|
|
||||||
self.show()
|
|
||||||
|
|
||||||
|
|
||||||
def _close_window(self,obj):
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def _set_object_type(self,selected_object_type):
|
|
||||||
# enable selected object type
|
|
||||||
self._object_frames[selected_object_type].show()
|
|
||||||
|
|
||||||
# disable all the others
|
|
||||||
[ self._object_frames[object_type].hide() for object_type in self._object_list
|
|
||||||
if object_type != selected_object_type]
|
|
||||||
|
|
||||||
# Set the object selector list to the selected object type
|
|
||||||
# this is required because we may be asked to set the object type
|
|
||||||
# without the use selecting it explicitly from the list.
|
|
||||||
store = self._tool_list
|
|
||||||
it = store.get_iter_first()
|
|
||||||
while it:
|
|
||||||
if store.get(it, self._object_type_column)[0] == selected_object_type:
|
|
||||||
break
|
|
||||||
it = store.iter_next(it)
|
|
||||||
|
|
||||||
if it != None:
|
|
||||||
self._tool_combo.set_active_iter(it)
|
|
||||||
|
|
||||||
self._current_object_type = selected_object_type
|
|
||||||
|
|
||||||
# Set the add button sensitivity
|
|
||||||
if self._object_frames[selected_object_type].selected_obj:
|
|
||||||
self._add_button.set_sensitive(True)
|
|
||||||
else:
|
|
||||||
self._add_button.set_sensitive(False)
|
|
||||||
|
|
||||||
|
|
||||||
def on_add(self,widget=None,object=None):
|
|
||||||
if object is None:
|
|
||||||
self.emit('add-object',self._object_frames[self._current_object_type].selected_obj)
|
|
||||||
else:
|
|
||||||
self.emit('add-object',object)
|
|
||||||
|
|
||||||
def on_selection_changed(self,widget,text,handle):
|
|
||||||
if handle:
|
|
||||||
self._add_button.set_sensitive(True)
|
|
||||||
else:
|
|
||||||
self._add_button.set_sensitive(False)
|
|
||||||
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(ObjectSelectorWindow)
|
|
||||||
|
|
||||||
|
|
@ -1,240 +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$
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
from gettext import gettext as _
|
|
||||||
from logging import getLogger
|
|
||||||
|
|
||||||
log = getLogger(".ObjectSelector")
|
|
||||||
|
|
||||||
from _FilterFrameBase import FilterFrameBase
|
|
||||||
from Filters import GenericFilter, Rules
|
|
||||||
import gen.lib
|
|
||||||
|
|
||||||
class PersonFilterFrame(FilterFrameBase):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
}
|
|
||||||
|
|
||||||
# This is used when the widgets are packed into the ObjectSelector
|
|
||||||
# frames.
|
|
||||||
__default_border_width = 5
|
|
||||||
|
|
||||||
def __init__(self,filter_spec=None,label="Filter"):
|
|
||||||
FilterFrameBase.__init__(self,filter_spec,label)
|
|
||||||
|
|
||||||
# Build the filter widgets, the make_* methods are
|
|
||||||
# in the FilterFrameBase base class.
|
|
||||||
|
|
||||||
# Gramps ID
|
|
||||||
self._id_check,self._id_label,self._id_edit = \
|
|
||||||
self.make_text_widget("Gramps ID")
|
|
||||||
|
|
||||||
# Name
|
|
||||||
self._name_check,self._name_label,self._name_edit = \
|
|
||||||
self.make_text_widget("Name")
|
|
||||||
|
|
||||||
# Gender
|
|
||||||
genders=[[_("Male"),gen.lib.Person.MALE],
|
|
||||||
[_("Female"),gen.lib.Person.FEMALE],
|
|
||||||
[_("Unknown"),gen.lib.Person.UNKNOWN]]
|
|
||||||
|
|
||||||
self._gender_list = gtk.ListStore(gobject.TYPE_STRING,
|
|
||||||
gobject.TYPE_INT)
|
|
||||||
|
|
||||||
for entry in genders:
|
|
||||||
self._gender_list.append(entry)
|
|
||||||
|
|
||||||
self._gender_check,self._gender_label, self._gender_combo = \
|
|
||||||
self.make_combo_widget("Gender",self._gender_list)
|
|
||||||
|
|
||||||
# Birth
|
|
||||||
self._birth_check, self._b_edit, \
|
|
||||||
self._b_before, self._b_after, \
|
|
||||||
self._b_unknown = self.make_year_widget("Birth Year")
|
|
||||||
|
|
||||||
# Death
|
|
||||||
self._death_check, self._d_edit, \
|
|
||||||
self._d_before, self._d_after, \
|
|
||||||
self._d_unknown = self.make_year_widget("Death Year")
|
|
||||||
|
|
||||||
# Filter
|
|
||||||
default_filters = [
|
|
||||||
Rules.Person.Everyone,
|
|
||||||
Rules.Person.IsFemale,
|
|
||||||
Rules.Person.IsMale,
|
|
||||||
Rules.Person.HasUnknownGender,
|
|
||||||
Rules.Person.Disconnected,
|
|
||||||
Rules.Person.SearchName,
|
|
||||||
Rules.Person.HaveAltFamilies,
|
|
||||||
Rules.Person.HavePhotos,
|
|
||||||
Rules.Person.IncompleteNames,
|
|
||||||
Rules.Person.HaveChildren,
|
|
||||||
Rules.Person.NeverMarried,
|
|
||||||
Rules.Person.MultipleMarriages,
|
|
||||||
Rules.Person.NoBirthdate,
|
|
||||||
Rules.Person.PersonWithIncompleteEvent,
|
|
||||||
Rules.Person.FamilyWithIncompleteEvent,
|
|
||||||
Rules.Person.ProbablyAlive,
|
|
||||||
Rules.Person.PeoplePrivate,
|
|
||||||
Rules.Person.IsWitness,
|
|
||||||
Rules.Person.HasTextMatchingSubstringOf,
|
|
||||||
Rules.Person.HasTextMatchingRegexpOf,
|
|
||||||
Rules.Person.HasNote,
|
|
||||||
Rules.Person.HasNoteMatchingSubstringOf,
|
|
||||||
Rules.Person.IsFemale,
|
|
||||||
]
|
|
||||||
|
|
||||||
# don't currently support filters that need an attribute.
|
|
||||||
filters = [ filter for filter in default_filters if \
|
|
||||||
not hasattr(filter,'labels') or len(filter.labels) == 0 ]
|
|
||||||
|
|
||||||
self._filter_list = gtk.ListStore(gobject.TYPE_STRING, gobject)
|
|
||||||
|
|
||||||
for filter in filters:
|
|
||||||
self._filter_list.append([filter.name,filter])
|
|
||||||
|
|
||||||
self._filter_check,self._filter_label,self._filter_combo = \
|
|
||||||
self.make_combo_widget("Filter",self._filter_list)
|
|
||||||
|
|
||||||
self._reset_widgets()
|
|
||||||
|
|
||||||
if filter_spec is not None:
|
|
||||||
self._set_filter(filter_spec)
|
|
||||||
|
|
||||||
def _set_filter(self,filter_spec):
|
|
||||||
if filter_spec.include_gramps_id():
|
|
||||||
self._id_check.set_active(True)
|
|
||||||
self._id_edit.set_text(filter_spec.get_gramps_id())
|
|
||||||
else:
|
|
||||||
self._id_check.set_active(False)
|
|
||||||
self._id_edit.set_text("")
|
|
||||||
|
|
||||||
if filter_spec.include_name():
|
|
||||||
self._name_check.set_active(True)
|
|
||||||
self._name_edit.set_text(filter_spec.get_name())
|
|
||||||
else:
|
|
||||||
self._name_check.set_active(False)
|
|
||||||
self._name_edit.set_text("")
|
|
||||||
|
|
||||||
if filter_spec.include_gender():
|
|
||||||
self._gender_check.set_active(True)
|
|
||||||
store = self._gender_list
|
|
||||||
it = store.get_iter_first()
|
|
||||||
while it:
|
|
||||||
if store.get(it, 1)[0] == filter_spec.get_gender():
|
|
||||||
break
|
|
||||||
it = store.iter_next(it)
|
|
||||||
|
|
||||||
if it != None:
|
|
||||||
self._gender_combo.set_active_iter(it)
|
|
||||||
else:
|
|
||||||
self._gender_check.set_active(False)
|
|
||||||
|
|
||||||
|
|
||||||
if filter_spec.include_birth():
|
|
||||||
self._birth_check.set_active(True)
|
|
||||||
self._b_edit.set_text(filter_spec.get_birth_year())
|
|
||||||
if filter_spec.get_birth_criteria() == filter_spec.__class__.BEFORE:
|
|
||||||
self._b_before.set_active(True)
|
|
||||||
self._b_after.set_active(False)
|
|
||||||
else:
|
|
||||||
self._b_before.set_active(False)
|
|
||||||
self._b_after.set_active(True)
|
|
||||||
else:
|
|
||||||
self._birth_check.set_active(False)
|
|
||||||
self._b_edit.set_text("")
|
|
||||||
|
|
||||||
if filter_spec.include_death():
|
|
||||||
self._death_check.set_active(True)
|
|
||||||
self._d_edit.set_text(filter_spec.get_death_year())
|
|
||||||
if filter_spec.get_death_criteria() == filter_spec.__class__.BEFORE:
|
|
||||||
self._d_before.set_active(True)
|
|
||||||
self._d_after.set_active(False)
|
|
||||||
else:
|
|
||||||
self._d_before.set_active(False)
|
|
||||||
self._d_after.set_active(True)
|
|
||||||
else:
|
|
||||||
self._death_check.set_active(False)
|
|
||||||
self._d_edit.set_text("")
|
|
||||||
|
|
||||||
def on_apply(self,button=None):
|
|
||||||
filter = GenericFilter()
|
|
||||||
|
|
||||||
if self._id_check.get_active():
|
|
||||||
filter.add_rule(Rules.Person.HasIdOf([self._id_edit.get_text()]))
|
|
||||||
|
|
||||||
if self._name_check.get_active():
|
|
||||||
filter.add_rule(Rules.Person.SearchName([self._name_edit.get_text()]))
|
|
||||||
|
|
||||||
if self._gender_check.get_active():
|
|
||||||
gender = self._gender_list.get_value(self._gender_combo.get_active_iter(),1)
|
|
||||||
if gender == gen.lib.Person.MALE:
|
|
||||||
filter.add_rule(Rules.Person.IsMale([]))
|
|
||||||
elif gender == gen.lib.Person.FEMALE:
|
|
||||||
filter.add_rule(Rules.Person.IsFemale([]))
|
|
||||||
elif gender == gen.lib.Person.UNKNOWN:
|
|
||||||
filter.add_rule(Rules.Person.HasUnknownGender([]))
|
|
||||||
else:
|
|
||||||
log.warn("Received unknown gender from filter widget")
|
|
||||||
|
|
||||||
if self._birth_check.get_active():
|
|
||||||
date = ""
|
|
||||||
if self._b_before.get_active():
|
|
||||||
date = "before " + self._b_edit.get_text()
|
|
||||||
elif self._b_after.get_active():
|
|
||||||
date = "after " + self._b_edit.get_text()
|
|
||||||
else:
|
|
||||||
log.warn("neither before or after is selected, this should not happen")
|
|
||||||
filter.add_rule(Rules.Person.HasBirth([date,'','']))
|
|
||||||
|
|
||||||
if self._death_check.get_active():
|
|
||||||
date = ""
|
|
||||||
if self._d_before.get_active():
|
|
||||||
date = "before " + self._d_edit.get_text()
|
|
||||||
elif self._d_after.get_active():
|
|
||||||
date = "after " + self._d_edit.get_text()
|
|
||||||
else:
|
|
||||||
log.warn("neither before or after is selected, this should not happen")
|
|
||||||
filter.add_rule(Rules.Person.HasDeath([date,'','']))
|
|
||||||
|
|
||||||
|
|
||||||
if self._filter_check.get_active():
|
|
||||||
filter.add_rule(self._filter_list.get_value(self._filter_combo.get_active_iter(),1)([]))
|
|
||||||
|
|
||||||
self.emit('apply-filter',filter)
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(PersonFilterFrame)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
w = gtk.Window()
|
|
||||||
f = PersonFilterFrame()
|
|
||||||
w.add(f)
|
|
||||||
|
|
||||||
w.show_all()
|
|
||||||
|
|
||||||
gtk.main()
|
|
@ -1,87 +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$
|
|
||||||
|
|
||||||
from _FilterSpecBase import FilterSpecBase
|
|
||||||
|
|
||||||
class PersonFilterSpec(FilterSpecBase):
|
|
||||||
|
|
||||||
BEFORE = 1
|
|
||||||
AFTER = 2
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
FilterSpecBase.__init__(self)
|
|
||||||
|
|
||||||
self._name = None
|
|
||||||
self._gender = None
|
|
||||||
self._birth_year = None
|
|
||||||
self._birth_criteria = self.__class__.BEFORE
|
|
||||||
self._death_year = None
|
|
||||||
self._death_criteria = self.__class__.BEFORE
|
|
||||||
|
|
||||||
def set_name(self,name):
|
|
||||||
self._name = name
|
|
||||||
|
|
||||||
def get_name(self):
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
def include_name(self):
|
|
||||||
return self._name is not None
|
|
||||||
|
|
||||||
def set_gender(self,gender):
|
|
||||||
self._gender = gender
|
|
||||||
|
|
||||||
def get_gender(self):
|
|
||||||
return self._gender
|
|
||||||
|
|
||||||
def include_gender(self):
|
|
||||||
return self._gender is not None
|
|
||||||
|
|
||||||
def set_birth_year(self,year):
|
|
||||||
self._birth_year = str(year)
|
|
||||||
|
|
||||||
def get_birth_year(self):
|
|
||||||
return self._birth_year
|
|
||||||
|
|
||||||
def include_birth(self):
|
|
||||||
return self._birth_year is not None
|
|
||||||
|
|
||||||
def set_birth_criteria(self,birth_criteria):
|
|
||||||
self._birth_criteria = birth_criteria
|
|
||||||
|
|
||||||
def get_birth_criteria(self):
|
|
||||||
return self._birth_criteria
|
|
||||||
|
|
||||||
def set_death_year(self,year):
|
|
||||||
self._death_year = str(year)
|
|
||||||
|
|
||||||
def get_death_year(self):
|
|
||||||
return self._death_year
|
|
||||||
|
|
||||||
def include_death(self):
|
|
||||||
return self._death_year is not None
|
|
||||||
|
|
||||||
def set_death_criteria(self,death_criteria):
|
|
||||||
self._death_criteria = death_criteria
|
|
||||||
|
|
||||||
def get_death_criteria(self):
|
|
||||||
return self._death_criteria
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
|||||||
#
|
|
||||||
# Gramps - a GTK+/GNOME based genealogy program
|
|
||||||
#
|
|
||||||
# Copyright (C) 2000-2007 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$
|
|
||||||
|
|
||||||
#for debug, remove later
|
|
||||||
import sys
|
|
||||||
sys.path.append("..")
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
|
|
||||||
from gen.lib import Person
|
|
||||||
from BasicUtils import name_displayer
|
|
||||||
display_name = name_displayer.display
|
|
||||||
|
|
||||||
from _ObjectFrameBase import ObjectFrameBase
|
|
||||||
from _PersonFilterFrame import PersonFilterFrame
|
|
||||||
from _PersonPreviewFrame import PersonPreviewFrame
|
|
||||||
from _PersonTreeFrame import PersonTreeFrame
|
|
||||||
|
|
||||||
|
|
||||||
class PersonFrame(ObjectFrameBase):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
'selection-changed' : (gobject.SIGNAL_RUN_LAST,
|
|
||||||
gobject.TYPE_NONE,
|
|
||||||
(gobject.TYPE_STRING,
|
|
||||||
gobject.TYPE_PYOBJECT)),
|
|
||||||
|
|
||||||
'add-object': (gobject.SIGNAL_RUN_LAST,
|
|
||||||
gobject.TYPE_NONE,
|
|
||||||
(gobject.TYPE_PYOBJECT,))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
__person_id_field = 1
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
dbstate,
|
|
||||||
uistate,
|
|
||||||
filter_spec = None):
|
|
||||||
|
|
||||||
ObjectFrameBase.__init__(self,
|
|
||||||
dbstate=dbstate,
|
|
||||||
uistate=uistate,
|
|
||||||
filter_frame = PersonFilterFrame(filter_spec=filter_spec),
|
|
||||||
preview_frame = PersonPreviewFrame(dbstate),
|
|
||||||
tree_frame = PersonTreeFrame(dbstate))
|
|
||||||
|
|
||||||
def handle_selection(treeselection):
|
|
||||||
(model, iter) = treeselection.get_selected()
|
|
||||||
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)
|
|
||||||
else:
|
|
||||||
self.emit('selection-changed',"No Selection",None)
|
|
||||||
else:
|
|
||||||
self.emit('selection-changed',"No Selection",None)
|
|
||||||
else:
|
|
||||||
self.emit('selection-changed',"No Selection",None)
|
|
||||||
|
|
||||||
|
|
||||||
self._tree_frame.get_selection().connect('changed',handle_selection)
|
|
||||||
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.
|
|
||||||
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:
|
|
||||||
(o,rowref) = model.get_value(iter,0)
|
|
||||||
if o:
|
|
||||||
self.emit('add-object',o)
|
|
||||||
|
|
||||||
def new_object(self,button):
|
|
||||||
from Editors import EditPerson
|
|
||||||
|
|
||||||
person = Person()
|
|
||||||
EditPerson(self._dbstate,self._uistate,[],person)
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(PersonFrame)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
pass
|
|
@ -1,169 +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$
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
from xml.sax.saxutils import escape
|
|
||||||
from gettext import gettext as _
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
from logging import getLogger
|
|
||||||
log = getLogger(".ObjectSelector")
|
|
||||||
|
|
||||||
import ImgManip
|
|
||||||
import const
|
|
||||||
from ToolTips import PersonTip
|
|
||||||
import DateHandler
|
|
||||||
|
|
||||||
from _PreviewFrameBase import PreviewFrameBase
|
|
||||||
|
|
||||||
def short(val,size=60):
|
|
||||||
if len(val) > size:
|
|
||||||
return "%s..." % val[0:size]
|
|
||||||
else:
|
|
||||||
return val
|
|
||||||
|
|
||||||
class PersonPreviewFrame(PreviewFrameBase):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
}
|
|
||||||
|
|
||||||
__default_border_width = 5
|
|
||||||
|
|
||||||
def __init__(self,dbstate,label="Preview"):
|
|
||||||
PreviewFrameBase.__init__(self,label)
|
|
||||||
self._dbstate = dbstate
|
|
||||||
align = gtk.Alignment()
|
|
||||||
|
|
||||||
# Image
|
|
||||||
self._image = gtk.Image()
|
|
||||||
|
|
||||||
# test image
|
|
||||||
self._image.set_from_file(os.path.join(const.IMAGE_DIR,"person.svg"))
|
|
||||||
|
|
||||||
# Text
|
|
||||||
label = gtk.Label()
|
|
||||||
label.set_use_markup(True)
|
|
||||||
label.set_line_wrap(True)
|
|
||||||
label.set_justify(gtk.JUSTIFY_LEFT)
|
|
||||||
label.set_alignment(xalign=0.5,yalign=0.1)
|
|
||||||
|
|
||||||
# box
|
|
||||||
box = gtk.VBox()
|
|
||||||
box.pack_start(self._image,False,False)
|
|
||||||
box.pack_start(label)
|
|
||||||
|
|
||||||
# align
|
|
||||||
align.add(box)
|
|
||||||
align.set_padding(self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width,
|
|
||||||
self.__class__.__default_border_width)
|
|
||||||
align.set(0.5,0.5,
|
|
||||||
1.0,1.0)
|
|
||||||
|
|
||||||
self.add(align)
|
|
||||||
self._label = label
|
|
||||||
|
|
||||||
def _get_text_preview(self,person):
|
|
||||||
global escape
|
|
||||||
|
|
||||||
birth_str = ""
|
|
||||||
birth_ref = person.get_birth_ref()
|
|
||||||
if birth_ref:
|
|
||||||
birth = self._dbstate.db.get_event_from_handle(birth_ref.ref)
|
|
||||||
date_str = DateHandler.get_date(birth)
|
|
||||||
if date_str != "":
|
|
||||||
birth_str = escape(date_str)
|
|
||||||
|
|
||||||
death_str = ""
|
|
||||||
death_ref = person.get_death_ref()
|
|
||||||
if death_ref:
|
|
||||||
death = self._dbstate.db.get_event_from_handle(death_ref.ref)
|
|
||||||
date_str = DateHandler.get_date(death)
|
|
||||||
if date_str != "":
|
|
||||||
death_str = escape(date_str)
|
|
||||||
|
|
||||||
s = "<span weight=\"bold\">%s</span>\n"\
|
|
||||||
" <span weight=\"normal\">%s:</span> %s\n"\
|
|
||||||
" <span weight=\"normal\">%s:</span> %s\n"\
|
|
||||||
" <span weight=\"normal\">%s:</span> %s\n"% (
|
|
||||||
_("Person"),
|
|
||||||
_("Name"),escape(person.get_primary_name().get_name()),
|
|
||||||
_("Birth"),birth_str,
|
|
||||||
_("Death"),death_str)
|
|
||||||
|
|
||||||
if len(person.get_source_references()) > 0:
|
|
||||||
psrc_ref = person.get_source_references()[0]
|
|
||||||
psrc_id = psrc_ref.get_reference_handle()
|
|
||||||
psrc = self._dbstate.db.get_source_from_handle(psrc_id)
|
|
||||||
|
|
||||||
s += "\n<span weight=\"bold\">%s</span>\n"\
|
|
||||||
" <span weight=\"normal\">%s:</span> %s\n" % (
|
|
||||||
_("Primary source"),
|
|
||||||
_("Name"),
|
|
||||||
escape(short(psrc.get_title())))
|
|
||||||
|
|
||||||
return s
|
|
||||||
|
|
||||||
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)
|
|
||||||
if mobj.get_mime_type()[0:5] == "image":
|
|
||||||
pixbuf = ImgManip.get_thumbnail_image(mobj.get_path())
|
|
||||||
self._image.set_from_pixbuf(pixbuf)
|
|
||||||
else:
|
|
||||||
self._image.set_from_file(os.path.join(const.IMAGE_DIR,"person.svg"))
|
|
||||||
|
|
||||||
self._label.set_markup(self._get_text_preview(person))
|
|
||||||
|
|
||||||
except:
|
|
||||||
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.IMAGE_DIR,"person.svg"))
|
|
||||||
self._label.set_markup("")
|
|
||||||
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(PersonPreviewFrame)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
w = gtk.Window()
|
|
||||||
f = PersonPreviewFrame()
|
|
||||||
w.add(f)
|
|
||||||
w.show_all()
|
|
||||||
|
|
||||||
gtk.main()
|
|
@ -1,119 +0,0 @@
|
|||||||
#
|
|
||||||
# Gramps - a GTK+/GNOME based genealogy program
|
|
||||||
#
|
|
||||||
# Copyright (C) 2000-2007 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$
|
|
||||||
|
|
||||||
from gettext import gettext as _
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
|
|
||||||
from TreeViews import PersonTreeView
|
|
||||||
|
|
||||||
from _TreeFrameBase import TreeFrameBase
|
|
||||||
|
|
||||||
column_names = [
|
|
||||||
_('Name'),
|
|
||||||
_('ID') ,
|
|
||||||
_('Gender'),
|
|
||||||
_('Birth Date'),
|
|
||||||
_('Birth Place'),
|
|
||||||
_('Death Date'),
|
|
||||||
_('Death Place'),
|
|
||||||
_('Spouse'),
|
|
||||||
_('Last Change'),
|
|
||||||
_('Cause of Death'),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class PersonTreeFrame(TreeFrameBase):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
}
|
|
||||||
|
|
||||||
__default_border_width = 5
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self,dbstate):
|
|
||||||
TreeFrameBase.__init__(self)
|
|
||||||
|
|
||||||
self._dbstate = dbstate
|
|
||||||
self._selection = None
|
|
||||||
self._model = None
|
|
||||||
self._data_filter = None
|
|
||||||
|
|
||||||
self._tree = PersonTreeView(dbstate.db)
|
|
||||||
self._tree.set_rules_hint(True)
|
|
||||||
self._tree.set_headers_visible(True)
|
|
||||||
|
|
||||||
self._tree.connect('row-activated',self._on_row_activated)
|
|
||||||
|
|
||||||
scrollwindow = gtk.ScrolledWindow()
|
|
||||||
scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
|
||||||
scrollwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
|
|
||||||
|
|
||||||
scrollwindow.add(self._tree)
|
|
||||||
|
|
||||||
self.add(scrollwindow)
|
|
||||||
|
|
||||||
self.change_db(self._dbstate.db)
|
|
||||||
|
|
||||||
def _on_row_activated(self,widget,path,col):
|
|
||||||
"""Expand / colapse row"""
|
|
||||||
|
|
||||||
if self._tree.row_expanded(path):
|
|
||||||
self._tree.collapse_row(path)
|
|
||||||
else:
|
|
||||||
self._tree.expand_row(path,False)
|
|
||||||
|
|
||||||
def change_db(self,db):
|
|
||||||
self.set_model()
|
|
||||||
|
|
||||||
def set_model(self,data_filter=None):
|
|
||||||
|
|
||||||
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 get_selection(self):
|
|
||||||
return self._selection
|
|
||||||
|
|
||||||
def get_tree(self):
|
|
||||||
return self._tree
|
|
||||||
|
|
||||||
if gtk.pygtk_version < (2,8,0):
|
|
||||||
gobject.type_register(PersonTreeFrame)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
w = ObjectSelectorWindow()
|
|
||||||
w.show_all()
|
|
||||||
w.connect("destroy", gtk.main_quit)
|
|
||||||
|
|
||||||
gtk.main()
|
|
@ -1,36 +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$
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
|
|
||||||
class PreviewFrameBase(gtk.Frame):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self,label):
|
|
||||||
gtk.Frame.__init__(self,label)
|
|
||||||
|
|
||||||
def set_object(self,person):
|
|
||||||
raise NotImplementedError("Subclasses of PreviewFrameBase must implement set_object")
|
|
@ -1,43 +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$
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
|
|
||||||
class TreeFrameBase(gtk.Frame):
|
|
||||||
|
|
||||||
__gproperties__ = {}
|
|
||||||
|
|
||||||
__gsignals__ = {
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
gtk.Frame.__init__(self)
|
|
||||||
|
|
||||||
def set_model(self,data_filter=None):
|
|
||||||
raise NotImplementedError("Subclasses of TreeFrameBase must implement set_model")
|
|
||||||
|
|
||||||
def get_selection(self):
|
|
||||||
raise NotImplementedError("Subclasses of TreeFrameBase must implement get_selection")
|
|
||||||
|
|
||||||
def get_tree(self):
|
|
||||||
raise NotImplementedError("Subclasses of TreeFrameBase must implement get_tree")
|
|
||||||
|
|
@ -1,110 +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$
|
|
||||||
|
|
||||||
"""
|
|
||||||
ObjectSelector provides a collection of widgets that can be used to select
|
|
||||||
any of the Primary objects in the database.
|
|
||||||
|
|
||||||
The class hierachy is currently this:
|
|
||||||
|
|
||||||
gtk.Window
|
|
||||||
ObjectSelectorWindow
|
|
||||||
PersonSelector
|
|
||||||
|
|
||||||
gtk.Frame
|
|
||||||
FilterFrameBase
|
|
||||||
PersonFilterFrame
|
|
||||||
FamilyFilterFrame
|
|
||||||
ObjectFrameBase
|
|
||||||
FamilyFrame
|
|
||||||
PersonFrame
|
|
||||||
PreviewFrameBase
|
|
||||||
FamilyPreviewFrame
|
|
||||||
PersonPreviewFrame
|
|
||||||
TreeFrameBase
|
|
||||||
FamilyTreeFrame
|
|
||||||
PersonTreeFrame
|
|
||||||
|
|
||||||
FilterSpecBase
|
|
||||||
PersonFilterSpec
|
|
||||||
|
|
||||||
ObjectFrameFactory
|
|
||||||
|
|
||||||
To implement a selector for a new Primary gen.lib type you need to implement a new
|
|
||||||
subclass of each of:
|
|
||||||
|
|
||||||
FilterFrameBase
|
|
||||||
ObjectFrameBase
|
|
||||||
PreviewFrameBase
|
|
||||||
TreeFrameBase
|
|
||||||
|
|
||||||
You must then extend ObjectFrameFactory so that it know how to create the new selector
|
|
||||||
type. The new type should also be added to the OBJECT_LIST in _ObjectSelectorWindow.py
|
|
||||||
so that it shows up in the selector. A subclass of ObjectSelectorWindow can be added to
|
|
||||||
this file as a convienience for starting a selector for just the new type.
|
|
||||||
|
|
||||||
At runtime Object selector is constructed from these widgets in the following structure:
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
| ObjectSelectorWindow |
|
|
||||||
|
|
|
||||||
| --------------------------------------------------------------------------- |
|
|
||||||
| | Subclass of ObjectFrameBase | |
|
|
||||||
| | | |
|
|
||||||
| | ----------------------------- ---------------------------------------- | |
|
|
||||||
| | | Subclass of TreeFrameBase | | Subclass of PreviewFrameBase | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | ---------------------------------------- | |
|
|
||||||
| | | | ---------------------------------------- | |
|
|
||||||
| | | | | Subclass of FilterFrameBase | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | | | | | | |
|
|
||||||
| | ----------------------------- ---------------------------------------- | |
|
|
||||||
| --------------------------------------------------------------------------- |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
"""
|
|
||||||
from gettext import gettext as _
|
|
||||||
|
|
||||||
from _ObjectSelectorWindow import ObjectSelectorWindow
|
|
||||||
from _Constants import ObjectTypes
|
|
||||||
from _PersonFilterSpec import PersonFilterSpec
|
|
||||||
|
|
||||||
class PersonSelector(ObjectSelectorWindow):
|
|
||||||
"""Provides an ObjectSelectorWindow configured for selecting a person object."""
|
|
||||||
|
|
||||||
def __init__(self,dbstate,uistate,track,filter_spec=None,title=_("Select Person")):
|
|
||||||
ObjectSelectorWindow.__init__(self,dbstate,uistate,track,
|
|
||||||
title=title,
|
|
||||||
filter_spec=filter_spec,
|
|
||||||
default_object_type = ObjectTypes.PERSON,
|
|
||||||
object_list = [ObjectTypes.PERSON])
|
|
@ -5,8 +5,7 @@
|
|||||||
# License: GPL
|
# License: GPL
|
||||||
# Id: $Id$
|
# Id: $Id$
|
||||||
|
|
||||||
"""A tooltip class for TreeViews
|
"""A tooltip class."""
|
||||||
"""
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Support for text markup added: March 05 - rjt-gramps <at> thegrindstone.me.uk
|
# Support for text markup added: March 05 - rjt-gramps <at> thegrindstone.me.uk
|
||||||
@ -17,12 +16,12 @@ import gtk
|
|||||||
import gobject
|
import gobject
|
||||||
|
|
||||||
class TreeTips(gtk.Widget):
|
class TreeTips(gtk.Widget):
|
||||||
''' A tooltips widget specialized to work with gtk.TreeView's.
|
""" A tooltips widget specialized to work with gtk.TreeView's.
|
||||||
|
|
||||||
TreeTips associates a column in a TreeStore with tooltips that will be
|
TreeTips associates a column in a TreeStore with tooltips that will be
|
||||||
displayed when the mouse is over the row the column is for. Each row can
|
displayed when the mouse is over the row the column is for. Each row can
|
||||||
have one treetip.
|
have one treetip.
|
||||||
'''
|
"""
|
||||||
__gproperties__ = {
|
__gproperties__ = {
|
||||||
'tip_window' : (gobject.TYPE_PYOBJECT,
|
'tip_window' : (gobject.TYPE_PYOBJECT,
|
||||||
'The window that the tooltip is displayed in.',
|
'The window that the tooltip is displayed in.',
|
||||||
@ -64,7 +63,7 @@ class TreeTips(gtk.Widget):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, treeview=None, column=None, markup_enabled=False):
|
def __init__(self, treeview=None, column=None, markup_enabled=False):
|
||||||
'''Create a new TreeTips Group.
|
"""Create a new TreeTips Group.
|
||||||
|
|
||||||
:Parameters:
|
:Parameters:
|
||||||
treeview : gtk.TreeView === Treeview for which the tips display,
|
treeview : gtk.TreeView === Treeview for which the tips display,
|
||||||
@ -73,7 +72,7 @@ class TreeTips(gtk.Widget):
|
|||||||
text, default is None.
|
text, default is None.
|
||||||
markup_enabled : bool === If True the tooltips are in Pango Markup,
|
markup_enabled : bool === If True the tooltips are in Pango Markup,
|
||||||
if False the tooltips are in plain text.
|
if False the tooltips are in plain text.
|
||||||
'''
|
"""
|
||||||
if treeview:
|
if treeview:
|
||||||
try:
|
try:
|
||||||
treeview.connect('leave-notify-event', self.__tree_leave_notify)
|
treeview.connect('leave-notify-event', self.__tree_leave_notify)
|
||||||
@ -106,15 +105,15 @@ class TreeTips(gtk.Widget):
|
|||||||
self.screenHeight = gtk.gdk.screen_height()
|
self.screenHeight = gtk.gdk.screen_height()
|
||||||
|
|
||||||
def enable(self):
|
def enable(self):
|
||||||
'''Enable showing of tooltips'''
|
"""Enable showing of tooltips"""
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
'''Disable showing tooltips'''
|
"""Disable showing tooltips"""
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
|
|
||||||
def do_get_property(self, prop):
|
def do_get_property(self, prop):
|
||||||
'''Return the gproperty's value.'''
|
"""Return the gproperty's value."""
|
||||||
if prop.name == 'delay':
|
if prop.name == 'delay':
|
||||||
return self.delay
|
return self.delay
|
||||||
elif prop.name == 'enabled':
|
elif prop.name == 'enabled':
|
||||||
@ -135,9 +134,9 @@ class TreeTips(gtk.Widget):
|
|||||||
raise AttributeError, 'unknown property %s' % prop.name
|
raise AttributeError, 'unknown property %s' % prop.name
|
||||||
|
|
||||||
def do_set_property(self, prop, value):
|
def do_set_property(self, prop, value):
|
||||||
'''Set the property of writable properties.
|
"""Set the property of writable properties.
|
||||||
|
|
||||||
'''
|
"""
|
||||||
if prop.name == 'delay':
|
if prop.name == 'delay':
|
||||||
self.delay = value
|
self.delay = value
|
||||||
elif prop.name == 'view':
|
elif prop.name == 'view':
|
||||||
@ -162,14 +161,14 @@ class TreeTips(gtk.Widget):
|
|||||||
'tooltip', 0, 0, -1, -1)
|
'tooltip', 0, 0, -1, -1)
|
||||||
|
|
||||||
def __tree_leave_notify(self, tree, event):
|
def __tree_leave_notify(self, tree, event):
|
||||||
'''Hide tooltips when we leave the tree.'''
|
"""Hide tooltips when we leave the tree."""
|
||||||
|
|
||||||
self.timeoutID = 0
|
self.timeoutID = 0
|
||||||
self.path = None
|
self.path = None
|
||||||
self.tip_window.hide()
|
self.tip_window.hide()
|
||||||
|
|
||||||
def __tree_motion_notify(self, tree, event):
|
def __tree_motion_notify(self, tree, event):
|
||||||
'''Decide which tooltip to display when we move within the tree.'''
|
"""Decide which tooltip to display when we move within the tree."""
|
||||||
|
|
||||||
if not self.enabled:
|
if not self.enabled:
|
||||||
return
|
return
|
||||||
@ -181,7 +180,7 @@ class TreeTips(gtk.Widget):
|
|||||||
int(event.x), int(event.y), self.timeoutID)
|
int(event.x), int(event.y), self.timeoutID)
|
||||||
|
|
||||||
def __treetip_show(self, tree, xEvent, yEvent, ID):
|
def __treetip_show(self, tree, xEvent, yEvent, ID):
|
||||||
'''Show the treetip window.'''
|
"""Show the treetip window."""
|
||||||
if self.timeoutID != ID:
|
if self.timeoutID != ID:
|
||||||
return False
|
return False
|
||||||
pathReturn = tree.get_path_at_pos(xEvent, yEvent)
|
pathReturn = tree.get_path_at_pos(xEvent, yEvent)
|
||||||
@ -223,7 +222,7 @@ class TreeTips(gtk.Widget):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def __compute_tooltip_position(self, cellInfo, popupWidth, popupHeight):
|
def __compute_tooltip_position(self, cellInfo, popupWidth, popupHeight):
|
||||||
'''Figures out where the tooltip should be placed on the page::
|
"""Figures out where the tooltip should be placed on the page::
|
||||||
|
|
||||||
[p] = pointer
|
[p] = pointer
|
||||||
x = [p]
|
x = [p]
|
||||||
@ -237,7 +236,7 @@ class TreeTips(gtk.Widget):
|
|||||||
+------------+
|
+------------+
|
||||||
|____________|
|
|____________|
|
||||||
[p]
|
[p]
|
||||||
'''
|
"""
|
||||||
|
|
||||||
xOrigin, yOrigin = self.view.get_bin_window().get_origin()
|
xOrigin, yOrigin = self.view.get_bin_window().get_origin()
|
||||||
x = xOrigin + cellInfo.x + cellInfo.width/2 - popupWidth/2
|
x = xOrigin + cellInfo.x + cellInfo.width/2 - popupWidth/2
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
# This is the src/TreeViews level Makefile for Gramps
|
|
||||||
# We could use GNU make's ':=' syntax for nice wildcard use,
|
|
||||||
# but that is not necessarily portable.
|
|
||||||
# If not using GNU make, then list all .py files individually
|
|
||||||
|
|
||||||
pkgdatadir = $(datadir)/@PACKAGE@/TreeViews
|
|
||||||
|
|
||||||
pkgdata_PYTHON = \
|
|
||||||
__init__.py\
|
|
||||||
_PersonTreeView.py
|
|
||||||
|
|
||||||
pkgpyexecdir = @pkgpyexecdir@/TreeViews
|
|
||||||
pkgpythondir = @pkgpythondir@/TreeViews
|
|
||||||
|
|
||||||
# Clean up all the byte-compiled files
|
|
||||||
MOSTLYCLEANFILES = *pyc *pyo
|
|
||||||
|
|
||||||
GRAMPS_PY_MODPATH = "../"
|
|
||||||
|
|
||||||
pycheck:
|
|
||||||
(export PYTHONPATH=$(GRAMPS_PY_MODPATH); \
|
|
||||||
pychecker $(pkgdata_PYTHON));
|
|
@ -1,156 +0,0 @@
|
|||||||
|
|
||||||
from gettext import gettext as _
|
|
||||||
import cgi
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
|
|
||||||
from Models import \
|
|
||||||
PersonTreeModel, PersonListModel, PersonFilterModel
|
|
||||||
|
|
||||||
from BasicUtils import name_displayer
|
|
||||||
from gen.lib import Event
|
|
||||||
import DateHandler
|
|
||||||
import Utils
|
|
||||||
|
|
||||||
display_given = name_displayer.display_given
|
|
||||||
|
|
||||||
|
|
||||||
class PersonTreeView(gtk.TreeView):
|
|
||||||
|
|
||||||
def __init__(self,db,apply_filter=None):
|
|
||||||
gtk.TreeView.__init__(self)
|
|
||||||
|
|
||||||
self._db = db
|
|
||||||
|
|
||||||
# Add the Name column
|
|
||||||
cols = (\
|
|
||||||
(_("Name"),300,self._family_name),\
|
|
||||||
(_("ID"),100,self._object_id),\
|
|
||||||
(_("Gender"),100,self._gender),\
|
|
||||||
(_("Birth Date"),200,self._birth_date),\
|
|
||||||
(_("Birth Place"),200,self._birth_place),\
|
|
||||||
(_("Death Date"),200,self._death_date),\
|
|
||||||
(_("Death Place"),200,self._death_place),\
|
|
||||||
(_("Spouse"),200,self._spouce),\
|
|
||||||
(_("Last Change"),200,self._last_change),\
|
|
||||||
(_("Cause of Death"),300,self._death_cause))
|
|
||||||
|
|
||||||
for col in cols:
|
|
||||||
self.append_column(
|
|
||||||
self._new_column(
|
|
||||||
col[0],col[1],col[2]))
|
|
||||||
|
|
||||||
self.set_enable_search(False)
|
|
||||||
self.set_fixed_height_mode(True)
|
|
||||||
|
|
||||||
if apply_filter is not None:
|
|
||||||
self.set_filter(apply_filter)
|
|
||||||
else:
|
|
||||||
self.clear_filter()
|
|
||||||
|
|
||||||
def _new_column(self,name,size,func):
|
|
||||||
col = gtk.TreeViewColumn(name)
|
|
||||||
col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
|
|
||||||
col.set_fixed_width(size)
|
|
||||||
cell = gtk.CellRendererText()
|
|
||||||
col.pack_start(cell,True)
|
|
||||||
col.set_cell_data_func(cell,func)
|
|
||||||
return col
|
|
||||||
|
|
||||||
def set_filter(self,apply_filter=None):
|
|
||||||
self.set_model(PersonFilterModel(self._db,apply_filter))
|
|
||||||
|
|
||||||
def clear_filter(self):
|
|
||||||
self.set_model(PersonTreeModel(self._db))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Accessor methods for the columns
|
|
||||||
|
|
||||||
def _object_id(self, column, cell, model, iter, user_data=None):
|
|
||||||
(o,rowref) = model.get_value(iter, 0)
|
|
||||||
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 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','')
|
|
||||||
|
|
||||||
def _gender(self, column, cell, model, iter, user_data=None):
|
|
||||||
(o,rowref) = model.get_value(iter, 0)
|
|
||||||
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', "")
|
|
||||||
|
|
||||||
def _birth_date(self, column, cell, model, iter, user_data=None):
|
|
||||||
(o,rowref) = model.get_value(iter, 0)
|
|
||||||
cell_value = ''
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
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('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 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 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 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 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 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 or model.is_list()) and o is not None:
|
|
||||||
cell.set_property('text', "")
|
|
||||||
else:
|
|
||||||
cell.set_property('text', "")
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
from _PersonTreeView import PersonTreeView
|
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
# $Id$
|
# $Id$
|
||||||
|
|
||||||
"""Tools/Utilities/Generate SoundEx Codes..."""
|
"""Tools/Utilities/Generate SoundEx Codes"""
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -36,7 +36,7 @@ from gettext import gettext as _
|
|||||||
#
|
#
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
import gtk
|
import gtk
|
||||||
import gtk.glade
|
from gtk import glade
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# GRAMPS modules
|
# GRAMPS modules
|
||||||
@ -63,7 +63,7 @@ class SoundGen(Tool.Tool, ManagedWindow.ManagedWindow):
|
|||||||
base = os.path.dirname(__file__)
|
base = os.path.dirname(__file__)
|
||||||
glade_file = base + os.sep + "soundex.glade"
|
glade_file = base + os.sep + "soundex.glade"
|
||||||
|
|
||||||
self.glade = gtk.glade.XML(glade_file,"soundEx","gramps")
|
self.glade = glade.XML(glade_file,"soundEx","gramps")
|
||||||
self.glade.signal_autoconnect({
|
self.glade.signal_autoconnect({
|
||||||
"destroy_passed_object" : self.close,
|
"destroy_passed_object" : self.close,
|
||||||
"on_help_clicked" : self.on_help_clicked,
|
"on_help_clicked" : self.on_help_clicked,
|
||||||
@ -141,7 +141,7 @@ register_tool(
|
|||||||
tool_class = SoundGen,
|
tool_class = SoundGen,
|
||||||
options_class = SoundGenOptions,
|
options_class = SoundGenOptions,
|
||||||
modes = Tool.MODE_GUI,
|
modes = Tool.MODE_GUI,
|
||||||
translated_name = _("Generate SoundEx Codes..."),
|
translated_name = _("Generate SoundEx Codes"),
|
||||||
status=(_("Stable")),
|
status=(_("Stable")),
|
||||||
author_name = "Donald N. Allingham",
|
author_name = "Donald N. Allingham",
|
||||||
author_email = "don@gramps-project.org",
|
author_email = "don@gramps-project.org",
|
||||||
|
Loading…
Reference in New Issue
Block a user