Se my reply to your comment below.

Diff comments:

> === modified file 'openlp/.version'
> --- openlp/.version   2015-02-21 20:05:25 +0000
> +++ openlp/.version   2015-05-27 08:50:25 +0000
> @@ -1,1 +1,1 @@
> -2.1.3
> +2.1.4
> 
> === modified file 'openlp/core/ui/mainwindow.py'
> --- openlp/core/ui/mainwindow.py      2015-02-21 20:05:25 +0000
> +++ openlp/core/ui/mainwindow.py      2015-05-27 08:50:25 +0000
> @@ -900,7 +900,10 @@
>          for section_key in import_keys:
>              if 'eneral' in section_key:
>                  section_key = section_key.lower()
> -            value = import_settings.value(section_key)
> +            try:
> +                value = import_settings.value(section_key)
> +            except KeyError:
> +                log.warning('The key "%s" does not exist (anymore), so it 
> will be skipped.' % section_key)
>              if value is not None:
>                  settings.setValue('%s' % (section_key), value)
>          now = datetime.now()
> 
> === modified file 'openlp/core/ui/slidecontroller.py'
> --- openlp/core/ui/slidecontroller.py 2015-05-25 19:31:12 +0000
> +++ openlp/core/ui/slidecontroller.py 2015-05-27 08:50:25 +0000
> @@ -828,8 +828,10 @@
>          self.selected_row = 0
>          # take a copy not a link to the servicemanager copy.
>          self.service_item = copy.copy(service_item)
> -        if old_item and self.is_live and 
> old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
> -            self._reset_blank()
> +        # Reset blanking if needed
> +        if old_item and self.is_live and 
> (old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or
> +                                          
> self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay)):
> +            
> self._reset_blank(self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay))
>          if service_item.is_command():
>              Registry().execute(
>                  '%s_start' % service_item.name.lower(), [self.service_item, 
> self.is_live, self.hide_mode(), slide_no])
> @@ -1080,6 +1082,7 @@
>                                 % timeout)
>              return
>          row = self.preview_widget.current_slide_number()
> +        old_selected_row = self.selected_row
>          self.selected_row = 0
>          if -1 < row < self.preview_widget.slide_count():
>              if self.service_item.is_command():
> @@ -1089,7 +1092,7 @@
>              else:
>                  to_display = self.service_item.get_rendered_frame(row)
>                  if self.service_item.is_text():
> -                    self.display.text(to_display)
> +                    self.display.text(to_display, row != old_selected_row)
>                  else:
>                      if start:
>                          self.display.build_html(self.service_item, 
> to_display)
> @@ -1119,8 +1122,7 @@
>          This updates the preview frame, for example after changing a slide 
> or using *Blank to Theme*.
>          """
>          self.log_debug('update_preview %s ' % 
> self.screens.current['primary'])
> -        if not self.screens.current['primary'] and self.service_item and \
> -                
> self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
> +        if self.service_item and 
> self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
>              # Grab now, but try again in a couple of seconds if slide change 
> is slow
>              QtCore.QTimer.singleShot(0.5, self.grab_maindisplay)
>              QtCore.QTimer.singleShot(2.5, self.grab_maindisplay)
> @@ -1349,7 +1351,11 @@
>  
>          :param item: The service item to be processed
>          """
> -        self.media_controller.video(self.controller_type, item, 
> self.hide_mode())
> +        if self.is_live and self.hide_mode() == HideMode.Theme:
> +            self.media_controller.video(self.controller_type, item, 
> HideMode.Blank)
> +            self.on_blank_display(True)
> +        else:
> +            self.media_controller.video(self.controller_type, item, 
> self.hide_mode())
>          if not self.is_live:
>              self.preview_display.show()
>              self.slide_preview.hide()
> @@ -1362,16 +1368,22 @@
>          self.preview_display.hide()
>          self.slide_preview.show()
>  
> -    def _reset_blank(self):
> +    def _reset_blank(self, no_theme):

I don't see why it should? In most cases the value will indeed be False, but 
this is a "private" method (or whatever we call methods only intended for 
internal class use), and is (so far) only used once, so I don't see the need...

>          """
>          Used by command items which provide their own displays to reset the
>          screen hide attributes
> +
> +        :param no_theme: Does the new item support theme-blanking.
>          """
>          hide_mode = self.hide_mode()
>          if hide_mode == HideMode.Blank:
>              self.on_blank_display(True)
>          elif hide_mode == HideMode.Theme:
> -            self.on_theme_display(True)
> +            # The new item-type doesn't support theme-blanking, so 'switch' 
> to normal blanking.
> +            if no_theme:
> +                self.on_blank_display(True)
> +            else:
> +                self.on_theme_display(True)
>          elif hide_mode == HideMode.Screen:
>              self.on_hide_display(True)
>          else:
> 
> === modified file 'openlp/plugins/bibles/lib/mediaitem.py'
> --- openlp/plugins/bibles/lib/mediaitem.py    2015-04-07 22:01:52 +0000
> +++ openlp/plugins/bibles/lib/mediaitem.py    2015-05-27 08:50:25 +0000
> @@ -193,7 +193,7 @@
>          self.add_search_fields('quick', translate('BiblesPlugin.MediaItem', 
> 'Quick'))
>          self.quickTab.setVisible(True)
>          # Add the Advanced Search tab.
> -        self.add_search_tab('advanced', UiStrings().Advanced)
> +        self.add_search_tab('advanced', translate('BiblesPlugin.MediaItem', 
> 'Advanced'))
>          self.advanced_book_label = QtGui.QLabel(self.advancedTab)
>          self.advanced_book_label.setObjectName('advanced_book_label')
>          self.advancedLayout.addWidget(self.advanced_book_label, 0, 0, 
> QtCore.Qt.AlignRight)
> 
> === modified file 'openlp/plugins/presentations/lib/messagelistener.py'
> --- openlp/plugins/presentations/lib/messagelistener.py       2015-03-26 
> 14:17:14 +0000
> +++ openlp/plugins/presentations/lib/messagelistener.py       2015-05-27 
> 08:50:25 +0000
> @@ -243,6 +243,9 @@
>          Instruct the controller to stop and hide the presentation.
>          """
>          log.debug('Live = %s, stop' % self.is_live)
> +        # Save the current slide number to be able to return to this slide 
> if the presentation is activated again.
> +        if self.doc.is_active():
> +            self.doc.slidenumber = self.doc.get_slide_number()
>          self.hide_mode = HideMode.Screen
>          if not self.doc:
>              return
> @@ -266,8 +269,6 @@
>              return
>          if not self.activate():
>              return
> -        if self.doc.slidenumber and self.doc.slidenumber != 
> self.doc.get_slide_number():
> -            self.doc.goto_slide(self.doc.slidenumber)
>          self.doc.unblank_screen()
>          Registry().execute('live_display_hide', HideMode.Screen)
>  
> 
> === modified file 'openlp/plugins/presentations/lib/powerpointcontroller.py'
> --- openlp/plugins/presentations/lib/powerpointcontroller.py  2015-04-02 
> 08:33:46 +0000
> +++ openlp/plugins/presentations/lib/powerpointcontroller.py  2015-05-27 
> 08:50:25 +0000
> @@ -32,12 +32,15 @@
>  from openlp.core.common import is_win, Settings
>  
>  if is_win():
> -    from win32com.client import Dispatch
> +    from win32com.client import DispatchWithEvents
>      import win32com
> +    import win32con
>      import winreg
>      import win32ui
> +    import win32gui
>      import pywintypes
>  
> +
>  from openlp.core.lib import ScreenList
>  from openlp.core.lib.ui import UiStrings, critical_error_message_box, 
> translate
>  from openlp.core.common import trace_error_handler, Registry
> @@ -70,8 +73,18 @@
>          if is_win():
>              try:
>                  winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, 
> 'PowerPoint.Application').Close()
> +                try:
> +                    # Try to detect if the version is 12 (2007) or above, 
> and if so add 'odp' as a support filetype
> +                    version_key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, 
> 'PowerPoint.Application\\CurVer')
> +                    tmp1, app_version_string, tmp2 = 
> winreg.EnumValue(version_key, 0)
> +                    version_key.Close()
> +                    app_version = int(app_version_string[-2:])
> +                    if app_version >= 12:
> +                        self.also_supports = ['odp']
> +                except (OSError, ValueError):
> +                    log.warning('Detection of powerpoint version using 
> registry failed.')
>                  return True
> -            except WindowsError:
> +            except OSError:
>                  pass
>          return False
>  
> @@ -80,12 +93,22 @@
>              """
>              Loads PowerPoint process.
>              """
> +            class PowerPointEvents:
> +                """
> +                Class to catch events from PowerPoint.
> +                """
> +                def OnSlideShowNextClick(self, slideshow_window, effect):
> +                    """
> +                    Occurs on the next click of the slide.
> +                    If the main OpenLP window is not in focus force update 
> of the slidecontroller.
> +                    """
> +                    if not Registry().get('main_window').isActiveWindow():
> +                        log.debug('main window is not in focus - should 
> update slidecontroller')
> +                        Registry().execute('slidecontroller_live_change', 
> slideshow_window.View.CurrentShowPosition)
> +
>              log.debug('start_process')
>              if not self.process:
> -                self.process = Dispatch('PowerPoint.Application')
> -            self.process.Visible = True
> -            # ppWindowMinimized = 2
> -            self.process.WindowState = 2
> +                self.process = DispatchWithEvents('PowerPoint.Application', 
> PowerPointEvents)
>  
>          def kill(self):
>              """
> @@ -124,6 +147,9 @@
>          self.presentation = None
>          self.index_map = {}
>          self.slide_count = 0
> +        self.blank_slide = 1
> +        self.blank_click = None
> +        self.presentation_hwnd = None
>  
>      def load_presentation(self):
>          """
> @@ -132,23 +158,15 @@
>          """
>          log.debug('load_presentation')
>          try:
> -            if not self.controller.process or not 
> self.controller.process.Visible:
> +            if not self.controller.process:
>                  self.controller.start_process()
> -            self.controller.process.Presentations.Open(self.file_path, 
> False, False, True)
> +            
> self.controller.process.Presentations.Open(os.path.normpath(self.file_path), 
> False, False, False)
>              self.presentation = 
> self.controller.process.Presentations(self.controller.process.Presentations.Count)
>              self.create_thumbnails()
>              self.create_titles_and_notes()
> -            # Powerpoint 2010 and 2013 pops up when loading a file, so we 
> minimize it again
> -            if float(self.presentation.Application.Version) >= 14.0:
> -                try:
> -                    # ppWindowMinimized = 2
> -                    self.presentation.Application.WindowState = 2
> -                except (AttributeError, pywintypes.com_error) as e:
> -                    log.exception('Failed to minimize main powerpoint 
> window')
> -                    log.exception(e)
> -                    trace_error_handler(log)
> -            # Make sure powerpoint doesn't steal focus
> -            Registry().get('main_window').activateWindow()
> +            # Make sure powerpoint doesn't steal focus, unless we're on a 
> single screen setup
> +            if len(ScreenList().screen_list) > 1:
> +                Registry().get('main_window').activateWindow()
>              return True
>          except (AttributeError, pywintypes.com_error) as e:
>              log.exception('Exception caught while loading Powerpoint 
> presentation')
> @@ -194,8 +212,9 @@
>                  trace_error_handler(log)
>          self.presentation = None
>          self.controller.remove_doc(self)
> -        # Make sure powerpoint doesn't steal focus
> -        Registry().get('main_window').activateWindow()
> +        # Make sure powerpoint doesn't steal focus, unless we're on a single 
> screen setup
> +        if len(ScreenList().screen_list) > 1:
> +            Registry().get('main_window').activateWindow()
>  
>      def is_loaded(self):
>          """
> @@ -203,10 +222,6 @@
>          """
>          log.debug('is_loaded')
>          try:
> -            if not self.controller.process.Visible:
> -                return False
> -            if self.controller.process.Windows.Count == 0:
> -                return False
>              if self.controller.process.Presentations.Count == 0:
>                  return False
>          except (AttributeError, pywintypes.com_error) as e:
> @@ -241,13 +256,11 @@
>          """
>          log.debug('unblank_screen')
>          try:
> -            self.presentation.SlideShowSettings.Run()
> -            # ppSlideShowRunning = 1
> +            self.presentation.SlideShowWindow.Activate()
>              self.presentation.SlideShowWindow.View.State = 1
> -            self.presentation.SlideShowWindow.Activate()
> -            # Unblanking is broken in PowerPoint 2010 and 2013, need to 
> redisplay
> -            if float(self.presentation.Application.Version) >= 14.0:
> -                
> self.presentation.SlideShowWindow.View.GotoSlide(self.blank_slide, False)
> +            # Unblanking is broken in PowerPoint 2010 (14.0), need to 
> redisplay
> +            if 15.0 > float(self.presentation.Application.Version) >= 14.0:
> +                
> self.presentation.SlideShowWindow.View.GotoSlide(self.index_map[self.blank_slide],
>  False)
>                  if self.blank_click:
>                      
> self.presentation.SlideShowWindow.View.GotoClick(self.blank_click)
>          except (AttributeError, pywintypes.com_error) as e:
> @@ -255,8 +268,12 @@
>              log.exception(e)
>              trace_error_handler(log)
>              self.show_error_msg()
> -        # Make sure powerpoint doesn't steal focus
> -        Registry().get('main_window').activateWindow()
> +        # Stop powerpoint from flashing in the taskbar
> +        if self.presentation_hwnd:
> +            win32gui.FlashWindowEx(self.presentation_hwnd, 
> win32con.FLASHW_STOP, 0, 0)
> +        # Make sure powerpoint doesn't steal focus, unless we're on a single 
> screen setup
> +        if len(ScreenList().screen_list) > 1:
> +            Registry().get('main_window').activateWindow()
>  
>      def blank_screen(self):
>          """
> @@ -264,8 +281,8 @@
>          """
>          log.debug('blank_screen')
>          try:
> -            # Unblanking is broken in PowerPoint 2010 and 2013, need to save 
> info for later
> -            if float(self.presentation.Application.Version) >= 14.0:
> +            # Unblanking is broken in PowerPoint 2010 (14.0), need to save 
> info for later
> +            if 15.0 > float(self.presentation.Application.Version) >= 14.0:
>                  self.blank_slide = self.get_slide_number()
>                  self.blank_click = 
> self.presentation.SlideShowWindow.View.GetClickIndex()
>              # ppSlideShowBlackScreen = 3
> @@ -295,7 +312,7 @@
>  
>      def stop_presentation(self):
>          """
> -        Stops the current presentation and hides the output.
> +        Stops the current presentation and hides the output. Used when 
> blanking to desktop.
>          """
>          log.debug('stop_presentation')
>          try:
> @@ -321,28 +338,52 @@
>                  except win32ui.error:
>                      dpi = 96
>              size = ScreenList().current['size']
> -            ppt_window = self.presentation.SlideShowSettings.Run()
> -            if not ppt_window:
> -                return
> +            ppt_window = None
>              try:
> -                ppt_window.Top = size.y() * 72 / dpi
> -                ppt_window.Height = size.height() * 72 / dpi
> -                ppt_window.Left = size.x() * 72 / dpi
> -                ppt_window.Width = size.width() * 72 / dpi
> -            except AttributeError as e:
> -                log.exception('AttributeError while in start_presentation')
> +                ppt_window = self.presentation.SlideShowSettings.Run()
> +            except (AttributeError, pywintypes.com_error) as e:
> +                log.exception('Caught exception while in start_presentation')
>                  log.exception(e)
> -            # Powerpoint 2010 and 2013 pops up when starting a file, so we 
> minimize it again
> -            if float(self.presentation.Application.Version) >= 14.0:
> +                trace_error_handler(log)
> +                self.show_error_msg()
> +            if ppt_window and not Settings().value('presentations/powerpoint 
> control window'):
>                  try:
> -                    # ppWindowMinimized = 2
> -                    self.presentation.Application.WindowState = 2
> -                except (AttributeError, pywintypes.com_error) as e:
> -                    log.exception('Failed to minimize main powerpoint 
> window')
> +                    ppt_window.Top = size.y() * 72 / dpi
> +                    ppt_window.Height = size.height() * 72 / dpi
> +                    ppt_window.Left = size.x() * 72 / dpi
> +                    ppt_window.Width = size.width() * 72 / dpi
> +                except AttributeError as e:
> +                    log.exception('AttributeError while in 
> start_presentation')
>                      log.exception(e)
> -                    trace_error_handler(log)
> -            # Make sure powerpoint doesn't steal focus
> -            Registry().get('main_window').activateWindow()
> +            # Find the presentation window and save the handle for later
> +            self.presentation_hwnd = None
> +            if ppt_window:
> +                log.debug('main display size:  y=%d, height=%d, x=%d, 
> width=%d'
> +                          % (size.y(), size.height(), size.x(), 
> size.width()))
> +                win32gui.EnumWindows(self._window_enum_callback, size)
> +            # Make sure powerpoint doesn't steal focus, unless we're on a 
> single screen setup
> +            if len(ScreenList().screen_list) > 1:
> +                Registry().get('main_window').activateWindow()
> +
> +    def _window_enum_callback(self, hwnd, size):
> +        """
> +        Method for callback from win32gui.EnumWindows.
> +        Used to find the powerpoint presentation window and stop it flashing 
> in the taskbar.
> +        """
> +        # Get the size of the current window and if it matches the size of 
> our main display we assume
> +        # it is the powerpoint presentation window.
> +        (left, top, right, bottom) = win32gui.GetWindowRect(hwnd)
> +        window_title = win32gui.GetWindowText(hwnd)
> +        log.debug('window size:  left=%d, top=%d, right=%d, width=%d' % 
> (left, top, right, bottom))
> +        log.debug('compare size:  %d and %d, %d and %d, %d and %d, %d and %d'
> +                  % (size.y(), top, size.height(), (bottom - top), size.x(), 
> left, size.width(), (right - left)))
> +        log.debug('window title: %s' % window_title)
> +        if size.y() == top and size.height() == (bottom - top) and size.x() 
> == left and \
> +                size.width() == (right - left) and 
> os.path.basename(self.file_path) in window_title:
> +            log.debug('Found a match and will save the handle')
> +            self.presentation_hwnd = hwnd
> +            # Stop powerpoint from flashing in the taskbar
> +            win32gui.FlashWindowEx(self.presentation_hwnd, 
> win32con.FLASHW_STOP, 0, 0)
>  
>      def get_slide_number(self):
>          """
> @@ -384,7 +425,7 @@
>          log.debug('goto_slide')
>          try:
>              if Settings().value('presentations/powerpoint slide click 
> advance') \
> -                    and self.get_slide_number() == self.index_map[slide_no]:
> +                    and self.get_slide_number() == slide_no:
>                  click_index = 
> self.presentation.SlideShowWindow.View.GetClickIndex()
>                  click_count = 
> self.presentation.SlideShowWindow.View.GetClickCount()
>                  log.debug('We are already on this slide - go to next effect 
> if any left, idx: %d, count: %d'
> @@ -405,6 +446,7 @@
>          """
>          log.debug('next_step')
>          try:
> +            self.presentation.SlideShowWindow.Activate()
>              self.presentation.SlideShowWindow.View.Next()
>          except (AttributeError, pywintypes.com_error) as e:
>              log.exception('Caught exception while in next_step')
> @@ -415,6 +457,12 @@
>          if self.get_slide_number() > self.get_slide_count():
>              log.debug('past end, stepping back to previous')
>              self.previous_step()
> +        # Stop powerpoint from flashing in the taskbar
> +        if self.presentation_hwnd:
> +            win32gui.FlashWindowEx(self.presentation_hwnd, 
> win32con.FLASHW_STOP, 0, 0)
> +        # Make sure powerpoint doesn't steal focus, unless we're on a single 
> screen setup
> +        if len(ScreenList().screen_list) > 1:
> +            Registry().get('main_window').activateWindow()
>  
>      def previous_step(self):
>          """
> @@ -490,8 +538,12 @@
>      :param shapes: A set of shapes to search for text.
>      """
>      text = ''
> -    for shape in shapes:
> -        if shape.PlaceholderFormat.Type == 2:  # 2 from is enum 
> PpPlaceholderType.ppPlaceholderBody
> -            if shape.HasTextFrame and shape.TextFrame.HasText:
> -                text += shape.TextFrame.TextRange.Text + '\n'
> +    try:
> +        for shape in shapes:
> +            if shape.PlaceholderFormat.Type == 2:  # 2 from is enum 
> PpPlaceholderType.ppPlaceholderBody
> +                if shape.HasTextFrame and shape.TextFrame.HasText:
> +                    text += shape.TextFrame.TextRange.Text + '\n'
> +    except pywintypes.com_error as e:
> +        log.warning('Failed to extract text from powerpoint slide')
> +        log.warning(e)
>      return text
> 
> === modified file 'openlp/plugins/presentations/lib/presentationtab.py'
> --- openlp/plugins/presentations/lib/presentationtab.py       2015-04-02 
> 08:33:46 +0000
> +++ openlp/plugins/presentations/lib/presentationtab.py       2015-05-27 
> 08:50:25 +0000
> @@ -74,8 +74,11 @@
>          self.powerpoint_layout = QtGui.QVBoxLayout(self.powerpoint_group_box)
>          self.powerpoint_layout.setObjectName('powerpoint_layout')
>          self.ppt_slide_click_check_box = 
> QtGui.QCheckBox(self.powerpoint_group_box)
> -        self.powerpoint_group_box.setObjectName('ppt_slide_click_check_box')
> +        
> self.ppt_slide_click_check_box.setObjectName('ppt_slide_click_check_box')
>          self.powerpoint_layout.addWidget(self.ppt_slide_click_check_box)
> +        self.ppt_window_check_box = 
> QtGui.QCheckBox(self.powerpoint_group_box)
> +        self.ppt_window_check_box.setObjectName('ppt_window_check_box')
> +        self.powerpoint_layout.addWidget(self.ppt_window_check_box)
>          self.left_layout.addWidget(self.powerpoint_group_box)
>          # Pdf options
>          self.pdf_group_box = QtGui.QGroupBox(self.left_column)
> @@ -123,6 +126,9 @@
>          self.ppt_slide_click_check_box.setText(
>              translate('PresentationPlugin.PresentationTab',
>                        'Clicking on a selected slide in the slidecontroller 
> advances to next effect.'))
> +        self.ppt_window_check_box.setText(
> +            translate('PresentationPlugin.PresentationTab',
> +                      'Let PowerPoint control the size and position of the 
> presentation window.'))
>          self.pdf_program_check_box.setText(
>              translate('PresentationPlugin.PresentationTab', 'Use given full 
> path for mudraw or ghostscript binary:'))
>  
> @@ -148,6 +154,8 @@
>          
> self.ppt_slide_click_check_box.setChecked(Settings().value(self.settings_section
>  +
>                                                                     
> '/powerpoint slide click advance'))
>          self.ppt_slide_click_check_box.setEnabled(powerpoint_available)
> +        
> self.ppt_window_check_box.setChecked(Settings().value(self.settings_section + 
> '/powerpoint control window'))
> +        self.ppt_window_check_box.setEnabled(powerpoint_available)
>          # load pdf-program settings
>          enable_pdf_program = Settings().value(self.settings_section + 
> '/enable_pdf_program')
>          self.pdf_program_check_box.setChecked(enable_pdf_program)
> @@ -186,6 +194,10 @@
>          if Settings().value(setting_key) != 
> self.ppt_slide_click_check_box.checkState():
>              Settings().setValue(setting_key, 
> self.ppt_slide_click_check_box.checkState())
>              changed = True
> +        setting_key = self.settings_section + '/powerpoint control window'
> +        if Settings().value(setting_key) != 
> self.ppt_window_check_box.checkState():
> +            Settings().setValue(setting_key, 
> self.ppt_window_check_box.checkState())
> +            changed = True
>          # Save pdf-settings
>          pdf_program = self.pdf_program_path.text()
>          enable_pdf_program = self.pdf_program_check_box.checkState()
> 
> === modified file 'openlp/plugins/presentations/presentationplugin.py'
> --- openlp/plugins/presentations/presentationplugin.py        2015-03-26 
> 14:22:23 +0000
> +++ openlp/plugins/presentations/presentationplugin.py        2015-05-27 
> 08:50:25 +0000
> @@ -45,7 +45,8 @@
>                          'presentations/Pdf': QtCore.Qt.Checked,
>                          'presentations/presentations files': [],
>                          'presentations/thumbnail_scheme': '',
> -                        'presentations/powerpoint slide click advance': 
> QtCore.Qt.Unchecked
> +                        'presentations/powerpoint slide click advance': 
> QtCore.Qt.Unchecked,
> +                        'presentations/powerpoint control window': 
> QtCore.Qt.Unchecked
>                          }
>  
>  
> 
> === modified file 'openlp/plugins/songs/lib/importers/worshipassistant.py'
> --- openlp/plugins/songs/lib/importers/worshipassistant.py    2015-03-09 
> 20:57:39 +0000
> +++ openlp/plugins/songs/lib/importers/worshipassistant.py    2015-05-27 
> 08:50:25 +0000
> @@ -131,6 +131,7 @@
>                  return
>              verse = ''
>              used_verses = []
> +            verse_id = VerseType.tags[VerseType.Verse] + '1'
>              for line in lyrics.splitlines():
>                  if line.startswith('['):  # verse marker
>                      # Add previous verse
> 
> === modified file 
> 'tests/functional/openlp_plugins/presentations/test_powerpointcontroller.py'
> --- 
> tests/functional/openlp_plugins/presentations/test_powerpointcontroller.py    
>     2015-04-02 08:33:46 +0000
> +++ 
> tests/functional/openlp_plugins/presentations/test_powerpointcontroller.py    
>     2015-05-27 08:50:25 +0000
> @@ -164,45 +164,42 @@
>          """
>          Test creating the titles from PowerPoint
>          """
> -        if is_win() and self.real_controller.check_available():
> -            # GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and 
> two mocked slides
> -            self.doc = PowerpointDocument(self.real_controller, 
> self.file_name)
> -            self.doc.save_titles_and_notes = MagicMock()
> -            self.doc._PowerpointDocument__get_text_from_shapes = MagicMock()
> -            slide = MagicMock()
> -            slide.Shapes.Title.TextFrame.TextRange.Text = 'SlideText'
> -            pres = MagicMock()
> -            pres.Slides = [slide, slide]
> -            self.doc.presentation = pres
> -
> -            # WHEN reading the titles and notes
> -            self.doc.create_titles_and_notes()
> -
> -            # THEN the save should have been called exactly once with 2 
> titles and 2 notes
> -            
> self.doc.save_titles_and_notes.assert_called_once_with(['SlideText\n', 
> 'SlideText\n'], [' ', ' '])
> -        else:
> -            self.skipTest('Powerpoint not available, skipping test.')
> +        # GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two 
> mocked slides
> +        self.doc = PowerpointDocument(self.mock_controller, self.file_name)
> +        self.doc.get_slide_count = MagicMock()
> +        self.doc.get_slide_count.return_value = 2
> +        self.doc.index_map = {1: 1, 2: 2}
> +        self.doc.save_titles_and_notes = MagicMock()
> +        self.doc._PowerpointDocument__get_text_from_shapes = MagicMock()
> +        slide = MagicMock()
> +        slide.Shapes.Title.TextFrame.TextRange.Text = 'SlideText'
> +        pres = MagicMock()
> +        pres.Slides = MagicMock(side_effect=[slide, slide])
> +        self.doc.presentation = pres
> +
> +        # WHEN reading the titles and notes
> +        self.doc.create_titles_and_notes()
> +
> +        # THEN the save should have been called exactly once with 2 titles 
> and 2 notes
> +        
> self.doc.save_titles_and_notes.assert_called_once_with(['SlideText\n', 
> 'SlideText\n'], [' ', ' '])
>  
>      def create_titles_and_notes_with_no_slides_test(self):
>          """
>          Test creating the titles from PowerPoint when it returns no slides
>          """
> -        if is_win() and self.real_controller.check_available():
> -            # GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and 
> two mocked slides
> -            doc = PowerpointDocument(self.real_controller, self.file_name)
> -            doc.save_titles_and_notes = MagicMock()
> -            doc._PowerpointDocument__get_text_from_shapes = MagicMock()
> -            pres = MagicMock()
> -            pres.Slides = []
> -            doc.presentation = pres
> -
> -            # WHEN reading the titles and notes
> -            doc.create_titles_and_notes()
> -
> -            # THEN the save should have been called exactly once with empty 
> titles and notes
> -            doc.save_titles_and_notes.assert_called_once_with([], [])
> -        else:
> -            self.skipTest('Powerpoint not available, skipping test.')
> +        # GIVEN: mocked save_titles_and_notes, _get_text_from_shapes and two 
> mocked slides
> +        doc = PowerpointDocument(self.mock_controller, self.file_name)
> +        doc.save_titles_and_notes = MagicMock()
> +        doc._PowerpointDocument__get_text_from_shapes = MagicMock()
> +        pres = MagicMock()
> +        pres.Slides = []
> +        doc.presentation = pres
> +
> +        # WHEN reading the titles and notes
> +        doc.create_titles_and_notes()
> +
> +        # THEN the save should have been called exactly once with empty 
> titles and notes
> +        doc.save_titles_and_notes.assert_called_once_with([], [])
>  
>      def get_text_from_shapes_test(self):
>          """
> @@ -253,3 +250,54 @@
>  
>          # THEN: next_step() should be call to try to advance to the next 
> effect.
>          self.assertTrue(doc.next_step.called, 'next_step() should have been 
> called!')
> +
> +    def blank_screen_test(self):
> +        """
> +        Test that blank_screen works as expected
> +        """
> +        # GIVEN: A Document with mocked controller, presentation, and mocked 
> function get_slide_number
> +        doc = PowerpointDocument(self.mock_controller, 
> self.mock_presentation)
> +        doc.presentation = MagicMock()
> +        doc.presentation.SlideShowWindow.View.GetClickIndex.return_value = 3
> +        doc.presentation.Application.Version = 14.0
> +        doc.get_slide_number = MagicMock()
> +        doc.get_slide_number.return_value = 2
> +
> +        # WHEN: Calling goto_slide
> +        doc.blank_screen()
> +
> +        # THEN: The view state, doc.blank_slide and doc.blank_click should 
> have new values
> +        self.assertEquals(doc.presentation.SlideShowWindow.View.State, 3, 
> 'The View State should be 3')
> +        self.assertEquals(doc.blank_slide, 2, 'doc.blank_slide should be 2 
> because of the PowerPoint version')
> +        self.assertEquals(doc.blank_click, 3, 'doc.blank_click should be 3 
> because of the PowerPoint version')
> +
> +    def unblank_screen_test(self):
> +        """
> +        Test that unblank_screen works as expected
> +        """
> +        # GIVEN: A Document with mocked controller, presentation, 
> ScreenList, and mocked function get_slide_number
> +        with 
> patch('openlp.plugins.presentations.lib.powerpointcontroller.ScreenList') as 
> mocked_screen_list:
> +            mocked_screen_list_ret = MagicMock()
> +            mocked_screen_list_ret.screen_list = [1]
> +            mocked_screen_list.return_value = mocked_screen_list_ret
> +            doc = PowerpointDocument(self.mock_controller, 
> self.mock_presentation)
> +            doc.presentation = MagicMock()
> +            doc.presentation.SlideShowWindow.View.GetClickIndex.return_value 
> = 3
> +            doc.presentation.Application.Version = 14.0
> +            doc.get_slide_number = MagicMock()
> +            doc.get_slide_number.return_value = 2
> +            doc.index_map[1] = 1
> +            doc.blank_slide = 1
> +            doc.blank_click = 1
> +
> +            # WHEN: Calling goto_slide
> +            doc.unblank_screen()
> +
> +            # THEN: The view state have new value, and several function 
> should have been called
> +            self.assertEquals(doc.presentation.SlideShowWindow.View.State, 
> 1, 'The View State should be 1')
> +            
> self.assertEquals(doc.presentation.SlideShowWindow.Activate.called, True,
> +                              'SlideShowWindow.Activate should have been 
> called')
> +            
> self.assertEquals(doc.presentation.SlideShowWindow.View.GotoSlide.called, 
> True,
> +                              'View.GotoSlide should have been called 
> because of the PowerPoint version')
> +            
> self.assertEquals(doc.presentation.SlideShowWindow.View.GotoClick.called, 
> True,
> +                              'View.GotoClick should have been called 
> because of the PowerPoint version')
> 
> === modified file 
> 'tests/functional/openlp_plugins/songs/test_worshipassistantimport.py'
> --- tests/functional/openlp_plugins/songs/test_worshipassistantimport.py      
> 2015-01-22 17:42:29 +0000
> +++ tests/functional/openlp_plugins/songs/test_worshipassistantimport.py      
> 2015-05-27 08:50:25 +0000
> @@ -49,3 +49,5 @@
>                           
> self.load_external_result_data(os.path.join(TEST_PATH, 
> 'would_you_be_free.json')))
>          self.file_import(os.path.join(TEST_PATH, 'would_you_be_free2.csv'),
>                           
> self.load_external_result_data(os.path.join(TEST_PATH, 
> 'would_you_be_free.json')))
> +        self.file_import(os.path.join(TEST_PATH, 'lift_up_your_heads.csv'),
> +                         
> self.load_external_result_data(os.path.join(TEST_PATH, 
> 'lift_up_your_heads.json')))
> 
> === added file 'tests/resources/worshipassistantsongs/lift_up_your_heads.csv'
> --- tests/resources/worshipassistantsongs/lift_up_your_heads.csv      
> 1970-01-01 00:00:00 +0000
> +++ tests/resources/worshipassistantsongs/lift_up_your_heads.csv      
> 2015-05-27 08:50:25 +0000
> @@ -0,0 +1,40 @@
> +"SongID","SongNr","Title","Author","Copyright","FirstLine","PriKey","AltKey","Tempo","Focus","Theme","Scripture","Active","Songbook","TimeSig","Introduced","LastUsed","TimesUsed","CCLINr","User1","User2","User3","User4","User5","Roadmap","Overmap","FileLink1","FileLink2","Updated","Lyrics","Info","Lyrics2","Background"
> +"000013ab-0000-0000-0000-000000000000","0","Lift Up Your Heads"," Bryan 
> Mierau","Public Domain","Lift up your heads and the 
> doors","Em","NULL","NULL","NULL","NULL","NULL","1","1","NULL","NULL","NULL","0","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2004-04-07
>  06:36:18.952",".Em           D             C             D   
> + Lift up your heads and the doors of your heart
> +.        Am      B7              Em
> + And the King of glory will come in
> +(Repeat)
> +
> +.G                   Am  D
> + Who is this King of Glory?
> +.    B7              Em
> + The Lord strong and mighty!
> +.G                   Am    D
> + Who is this King of Glory?
> +.    B7        
> + The Lord, mighty in battle!
> +
> +.G                   Am   D
> + Who is this King of Glory?
> +.B7           Em
> + Jesus our Messiah!
> +.G                   Am  D 
> + Who is this King of Glory?
> +.B7             Em
> + Jesus, Lord of Lords!
> + 
> +","NULL","Lift up your heads and the doors of your heart
> +And the King of glory will come in
> +(Repeat)
> +
> +Who is this King of Glory?
> +The Lord strong and mighty!
> +Who is this King of Glory?
> +The Lord, mighty in battle!
> +
> +Who is this King of Glory?
> +Jesus our Messiah!
> +Who is this King of Glory?
> +Jesus, Lord of Lords!
> +
> +","NULL"
> 
> === added file 'tests/resources/worshipassistantsongs/lift_up_your_heads.json'
> --- tests/resources/worshipassistantsongs/lift_up_your_heads.json     
> 1970-01-01 00:00:00 +0000
> +++ tests/resources/worshipassistantsongs/lift_up_your_heads.json     
> 2015-05-27 08:50:25 +0000
> @@ -0,0 +1,13 @@
> +{
> +    "authors": [
> +        "Bryan Mierau"
> +    ],
> +    "title": "Lift Up Your Heads",
> +    "verse_order_list": [],
> +    "verses": [
> +        [
> +            "Lift up your heads and the doors of your heart\nAnd the King of 
> glory will come in\n(Repeat)\n\nWho is this King of Glory?\nThe Lord strong 
> and mighty!\nWho is this King of Glory?\nThe Lord, mighty in battle!\n\nWho 
> is this King of Glory?\nJesus our Messiah!\nWho is this King of 
> Glory?\nJesus, Lord of Lords!\n",
> +            "v1"
> +        ]
> +    ]
> +}
> 


-- 
https://code.launchpad.net/~tomasgroth/openlp/bugfixes20/+merge/260252
Your team OpenLP Core is subscribed to branch lp:openlp.

_______________________________________________
Mailing list: https://launchpad.net/~openlp-core
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openlp-core
More help   : https://help.launchpad.net/ListHelp

Reply via email to