Source code for timelinelib.wxgui.dialogs.duplicateevent.controller
# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Rickard Lindberg, Roger Lindberg
#
# This file is part of Timeline.
#
# Timeline 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 3 of the License, or
# (at your option) any later version.
#
# Timeline 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 Timeline. If not, see <http://www.gnu.org/licenses/>.
from timelinelib.wxgui.framework import Controller
FORWARD = 0
BACKWARD = 1
BOTH = 2
[docs]class DuplicateEventDialogController(Controller):
[docs] def on_init(self, event, event_duplicator=None):
if event_duplicator is None:
self.event_duplicator = EventDuplicator()
else:
self.event_duplicator = event_duplicator
self.event = event
self._set_default_values()
[docs] def on_ok(self, evt):
self._create_duplicates()
self.view.Close()
def _set_default_values(self):
self.view.SetCount(1)
self.view.SetFrequency(1)
self.view.SetDirection(FORWARD)
self.view.SelectMovePeriodFnAtIndex(0)
def _create_duplicates(self):
missing_dates_count, periods = self._repeat_period(
self.event.time_period
)
self.event_duplicator.duplicate(self.event, periods)
if missing_dates_count > 0:
self.view.HandleDateErrors(missing_dates_count)
def _repeat_period(self, period):
missing_dates_count = 0
periods = []
for index in self._calculate_indicies():
new_period = self.view.GetMovePeriodFn()(
period,
index * self.view.GetFrequency()
)
if new_period is None:
missing_dates_count += 1
else:
periods.append(new_period)
return (missing_dates_count, periods)
def _calculate_indicies(self):
direction = self.view.GetDirection()
repetitions = self.view.GetCount()
if direction == FORWARD:
return range(1, repetitions + 1)
elif direction == BACKWARD:
return range(-repetitions, 0)
elif direction == BOTH:
indicies = list(range(-repetitions, repetitions + 1))
indicies.remove(0)
return indicies
else:
raise Exception("Invalid direction.")
[docs]class EventDuplicator:
[docs] def duplicate(self, event, periods):
with event.db.transaction("Duplicate event"):
self._duplicate_events(event, periods)
def _duplicate_events(self, event, periods):
for period in periods:
self._duplicate_event(event, period)
def _duplicate_event(self, event, period):
duplicate = event.duplicate()
duplicate.time_period = period
duplicate.container = event.container
duplicate.save()
if event.is_container():
delta = period.get_start_time() - event.get_start_time()
for subevent in event.subevents:
duplicate_subevent = subevent.duplicate()
duplicate_subevent.time_period = subevent.time_period.move_delta(delta)
# It is important to set time period before container, because
# otherwise the strategy might move events unexpectedly.
duplicate_subevent.container = duplicate
duplicate_subevent.save()