text: # -*- coding: utf-8 -*-
  
  
  from anima.ui.lib import QtCore, QtWidgets
  
  
  class ScheduleTimingWidget(QtWidgets.QWidget):
      """A widget for entering schedule timing related information
  
      :param timing_resolution: Timing resolution as a Datetime.TimeDelta instance.
      """
  
      def __init__(self, *args, **kwargs):
          timing_resolution = kwargs.pop("timing_resolution", None)
          super(ScheduleTimingWidget, self).__init__(*args, **kwargs)
          self._timing_resolution = None
  
          self.main_layout = None
          self.schedule_timing_widget = None
          self.schedule_unit_widget = None
          self.schedule_model_widget = None
  
          self._updating_schedule_info = False
  
          self._setup_ui()
  
          self.timing_resolution = timing_resolution
  
          self._setup_signals()
  
      def _setup_ui(self):
          """set up the ui
          """
          self.main_layout = QtWidgets.QHBoxLayout(self)
          self.main_layout.setContentsMargins(0, 0, 0, 0)
  
          self.schedule_timing_widget = QtWidgets.QSpinBox(self)
          self.schedule_timing_widget.setMinimum(1)
          self.schedule_timing_widget.setMaximum(9999999)
          self.main_layout.addWidget(self.schedule_timing_widget)
  
          self.schedule_unit_widget = QtWidgets.QComboBox(self)
          from stalker import defaults
          for datetime_unit_name, datetime_unit in zip(defaults.datetime_unit_names, defaults.datetime_units):
              self.schedule_unit_widget.addItem(datetime_unit_name.title(), datetime_unit)
  
          self.main_layout.addWidget(self.schedule_unit_widget)
  
          self.schedule_model_widget = QtWidgets.QComboBox(self)
          from stalker.models.mixins import DateRangeMixin
          for task_schedule_model in defaults.task_schedule_models:
              self.schedule_model_widget.addItem(task_schedule_model.title(), task_schedule_model)
  
          self.main_layout.addWidget(self.schedule_model_widget)
  
          self.main_layout.setStretch(0, 1)
          self.main_layout.setStretch(1, 2)
          self.main_layout.setStretch(2, 2)
  
      def _setup_signals(self):
          """set up the signals
          """
          from functools import partial
          self.schedule_timing_widget.valueChanged.connect(partial(self.update_timing_info))
          self.schedule_unit_widget.currentIndexChanged.connect(partial(self.update_timing_info))
  
      def update_timing_info(self, *args):
          """updates the timing information
          """
          self.set_schedule_info(*self.get_schedule_info())
  
      def get_schedule_info(self):
          """getter for the schedule_info
          """
          schedule_timing = self.schedule_timing_widget.value()
          schedule_unit = self.schedule_unit_widget.itemData(self.schedule_unit_widget.currentIndex())
          schedule_model = self.schedule_model_widget.itemData(self.schedule_model_widget.currentIndex())
          return schedule_timing, schedule_unit, schedule_model
  
      def set_schedule_info(self, timing=1, unit='h', model='effort'):
          """setter for the schedule_info
  
          :param int timing:
          :param str unit:
          :param str model:
          :return:
          """
          if self._updating_schedule_info:
              return
  
          self._updating_schedule_info = True
  
          from stalker.models.mixins import ScheduleMixin
          seconds = ScheduleMixin.to_seconds(timing, unit, model)
  
          # round the seconds to the timing resolution
          trs = self.timing_resolution.days * 86400 + self.timing_resolution.seconds
  
          # adjust the step of the schedule_timing to the current unit
          from anima import utils
          step = max(1, utils.to_unit(trs, unit, model))
          self.schedule_timing_widget.setSingleStep(step)
  
          # round the seconds to the timing resolution
          seconds = (max(1, round(seconds / trs))) * trs
  
          # get the timing value in this unit
          timing = utils.to_unit(seconds, unit, model)
  
          self.schedule_timing_widget.setValue(timing)
  
          index = self.schedule_unit_widget.findData(unit)
          if index:
              self.schedule_unit_widget.setCurrentIndex(index)
  
          index = self.schedule_model_widget.findData(model)
          if index:
              self.schedule_model_widget.setCurrentIndex(index)
  
          self._updating_schedule_info = False
  
      @property
      def timing_resolution(self):
          """the getter for the timing_resolution property
          """
          return self._timing_resolution
  
      @timing_resolution.setter
      def timing_resolution(self, timing_resolution=None):
          """setter for the timing_resolution property
  
          :param DateTime.TimeDelta timing_resolution: datetime.timedelta instance showing the timing resolution. If not
            given or None is given the anima.default.timing_resolution value will be used.
          :return:
          """
          import datetime
          if timing_resolution is None:
              from anima import defaults
              timing_resolution = defaults.timing_resolution
          elif not isinstance(timing_resolution, datetime.timedelta):
              raise TypeError("%s.timing_resolution should be set to a datetime.timedelta instance, not %s" % (
                  self.__class__.__name__, timing_resolution.__class__.__name__
              ))
  
          self._timing_resolution = timing_resolution
  
          # update the timing information
          self.update_timing_info()
  