Clone event w/o references (2nd pass, part B)

Feature request #9604

This functionality in the Event list doubles an event with all the tags, citations, media, attributes and notes, but without the references. Its like an event addition, but with default values.
This commit is contained in:
Alois Poettker 2018-04-18 17:08:01 +02:00
parent 32dd3a2e14
commit 208feceb03
10 changed files with 113 additions and 18 deletions

View File

@ -2,6 +2,7 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
# Copyright (C) 2018 Alois Poettker
#
# 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
@ -27,10 +28,24 @@ from .backrefmodel import BackRefModel
from .backreflist import BackRefList
class EventBackRefList(BackRefList):
""""""
def __init__(self, dbstate, uistate, track, obj, option=None, callback=None):
"""
Connector class between events and back reference mechanism
"""
self.option = option
def __init__(self, dbstate, uistate, track, obj, callback=None):
BackRefList.__init__(self, dbstate, uistate, track, obj,
BackRefModel, callback)
def get_icon_name(self):
return 'gramps-event'
def get_data(self):
"""
Method overrides 'get_data' from BackRefList.py
"""
if self.option and self.option['action']:
return []
else:
return self.obj

View File

@ -4,6 +4,7 @@
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2009 Gary Burton
# Copyright (C) 2011 Tim G L Lyons
# Copyright (C) 2018 Alois Poettker
#
# 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
@ -71,6 +72,9 @@ WIKI_HELP_SEC = _('manual|New_Event_dialog')
class EditEvent(EditPrimary):
def __init__(self, dbstate, uistate, track, event, callback=None):
""""""
self.callback = callback
self.action = uistate.action.split('-')[1]
EditPrimary.__init__(self, dbstate, uistate, track,
event, dbstate.db.get_event_from_handle,
@ -86,18 +90,27 @@ class EditEvent(EditPrimary):
return Event()
def get_menu_title(self):
""" compile menu title out of different actions """
handle = self.obj.get_handle()
event_action, event_name = '', ''
if handle:
if self.action == 'clone':
event_action = _('Clone')
if self.action == 'edit':
event_action = _('Edit')
who = get_participant_from_event(self.db, handle)
desc = self.obj.get_description()
event_name = self.obj.get_type()
if desc:
event_name = '%s - %s' % (event_name, desc)
event_name = self.obj.get_type().string
if who:
event_name = '%s - %s' % (event_name, who)
dialog_title = _('Event: %s') % event_name
event_name = ': %s - %s' % (event_name, who)
elif desc:
event_name = ': %s - %s' % (event_name, desc)
else:
dialog_title = _('New Event')
event_action = _('New')
dialog_title = _('%s Event%s') % (event_action, event_name)
return dialog_title
def get_custom_events(self):
@ -207,10 +220,14 @@ class EditEvent(EditPrimary):
self._add_tab(notebook, self.attr_list)
handle_list = self.dbstate.db.find_backlink_handles(self.obj.handle)
# Additional variables in 'EventBackRefList' injected via 'option'
backref_option = {}
backref_option['action'] = self.action == 'clone'
self.backref_list = EventBackRefList(self.dbstate,
self.uistate,
self.track,
handle_list)
handle_list,
option=backref_option)
self._add_tab(notebook, self.backref_list)
self._setup_notebook_tabs(notebook)
@ -269,7 +286,11 @@ class EditEvent(EditPrimary):
self.db) as trans:
self.db.add_event(self.obj, trans)
else:
if self.data_has_changed():
if self.action == 'clone':
with DbTxn(_("Clone Event"), self.db) as trans:
self.obj.handle = None
self.db.add_event(self.obj, trans)
elif self.data_has_changed():
with DbTxn(_("Edit Event (%s)") % self.obj.get_gramps_id(),
self.db) as trans:
if not self.obj.get_gramps_id():
@ -287,7 +308,6 @@ class EditEvent(EditPrimary):
entered date when importing from a XML file, so we can get an
incorrect fail.
"""
if self.db.readonly:
return False
elif self.obj.handle:

View File

@ -241,7 +241,7 @@ class EditEventRef(EditReference):
self.uistate,
self.track,
self.db.find_backlink_handles(self.source.handle),
self.enable_warnbox)
callback=self.enable_warnbox)
self._add_tab(notebook, self.backref_tab)
self.track_ref_for_deletion("backref_tab")

View File

@ -3,7 +3,7 @@
# Copyright (C) 2001-2007 Donald N. Allingham
# Copyright (C) 2008 Gary Burton
# Copyright (C) 2011 Tim G L Lyons
# Copyright (C) 2017 Alois Poettker
# Copyright (C) 2018 Alois Poettker
#
# 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
@ -29,6 +29,7 @@ Provide the event view.
# Standard python modules
#
#-------------------------------------------------------------------------
import copy
import logging
_LOG = logging.getLogger(".plugins.eventview")
@ -40,16 +41,16 @@ _LOG = logging.getLogger(".plugins.eventview")
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gramps.gui.dialog import ErrorDialog, MultiSelectDialog, QuestionDialog
from gramps.gen.errors import WindowActiveError
from gramps.gen.lib import Event
from gramps.gen.plug import CATEGORY_QR_EVENT
from gramps.gen.utils.string import data_recover_msg
from gramps.gui.dialog import ErrorDialog, MultiSelectDialog, QuestionDialog
from gramps.gui.ddtargets import DdTargets
from gramps.gui.editors import EditEvent, DeleteEventQuery
from gramps.gui.filters.sidebar import EventSidebarFilter
from gramps.gui.merge import MergeEvent
from gramps.gen.plug import CATEGORY_QR_EVENT
from gramps.gui.views.bookmarks import EventBookmarks
from gramps.gui.views.listview import ListView, TEXT, MARKUP, ICON
from gramps.gui.views.treemodels import EventModel
@ -97,6 +98,7 @@ class EventView(ListView):
EDIT_MSG = _("Edit the selected event")
DEL_MSG = _("Delete the selected event")
MERGE_MSG = _("Merge the selected events")
CLONE_MSG = _("Clones the selected event")
FILTER_TYPE = "Event"
QR_CATEGORY = CATEGORY_QR_EVENT
@ -124,6 +126,8 @@ class EventView(ListView):
'<PRIMARY>BackSpace' : self.key_delete,
})
# Identify the requested action in several sublevel
uistate.action = ''
uistate.connect('nameformat-changed', self.build_tree)
uistate.connect('placeformat-changed', self.build_tree)
@ -174,6 +178,7 @@ class EventView(ListView):
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<menuitem action="Clone"/>
</placeholder>
<menuitem action="FilterEdit"/>
</menu>
@ -188,6 +193,7 @@ class EventView(ListView):
<toolitem action="Edit"/>
<toolitem action="Remove"/>
<toolitem action="Merge"/>
<toolitem action="Clone"/>
</placeholder>
</toolbar>
<popup name="Popup">
@ -198,6 +204,7 @@ class EventView(ListView):
<menuitem action="Edit"/>
<menuitem action="Remove"/>
<menuitem action="Merge"/>
<menuitem action="Clone"/>
<separator/>
<menu name="QuickReport" action="QuickReport"/>
</popup>
@ -205,8 +212,13 @@ class EventView(ListView):
def define_actions(self):
ListView.define_actions(self)
self.edit_action.add_actions([
('Clone', 'gramps-clone', _('Clone...'), None,
self.CLONE_MSG, self.clone),
])
self._add_action('FilterEdit', None,
_('Event Filter Editor'), callback=self.filter_editor)
_('Event Filter Editor'),
callback=self.filter_editor,)
self._add_action('QuickReport', None,
_("Quick View"), None, None, None)
@ -219,6 +231,7 @@ class EventView(ListView):
def add(self, obj):
try:
self.uistate.action = 'event-add'
EditEvent(self.dbstate, self.uistate, [], Event())
except WindowActiveError:
pass
@ -282,6 +295,7 @@ class EventView(ListView):
for handle in self.selected_handles():
event = self.dbstate.db.get_event_from_handle(handle)
try:
self.uistate.action = 'event-edit'
EditEvent(self.dbstate, self.uistate, [], event)
except WindowActiveError:
pass
@ -290,16 +304,38 @@ class EventView(ListView):
"""
Merge the selected events.
"""
mlist = self.selected_handles()
merge_list = self.selected_handles()
if len(mlist) != 2:
if len(merge_list) != 2:
msg = _("Cannot merge event objects.")
msg2 = _("Exactly two events must be selected to perform a merge. "
"A second object can be selected by holding down the "
"control key while clicking on the desired event.")
ErrorDialog(msg, msg2, parent=self.uistate.window)
else:
MergeEvent(self.dbstate, self.uistate, [], mlist[0], mlist[1])
self.uistate.action = 'event-merge'
MergeEvent(self.dbstate, self.uistate, [], merge_list[0], merge_list[1])
def clone(self, obj):
"""
Clones the selected event.
"""
event_list = self.selected_handles()
if len(event_list) != 1:
msg = _("Cannot clone event object.")
msg2 = _("Exactly one event must be selected to perform a clone.")
ErrorDialog(msg, msg2, parent=self.uistate.window)
else:
event = Event()
event = copy.deepcopy(self.dbstate.db.get_event_from_handle(event_list[0]))
event.gramps_id = None
try:
self.uistate.action = 'event-clone'
EditEvent(self.dbstate, self.uistate, [], event)
except WindowActiveError:
pass
def tag_updated(self, handle_list):
"""

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Creator: CorelDRAW -->
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="48.033mm" height="48.033mm" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 48.033 48.033"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css">
<![CDATA[
.str0 {stroke:#3C6B41;stroke-width:2.26929}
.fil0 {fill:url(#id0);fill-rule:nonzero}
]]>
</style>
<linearGradient id="id0" gradientUnits="userSpaceOnUse" x1="47.2838" y1="34.1401" x2="0.752554" y2="14.5731">
<stop offset="0" style="stop-color:#337B30"/>
<stop offset="0.101961" style="stop-color:#468843"/>
<stop offset="1" style="stop-color:honeydew"/>
</linearGradient>
</defs>
<g id="Ebene_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<path class="fil0 str0" d="M1.17237 1.84096c2.91519,1.49944 5.83038,3.00369 8.74529,4.49859 2.91519,1.49518 5.83464,2.9949 8.75437,4.4898 -1.69034,1.03139 -3.38096,2.0625 -5.06705,3.08936 0.963882,1.55333 1.92805,3.10695 2.89221,4.65602 1.2657,1.67502 2.5314,3.35033 3.80163,5.02081 1.00076,0.855807 2.00577,1.70679 3.01107,2.55778 0.232886,0.202818 0.470595,0.401098 0.708303,0.599093 0.232886,-0.197996 0.466056,-0.396275 0.703481,-0.599093 1.00076,-0.850985 2.00606,-1.70197 3.01107,-2.55778 1.2657,-1.67048 2.5314,-3.34579 3.80163,-5.02081 0.964166,-1.54908 1.92805,-3.10269 2.89221,-4.65602 -1.69062,-1.02686 -3.38096,-2.05797 -5.06705,-3.08936 2.91491,-1.4949 5.83464,-2.99462 8.74983,-4.4898 2.91462,-1.4949 5.83464,-2.99915 8.75465,-4.49859 -0.0822619,3.22892 -0.164524,6.4621 -0.242247,9.68648 -0.0777233,3.2241 -0.159985,6.45727 -0.237708,9.68166 -1.69034,-1.02657 -3.38125,-2.05797 -5.06705,-3.08908 -0.968705,1.56269 -1.93741,3.1251 -2.90611,4.68297 -1.50341,1.9862 -3.00653,3.97183 -4.50511,5.95349 -0.0958776,0.125946 -0.192039,0.251892 -0.283378,0.373582 -0.109777,0.0899208 -0.214732,0.180125 -0.31997,0.27033 -0.680504,0.580655 -1.36129,1.15734 -2.04208,1.73346 -0.141831,1.99953 -0.283662,3.99878 -0.420387,5.99831 -0.136725,1.99925 -0.274301,3.99878 -0.411593,5.99831 -0.0865168,1.24698 -0.173317,2.49452 -0.260401,3.74178 -1.26088,0 -2.5175,0 -3.77412,0 -1.58539,0 -3.17077,0 -4.75616,0 -1.26116,0 -2.51778,0 -3.7744,0 -0.0868005,-1.24726 -0.173601,-2.4948 -0.260118,-3.74178 -0.141831,-1.99953 -0.283662,-3.99906 -0.420387,-5.99831 -0.137009,-1.99953 -0.274301,-3.99878 -0.411309,-5.99831 -0.681072,-0.576117 -1.36186,-1.1528 -2.04265,-1.73346 -0.109777,-0.0902044 -0.214732,-0.180409 -0.31997,-0.27033 -0.095594,-0.121691 -0.191755,-0.247637 -0.282811,-0.373582 -1.43051,-1.88238 -2.85591,-3.7693 -4.28159,-5.65621 -0.0683625,-0.0899208 -0.137009,-0.180125 -0.205655,-0.27033 -0.00907717,-0.00879351 -0.0136158,-0.0178707 -0.0181543,-0.0269479 -0.968705,-1.55787 -1.93741,-3.12028 -2.90611,-4.68297 -1.69062,1.03111 -3.38125,2.0625 -5.06705,3.08908 -0.0822619,-3.22438 -0.164524,-6.45756 -0.242247,-9.68166 -0.0777233,-3.22438 -0.155447,-6.45756 -0.232886,-9.68648z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB