Gnumed.timelinelib.canvas.data.immutable

Package Gnumed :: Package timelinelib :: Package canvas :: Package data :: Module immutable |
[frames] | no frames]

# Source Code for Module Gnumed.timelinelib.canvas.data.immutable

      1  # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg
      2  #
      3  # This file is part of Timeline.
      4  #
      5  # Timeline is free software: you can redistribute it and/or modify
      6  # it under the terms of the GNU General Public License as published by
      7  # the Free Software Foundation, either version 3 of the License, or
      8  # (at your option) any later version.
      9  #
     10  # Timeline is distributed in the hope that it will be useful,
     11  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  # GNU General Public License for more details.
     14  #
     15  # You should have received a copy of the GNU General Public License
     16  # along with Timeline.  If not, see <http://www.gnu.org/licenses/>.
     17
     18
     19  from timelinelib.canvas.drawing.drawers import get_progress_color
     20  from timelinelib.general.immutable import Field
     21  from timelinelib.general.immutable import ImmutableDict
     22  from timelinelib.general.immutable import ImmutableRecord
     23
     24
     25 -class ImmutableEvent(ImmutableRecord):
     26
     27      text = Field(None)
     28      time_period = Field(None)
     29      category_id = Field(None)
     30      fuzzy = Field(False)
     31      locked = Field(False)
     32      ends_today = Field(False)
     33      description = Field(None)
     34      icon = Field(None)
     35      hyperlink = Field(None)
     36      alert = Field(None)
     37      progress = Field(None)
     38      default_color = Field(None)
     39      container_id = Field(None)
     40      sort_order = Field(None)
     41
     42
     43 -class ImmutableMilestone(ImmutableRecord):
     44
     45      text = Field(None)
     46      category_id = Field(None)
     47      time_period = Field(None)
     48      description = Field(None)
     49      default_color = Field((255, 255, 128))
     50      sort_order = Field(None)
     51
     52
     53 -class ImmutableEra(ImmutableRecord):
     54
     55      name = Field(None)
     56      time_period = Field(None)
     57      color = Field((200, 200, 200))
     58      ends_today = Field(False)
     59
     60
     61 -class ImmutableCategory(ImmutableRecord):
     62
     63      name = Field("")
     64      color = Field((255, 0, 0))
     65      progress_color = Field(get_progress_color((255, 0, 0)))
     66      done_color = Field(get_progress_color((255, 0, 0)))
     67      font_color = Field((0, 0, 0))
     68      parent_id = Field(None)
     69
     70
     71 -class ImmutableContainer(ImmutableRecord):
     72
     73      text = Field(None)
     74      category_id = Field(None)
     75      time_period = Field(None)
     76      description = Field(None)
     77
     78
     79 -class ImmutableDB(ImmutableRecord):
     80
     81      categories = Field(ImmutableDict())
     82      containers = Field(ImmutableDict())
     83      events = Field(ImmutableDict())
     84      milestones = Field(ImmutableDict())
     85      eras = Field(ImmutableDict())
     86
     87 -    def save_event(self, event, id_):
     88          self._ensure_non_none_category_exists(event.category_id)
     89          self._ensure_non_none_container_exists(event.container_id)
     90          return self.update(
     91              events=self.events.update({
     92                  id_: event,
     93              })
     94          )
     95
     96 -    def delete_event(self, id_):
     97          self._ensure_event_exists(id_)
     98          return self.update(
     99              events=self.events.remove(id_)
    100          )
    101
    102 -    def save_milestone(self, milestone, id_):
    103          self._ensure_non_none_category_exists(milestone.category_id)
    104          return self.update(
    105              milestones=self.milestones.update({
    106                  id_: milestone
    107              })
    108          )
    109
    110 -    def delete_milestone(self, id_):
    111          self._ensure_milestone_exists(id_)
    112          return self.update(
    113              milestones=self.milestones.remove(id_)
    114          )
    115
    116 -    def save_era(self, era, id_):
    117          return self.update(
    118              eras=self.eras.update({
    119                  id_: era,
    120              })
    121          )
    122
    123 -    def delete_era(self, id_):
    124          self._ensure_era_exists(id_)
    125          return self.update(
    126              eras=self.eras.remove(id_)
    127          )
    128
    129 -    def save_category(self, category, id_):
    130          self._ensure_category_name_is_unique(id_, category.name)
    131          self._ensure_non_none_category_exists(category.parent_id)
    132          self._ensure_no_category_circular(id_, category.parent_id)
    133          return self.update(
    134              categories=self.categories.update({id_: category})
    135          )
    136
    137 -    def delete_category(self, delete_id):
    138          self._ensure_category_exists(delete_id)
    139          new_parent_id = self.categories.get(delete_id).parent_id
    140
    141          def update_parent_id(category):
    142              if category.parent_id == delete_id:
    143                  return category.update(parent_id=new_parent_id)
    144              else:
    145                  return category
    146
    147          def update_category_id(thing):
    148              if thing.category_id == delete_id:
    149                  return thing.update(category_id=new_parent_id)
    150              else:
    151                  return thing
    152          return self.update(
    153              categories=self.categories.remove(delete_id).map(update_parent_id),
    154              events=self.events.map(update_category_id),
    155              milestones=self.milestones.map(update_category_id),
    156              containers=self.containers.map(update_category_id)
    157          )
    158
    159 -    def save_container(self, container, id_):
    160          self._ensure_non_none_category_exists(container.category_id)
    161          return self.update(
    162              containers=self.containers.update({id_: container})
    163          )
    164
    165 -    def delete_container(self, delete_id):
    166          self._ensure_container_exists(delete_id)
    167
    168          def update_container_id(event):
    169              if event.container_id == delete_id:
    170                  return event.update(container_id=None)
    171              else:
    172                  return event
    173          return self.update(
    174              containers=self.containers.remove(delete_id),
    175              events=self.events.map(update_container_id),
    176          )
    177
    178 -    def _ensure_event_exists(self, id_):
    179          if id_ not in self.events:
    180              raise InvalidOperationError(
    181                  "Event with id {0!r} does not exist".format(id_)
    182              )
    183
    184 -    def _ensure_milestone_exists(self, id_):
    185          if id_ not in self.milestones:
    186              raise InvalidOperationError(
    187                  "Milestone with id {0!r} does not exist".format(id_)
    188              )
    189
    190 -    def _ensure_era_exists(self, id_):
    191          if id_ not in self.eras:
    192              raise InvalidOperationError(
    193                  "Era with id {0!r} does not exist".format(id_)
    194              )
    195
    196 -    def _ensure_category_name_is_unique(self, save_id, save_name):
    197          for id_, category in self.categories:
    198              if id_ != save_id and category.name == save_name:
    199                  raise InvalidOperationError(
    200                      "Category name {0!r} is not unique".format(save_name)
    201                  )
    202
    203 -    def _ensure_non_none_category_exists(self, id_):
    204          if id_ is not None:
    205              self._ensure_category_exists(id_)
    206
    207 -    def _ensure_category_exists(self, id_):
    208          if id_ not in self.categories:
    209              raise InvalidOperationError(
    210                  "Category with id {0!r} does not exist".format(id_)
    211              )
    212
    213 -    def _ensure_no_category_circular(self, save_id, parent_id):
    214          while parent_id is not None:
    215              if parent_id == save_id:
    216                  raise InvalidOperationError(
    217                      "Circular category parent"
    218                  )
    219              else:
    220                  parent_id = self.categories.get(parent_id).parent_id
    221
    222 -    def _ensure_non_none_container_exists(self, id_):
    223          if id_ is not None:
    224              self._ensure_container_exists(id_)
    225
    226 -    def _ensure_container_exists(self, id_):
    227          if id_ not in self.containers:
    228              raise InvalidOperationError(
    229                  "Container with id {0!r} does not exist".format(id_)
    230              )
    231
    232
    233 -class InvalidOperationError(Exception):
    234      pass
    235