Gnumed.timelinelib.wxgui.dialogs.slideshow.controller

Package Gnumed :: Package timelinelib :: Package wxgui :: Package dialogs :: Package slideshow :: Module controller |
[frames] | no frames]

# Source Code for Module Gnumed.timelinelib.wxgui.dialogs.slideshow.controller

      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  import os
     20  import shutil
     21  import wx
     22  from timelinelib.wxgui.framework import Controller
     23  from timelinelib.wxgui.dialogs.slideshow.templates import CSS
     24  from timelinelib.wxgui.dialogs.slideshow.templates import IMAGE_AND_DESCRIPTION
     25  from timelinelib.wxgui.dialogs.slideshow.templates import ONLY_DESCRIPTION
     26  from timelinelib.wxgui.dialogs.slideshow.templates import PAGE_TEMPLATE
     27  from timelinelib.config.paths import ICONS_DIR
     28
     29
     30  DIR_IS_MANDATORY = _("The html pages directory is mandatory")
     31  CANT_FIND_DIR = _("Can't find the html pages directory!") + "\n" + _("Do you want to create it?")
     32  OVERWRITE_DIR = _("The html pages director isn't empty!") + "\n" + _("Do you want overwrite it?")
     33
     34
     35 -class SlideshowDialogController(Controller):
     36
     37 -    def on_init(self, db, canvas):
     38          self._db = db
     39          self._canvas = canvas
     40          self._text_transformer = self._install_text_transformer_plugin()
     41
     42 -    def on_change_dir(self, evt):
     43          self.view.ChangeDir()
     44
     45 -    def on_start(self, evt):
     46          if self._input_is_valid():
     47              self._create_and_start_slideshow()
     48              self.view.EndModalOk()
     49
     50 -    def _input_is_valid(self):
     51          if self._target_dir_not_given():
     52              self.view.InvalidTargetDir(DIR_IS_MANDATORY)
     53              return False
     54          if not self._target_dir_exists():
     55              if not self.view.GetUserAck(CANT_FIND_DIR):
     56                  return False
     57              os.mkdir(self.view.GetTargetDir())
     58          elif self._target_dir_is_not_empty():
     59              if not self.view.GetUserAck(OVERWRITE_DIR):
     60                  return False
     61          return True
     62
     63 -    def _target_dir_not_given(self):
     64          return len(self.view.GetTargetDir().strip()) == 0
     65
     66 -    def _target_dir_exists(self):
     67          return os.path.exists(self.view.GetTargetDir())
     68
     69 -    def _target_dir_is_not_empty(self):
     70          return len(os.listdir(self.view.GetTargetDir())) > 0
     71
     72 -    def _create_and_start_slideshow(self):
     73          events = self._get_events()
     74          if len(events) > 0:
     75              self._create_images(events)
     76              self._create_css()
     77              self._create_pages(events)
     78              self.view.DisplayStartPage(os.path.join(self.view.GetTargetDir(), "page_1.html"))
     79
     80 -    def _get_events(self):
     81          if self.view.AllEventsSelected():
     82              func = self._get_all_events
     83          else:
     84              func = self._get_visible_events
     85          return sorted([event for event in func() if not event.is_container()], key=lambda event: event.get_start_time())
     86
     87 -    def _get_all_events(self):
     88          return self._db.get_all_events()
     89
     90 -    def _get_visible_events(self):
     91          vp = self._canvas.get_view_properties()
     92          return vp.filter_events(self._db.get_events(vp.displayed_period))
     93
     94 -    def _create_images(self, events):
     95          shutil.copy(os.path.join(ICONS_DIR, "32.png"), os.path.join(self.view.GetTargetDir(), "32.png"))
     96          self._image_source = [""]
     97          inx = 0
     98          for event in events:
     99              inx += 1
    100              icon = event.get_icon()
    101              if icon:
    102                  icon.SaveFile(os.path.join(self.view.GetTargetDir(), "icon_img_%d.bmp" % inx), wx.BITMAP_TYPE_BMP)
    103                  self._image_source.append("icon_img_%d.bmp" % inx)
    104              else:
    105                  self._image_source.append("")
    106
    107 -    def _create_css(self):
    108          f = open(os.path.join(self.view.GetTargetDir(), "slideshow.css"), "w")
    109          f.write(CSS.encode('utf8', 'ignore'))
    110          f.close()
    111
    112 -    def _create_pages(self, events):
    113          nbr_of_pages = len(events)
    114          page_nbr = 0
    115          w1 = events[-1].get_start_time() - events[0].get_start_time()
    116          pos_style = self._get_positions_style(events)
    117          pos_history = self._get_position_history(len(events))
    118          for event in events:
    119              w2 = event.get_start_time() - events[0].get_start_time()
    120              p = self._calc_history_pos(w1, w2, events, event)
    121              page_nbr += 1
    122              next_page_nbr = self._get_next_page_nbr(page_nbr, nbr_of_pages)
    123              prev_page_nbr = self._get_prev_page_nbr(page_nbr, nbr_of_pages)
    124              self._create_page(pos_style, p, event, page_nbr, next_page_nbr, prev_page_nbr, pos_history)
    125
    126 -    def _calc_history_pos(self, w1, w2, events, event):
    127          w2 = event.get_start_time() - events[0].get_start_time()
    128          try:
    129              return 2 + int(90 * (w2 / w1))
    130          except ZeroDivisionError:
    131              return 2
    132
    133 -    def _get_next_page_nbr(self, page_nbr, nbr_of_pages):
    134          if page_nbr == nbr_of_pages:
    135              return 1
    136          else:
    137              return page_nbr + 1
    138
    139 -    def _get_prev_page_nbr(self, page_nbr, nbr_of_pages):
    140          if page_nbr == 1:
    141              return nbr_of_pages
    142          else:
    143              return page_nbr - 1
    144
    145 -    def _create_page(self, pos_style, p, event, page_nbr, next_page_nbr, prev_page_nbr, pos_history):
    146          f = open(os.path.join(self.view.GetTargetDir(), "page_%d.html" % page_nbr), "w")
    147          if self._image_source[page_nbr] == "":
    148              x = ONLY_DESCRIPTION % self._text_transformer.transform(event.get_description())
    149          else:
    150              x = IMAGE_AND_DESCRIPTION % (self._image_source[page_nbr],
    151                                           self._text_transformer.transform(event.get_description()))
    152          pg = PAGE_TEMPLATE % (pos_style,
    153                                p,
    154                                self._db.get_time_type().format_period(event.get_time_period()),
    155                                event.get_text(),
    156                                x,
    157                                prev_page_nbr,
    158                                next_page_nbr,
    159                                pos_history)
    160          f.write(pg.encode('utf8', 'ignore'))
    161          f.close()
    162
    163 -    def _install_text_transformer_plugin(self):
    164          from timelinelib.plugin import factory
    165          from timelinelib.plugin.factory import TEXT_TRANSFORMER
    166          from timelinelib.plugin.plugins.texttransformers.defaulttexttransformer import DefaultTextTransformer
    167          plugin = factory.get_plugin(TEXT_TRANSFORMER, "Plain text to HTML transformer") or DefaultTextTransformer()
    168          return plugin.run()
    169
    170 -    def _get_positions_style(self, events):
    171          template = """div.position_in_history_%d {
    172      border-radius: 50%%;
    173      width: 10px;
    174      height: 10px;
    175      background-color: #66CDAA;
    176      position: fixed;
    177      top: 10px;
    178      left: %d%%
    179  }
    180  """
    181          collector = []
    182          w1 = events[-1].get_start_time() - events[0].get_start_time()
    183          nbr = 0
    184          for event in events:
    185              nbr += 1
    186              w2 = event.get_start_time() - events[0].get_start_time()
    187              p = self._calc_history_pos(w1, w2, events, event)
    188              collector.append(template % (nbr, p))
    189          return "\n".join(collector)
    190
    191 -    def _get_position_history(self, count):
    192          template = '<div class="position_in_history_%d"/>'
    193          collector = []
    194          for i in range(count):
    195              collector.append(template % (i + 1))
    196          return "\n".join(collector)
    197