Feature: see fam events in person editor and pers event in fam editor

svn: r12812
This commit is contained in:
Benny Malengier 2009-07-16 22:00:22 +00:00
parent c2c937ae5d
commit 4957fb2a29
5 changed files with 343 additions and 52 deletions

View File

@ -26,6 +26,7 @@
#
#-------------------------------------------------------------------------
from gettext import gettext as _
import gtk
#-------------------------------------------------------------------------
#
@ -35,7 +36,7 @@ from gettext import gettext as _
import gen.lib
import Errors
from DdTargets import DdTargets
from _EmbeddedList import EmbeddedList
from _GroupEmbeddedList import GroupEmbeddedList
from _EventRefModel import EventRefModel
#-------------------------------------------------------------------------
@ -43,16 +44,21 @@ from _EventRefModel import EventRefModel
# EventEmbedList
#
#-------------------------------------------------------------------------
class EventEmbedList(EmbeddedList):
class EventEmbedList(GroupEmbeddedList):
_HANDLE_COL = 7
_DND_TYPE = DdTargets.EVENTREF
_DND_EXTRA = DdTargets.EVENT
_WORKGROUP = EventRefModel._ROOTINDEX
_WORKNAME = _("Family Events")
_FATHNAME = _("Events father")
_MOTHNAME = _("Events mother")
_MSG = {
'add' : _('Add a new event'),
'del' : _('Remove the selected event'),
'edit' : _('Edit the selected event'),
'add' : _('Add a new family event'),
'del' : _('Remove the selected family event'),
'edit' : _('Edit the selected family event or edit person'),
'share' : _('Share an existing event'),
'up' : _('Move the selected event upwards'),
'down' : _('Move the selected event downwards'),
@ -61,18 +67,26 @@ class EventEmbedList(EmbeddedList):
#index = column in model. Value =
# (name, sortcol in model, width, markup/text, weigth_col
_column_names = [
(_('Type'), 0, 100, 0, -1),
(_('Description'), 1, 175, 0, -1),
(_('ID'), 2, 60, 0, -1),
(_('Date'), 6, 150, 1, -1),
(_('Place'), 4, 140, 0, -1),
(_('Role'), 5, 80, 0, -1),
(_('Description'), -1, 195, 0, EventRefModel.COL_FONTWEIGHT[0]),
(_('Type'), EventRefModel.COL_TYPE[0], 100, 0,
EventRefModel.COL_FONTWEIGHT[0]),
(_('ID'), EventRefModel.COL_GID[0], 60, 0,
EventRefModel.COL_FONTWEIGHT[0]),
(_('Date'), EventRefModel.COL_SORTDATE[0], 150, 1, -1),
(_('Place'), EventRefModel.COL_PLACE[0], 140, 0, -1),
(_('Role'), EventRefModel.COL_ROLE[0], 80, 0, -1),
None,
None,
None
]
def __init__(self, dbstate, uistate, track, obj):
def __init__(self, dbstate, uistate, track, obj,
build_model=EventRefModel):
self.obj = obj
EmbeddedList.__init__(self, dbstate, uistate, track, _('_Events'),
EventRefModel, share_button=True,
self._groups = []
self._data = []
GroupEmbeddedList.__init__(self, dbstate, uistate, track, _('_Events'),
build_model, share_button=True,
move_buttons=True)
def get_ref_editor(self):
@ -83,9 +97,41 @@ class EventEmbedList(EmbeddedList):
return 'gramps-event'
def get_data(self):
return self.obj.get_event_ref_list()
#family events
if not self._data or self.changed:
self._data = [self.obj.get_event_ref_list()]
self._groups = [(self.obj.get_handle(), self._WORKNAME)]
#father events
fhandle = self.obj.get_father_handle()
if fhandle:
fdata = self.dbstate.db.get_person_from_handle(fhandle).\
get_event_ref_list()
if fdata:
self._groups.append((fhandle, self._FATHNAME))
self._data.append(fdata)
#mother events
mhandle = self.obj.get_mother_handle()
if mhandle:
mdata = self.dbstate.db.get_person_from_handle(mhandle).\
get_event_ref_list()
if mdata:
self._groups.append((mhandle, self._MOTHNAME))
self._data.append(mdata)
self.changed = False
return self._data
def groups(self):
"""
Return the (group key, group name)s in the order as given by get_data()
"""
return self._groups
def column_order(self):
"""
The columns to show as a tuple containing
tuples (show/noshow, model column)
"""
return ((1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5))
def default_type(self):
@ -110,7 +156,7 @@ class EventEmbedList(EmbeddedList):
from Selectors import selector_factory
SelectEvent = selector_factory('Event')
sel = SelectEvent(self.dbstate,self.uistate,self.track)
sel = SelectEvent(self.dbstate, self.uistate, self.track)
event = sel.run()
if event:
try:
@ -124,12 +170,12 @@ class EventEmbedList(EmbeddedList):
def edit_button_clicked(self, obj):
ref = self.get_selected()
if ref:
event = self.dbstate.db.get_event_from_handle(ref.ref)
if ref and ref[1] is not None and ref[0] == self._WORKGROUP:
event = self.dbstate.db.get_event_from_handle(ref[1].ref)
try:
self.get_ref_editor()(
self.dbstate, self.uistate, self.track,
event, ref, self.object_edited)
event, ref[1], self.object_edited)
except Errors.WindowActiveError:
from QuestionDialog import WarningDialog
WarningDialog(
@ -140,10 +186,14 @@ class EventEmbedList(EmbeddedList):
"the same event is being edited.\n\nTo edit this event "
"reference, you need to close the event.")
)
elif ref and ref[0] != self._WORKGROUP:
#bring up family editor
key = self._groups[ref[0]][0]
self.editnotworkgroup(key)
def object_added(self, reference, primary):
reference.ref = primary.handle
self.get_data().append(reference)
self.get_data()[self._WORKGROUP].append(reference)
self.changed = True
self.rebuild()
@ -151,23 +201,44 @@ class EventEmbedList(EmbeddedList):
self.changed = True
self.rebuild()
def get_popup_menu_items(self):
if self._tmpgroup == self._WORKGROUP:
GroupEmbeddedList.get_popup_menu_items(self)
else:
return [
(True, True, gtk.STOCK_ADD, self.add_button_clicked),
(False,True, gtk.STOCK_EDIT, self.edit_button_clicked),
]
def _non_native_change(self):
"""
handle change request of non native data
"""
from QuestionDialog import WarningDialog
WarningDialog(
_("Cannot change Person"),
_("You cannot change Person events in the Family Editor")
)
def _handle_drag(self, row, obj):
"""
An event reference that is from a drag and drop has
an unknown event reference role
an unknown event reference role, so it cannot just be added,
it needs to be edited and confirmed
"""
from gen.lib import EventRoleType
obj.set_role((EventRoleType.UNKNOWN,''))
EmbeddedList._handle_drag(self, row, obj)
event = self.dbstate.db.get_event_from_handle(obj.ref)
try:
self.get_ref_editor()(self.dbstate, self.uistate, self.track,
event, obj, self.object_edited)
except Errors.WindowActiveError:
from QuestionDialog import WarningDialog
WarningDialog(
if row[0] == self._WORKGROUP:
from gen.lib import EventRoleType
obj.set_role((EventRoleType.UNKNOWN,''))
#add the event
GroupEmbeddedList._handle_drag(self, row, obj)
#call editor to set new eventref
event = self.dbstate.db.get_event_from_handle(obj.ref)
try:
self.get_ref_editor()(self.dbstate, self.uistate, self.track,
event, obj, self.object_edited)
except Errors.WindowActiveError:
from QuestionDialog import WarningDialog
WarningDialog(
_("Cannot edit this reference"),
_("This event reference cannot be edited at this time. "
"Either the associated event is already being edited "
@ -175,6 +246,8 @@ class EventEmbedList(EmbeddedList):
"the same event is being edited.\n\nTo edit this event "
"reference, you need to close the event.")
)
else:
self.dropnotworkgroup(row, obj)
def handle_extra_type(self, objtype, obj):
try:
@ -187,3 +260,48 @@ class EventEmbedList(EmbeddedList):
except Errors.WindowActiveError:
pass
def editnotworkgroup(self, key):
"""
Edit non native event in own editor
"""
from Editors import EditPerson
person = self.dbstate.db.get_person_from_handle(key)
try:
EditPerson(self.dbstate, self.uistate, [], person)
except Errors.WindowActiveError:
pass
def dropnotworkgroup(self, row, obj):
"""
Drop of obj on row that is not WORKGROUP
"""
self._non_native_change()
def move_away_work(self, row_from, row_to, obj):
"""
move from the workgroup to a not workgroup
we allow to change the default name like this
"""
self.dropnotworkgroup(None, None)
def move_to_work(self, row_from, row_to, obj):
"""
move from a non workgroup to the workgroup
handle this as a drop from clipboard
"""
self._handle_drag(row_to, obj)
def _move_up_notwork(self, row_from, obj, selmethod=None):
"""
move up outside of workgroup
"""
self._non_native_change()
def _move_down_notwork(self, row_from, obj, selmethod=None):
"""
move up outside of workgroup
"""
self._non_native_change()
def post_rebuild(self):
self.tree.expand_all()

View File

@ -20,12 +20,20 @@
# $Id$
#-------------------------------------------------------------------------
#
# python
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GTK libraries
#
#-------------------------------------------------------------------------
import gtk
from pango import WEIGHT_NORMAL, WEIGHT_BOLD
import cgi
#-------------------------------------------------------------------------
@ -48,22 +56,65 @@ invalid_date_format = Config.get(Config.INVALID_DATE_FORMAT)
# EventRefModel
#
#-------------------------------------------------------------------------
class EventRefModel(gtk.ListStore):
class EventRefModel(gtk.TreeStore):
#index of the working group
_ROOTINDEX = 0
_GROUPSTRING = _('%(groupname)s - %(groupnumber)d')
COL_DESCR = (0, str)
COL_TYPE = (1, str)
COL_GID = (2, str)
COL_DATE = (3, str)
COL_PLACE = (4, str)
COL_ROLE = (5, str)
COL_SORTDATE = (6, str)
COL_EVENTREF = (7, object)
COL_FONTWEIGHT = (8, int)
COLS = (COL_DESCR, COL_TYPE, COL_GID, COL_DATE, COL_PLACE, COL_ROLE,
COL_SORTDATE, COL_EVENTREF, COL_FONTWEIGHT)
def __init__(self, event_list, db):
gtk.ListStore.__init__(self, str, str, str, str, str, str, str, object)
def __init__(self, event_list, db, groups):
"""
@param event_list: A list of lists, every entry is a group, the entries
in a group are the data that needs to be shown subordinate to the
group
@param db: a database objects that can be used to obtain info
@param groups: a list of (key, name) tuples. key is a key for the group
that might be used. name is the name for the group.
"""
typeobjs = (x[1] for x in self.COLS)
gtk.TreeStore.__init__(self, *typeobjs)
self.db = db
for event_ref in event_list:
event = db.get_event_from_handle(event_ref.ref)
self.append(row=[str(event.get_type()),
event.get_description(),
event.get_gramps_id(),
self.column_date(event_ref),
self.column_place(event_ref),
self.column_role(event_ref),
self.column_sort_date(event_ref),
event_ref
])
self.groups = groups
for index, group in enumerate(event_list):
parentiter = self.append(None, row=self.row_group(index, group))
for eventref in group:
event = db.get_event_from_handle(eventref.ref)
self.append(parentiter, row = self.row(index, eventref, event))
def row_group(self, index, group):
name = self.namegroup(index, len(group))
return [name, '', '', '', '', '', '', (index, None), WEIGHT_BOLD]
def namegroup(self, groupindex, length):
return self._GROUPSTRING % {'groupname': self.groups[groupindex][1],
'groupnumber': length}
def row(self, index, eventref, event):
return [event.get_description(),
str(event.get_type()),
event.get_gramps_id(),
self.column_date(eventref),
self.column_place(eventref),
self.column_role(eventref),
self.column_sort_date(eventref),
(index, eventref),
self.colweight(index),
]
def colweight(self, index):
return WEIGHT_NORMAL
def column_role(self, event_ref):
return str(event_ref.get_role())

View File

@ -20,13 +20,22 @@
# $Id$
#-------------------------------------------------------------------------
#
# python
#
#-------------------------------------------------------------------------
from gettext import gettext as _
#-------------------------------------------------------------------------
#
# GRAMPS classes
#
#-------------------------------------------------------------------------
import gen.lib
from BasicUtils import name_displayer
from _EventEmbedList import EventEmbedList
from _EventRefModel import EventRefModel
_std_types = [
gen.lib.EventType(gen.lib.EventType.BIRTH),
@ -40,12 +49,53 @@ _std_types = [
#
#-------------------------------------------------------------------------
class PersonEventEmbedList(EventEmbedList):
_WORKNAME = _("Personal Events")
_FAMNAME = _("With %(namepartner)s (%(famid)s)")
_UNKNOWNNAME = _("<Unknown>")
_MSG = {
'add' : _('Add a new personal event'),
'del' : _('Remove the selected personal event'),
'edit' : _('Edit the selected personal event or edit family'),
'share' : _('Share an existing event'),
'up' : _('Move the selected event upwards or change family order'),
'down' : _('Move the selected event downwards or change family order'),
}
def __init__(self, dbstate, uistate, track, obj):
EventEmbedList.__init__(self, dbstate, uistate, track, obj)
def __init__(self, dbstate, uistate, track, obj):
EventEmbedList.__init__(self, dbstate, uistate, track, obj,
build_model=EventRefModel )
def get_data(self):
return self.obj.get_event_ref_list()
if not self._data or self.changed:
self._data = [self.obj.get_event_ref_list()]
self._groups = [(self.obj.get_handle(), self._WORKNAME)]
# own family events
family_handle_list = self.obj.get_family_handle_list()
if family_handle_list:
for family_handle in family_handle_list:
family = self.dbstate.db.get_family_from_handle(family_handle)
father_handle = family.get_father_handle()
mother_handle = family.get_mother_handle()
if self.obj.get_handle() == father_handle:
handlepartner = mother_handle
else:
handlepartner = father_handle
if handlepartner:
partner = self.dbstate.db.get_person_from_handle(
handlepartner)
groupname = name_displayer.display(partner)
else:
groupname = self._UNKNOWNNAME
self._data.append(family.get_event_ref_list())
self._groups.append((family_handle, self._FAMNAME % {
'namepartner': groupname,
'famid': family.get_gramps_id()
}))
self.changed = False
return self._data
def default_role(self):
return gen.lib.EventRoleType(gen.lib.EventRoleType.PRIMARY)
@ -56,7 +106,7 @@ class PersonEventEmbedList(EventEmbedList):
# combine return info into a single flat sequence
event = None
for event_ref in self.get_data():
for event_ref in self.get_data()[0]:
event = self.dbstate.db.get_event_from_handle(event_ref.ref)
type_list.append(event.get_type())
@ -69,3 +119,62 @@ class PersonEventEmbedList(EventEmbedList):
from Editors import EditEventRef
return EditEventRef
def editnotworkgroup(self, key):
"""
Edit non native event in own editor
"""
from Editors import EditFamily
family = self.dbstate.db.get_family_from_handle(key)
try:
EditFamily(self.dbstate, self.uistate, [], family)
except Errors.WindowActiveError:
pass
def _non_native_change(self):
"""
handle change request of non native data
"""
from QuestionDialog import WarningDialog
WarningDialog(
_("Cannot change Family"),
_("You cannot change Family events in the Person Editor")
)
def _move_up_group(self, groupindex):
"""
move up pressed on the group
If on a family group, allow to reorder the order of families
as connected to this person.
"""
ref = self.get_selected()
if not ref or ref[1]:
return
if ref[0] == 1:
#cannot move up, already first family
return
#change family list and rebuild the tabpage
index = ref[0] - 1
flist = self.obj.get_family_handle_list()
handle = flist.pop(index)
flist.insert(index-1, handle)
self.changed = True
self.rebuild()
def _move_down_group(self, groupindex):
"""
move down pressed on the group
If on a family group, allow to reorder the order of families
as connected to this person.
"""
ref = self.get_selected()
if not ref or ref[1]:
return
if ref[0] == len(self._groups)-1:
#cannot move down, already last family
return
#change family list and rebuild the tabpage
index = ref[0] -1
flist = self.obj.get_family_handle_list()
handle = flist.pop(index)
flist.insert(index+1, handle)
self.changed = True
self.rebuild()

View File

@ -484,6 +484,8 @@ class EditFamily(EditPrimary):
def event_updated(self, obj):
self.load_data()
#place in event might have changed, or person event shown in the list
self.event_list.rebuild_callback()
def show_buttons(self):
"""

View File

@ -186,6 +186,9 @@ class EditPerson(EditPrimary):
self._add_db_signal('family-delete', self.family_change)
self._add_db_signal('family-update', self.family_change)
self._add_db_signal('family-add', self.family_change)
self._add_db_signal('event-update', self.event_updated)
self._add_db_signal('event-rebuild', self.event_updated)
self._add_db_signal('event-delete', self.event_updated)
def family_change(self, handle_list=[]):
"""
@ -213,6 +216,14 @@ class EditPerson(EditPrimary):
self.obj.set_family_handle_list(person.get_family_handle_list())
self.obj.set_parent_family_handle_list(
person.get_parent_family_handle_list())
#a family groupname in event_list might need to be changed
# we just rebuild the view always
self.event_list.rebuild_callback()
def event_updated(self, obj):
#place in event might have changed, or person event shown in the list
# we just rebuild the view always
self.event_list.rebuild_callback()
def _setup_fields(self):
"""