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):
@@ -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,16 +201,37 @@ 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
"""
if row[0] == self._WORKGROUP:
from gen.lib import EventRoleType
obj.set_role((EventRoleType.UNKNOWN,''))
EmbeddedList._handle_drag(self, row, obj)
#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,
@@ -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')
def __init__(self, event_list, db):
gtk.ListStore.__init__(self, str, str, str, str, str, str, str, object)
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, 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(),
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(event_ref),
self.column_place(event_ref),
self.column_role(event_ref),
self.column_sort_date(event_ref),
event_ref
])
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),
@@ -41,11 +50,52 @@ _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)
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):
"""