Add registry mixin and code cleanups

This commit is contained in:
Tim Bentley 2013-12-15 16:50:09 +00:00
parent e93b825ab4
commit e9a7850bc8
7 changed files with 240 additions and 157 deletions

View File

@ -162,7 +162,8 @@ class OpenLP(QtGui.QApplication):
self.shared_memory = QtCore.QSharedMemory('OpenLP')
if self.shared_memory.attach():
status = QtGui.QMessageBox.critical(None, UiStrings().Error, UiStrings().OpenLPStart,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No))
if status == QtGui.QMessageBox.No:
return True
return False
@ -248,16 +249,16 @@ def main(args=None):
usage = 'Usage: %prog [options] [qt-options]'
parser = OptionParser(usage=usage)
parser.add_option('-e', '--no-error-form', dest='no_error_form', action='store_true',
help='Disable the error notification form.')
help='Disable the error notification form.')
parser.add_option('-l', '--log-level', dest='loglevel', default='warning', metavar='LEVEL',
help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".')
help='Set logging to LEVEL level. Valid values are "debug", "info", "warning".')
parser.add_option('-p', '--portable', dest='portable', action='store_true',
help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).')
help='Specify if this should be run as a portable app, off a USB flash drive (not implemented).')
parser.add_option('-d', '--dev-version', dest='dev_version', action='store_true',
help='Ignore the version file and pull the version directly from Bazaar')
help='Ignore the version file and pull the version directly from Bazaar')
parser.add_option('-s', '--style', dest='style', help='Set the Qt4 style (passed directly to Qt4).')
# Parse command line options and deal with them.
# Use args supplied programatically if possible.
# Use args supplied pragmatically if possible.
(options, args) = parser.parse_args(args) if args else parser.parse_args()
qt_args = []
if options.loglevel.lower() in ['d', 'debug']:
@ -326,4 +327,3 @@ def main(args=None):
if not options.no_error_form:
sys.excepthook = application.hook_exception
sys.exit(application.run(qt_args))

View File

@ -55,6 +55,7 @@ def trace_error_handler(logger):
for tb in traceback.extract_stack():
logger.error('Called by ' + tb[3] + ' at line ' + str(tb[1]) + ' in ' + tb[0])
def check_directory_exists(directory, do_not_log=False):
"""
Check a theme directory exists and if not create it
@ -129,6 +130,7 @@ def de_hump(name):
from .openlpmixin import OpenLPMixin
from .registry import Registry
from .registrymixin import RegistryMixin
from .uistrings import UiStrings
from .settings import Settings
from .applocation import AppLocation

View File

@ -32,6 +32,8 @@ Provide Registry Services
import logging
import sys
from openlp.core.common import trace_error_handler
log = logging.getLogger(__name__)
@ -76,6 +78,7 @@ class Registry(object):
if key in self.service_list:
return self.service_list[key]
else:
trace_error_handler(log)
log.error('Service %s not found in list' % key)
raise KeyError('Service %s not found in list' % key)
@ -90,6 +93,7 @@ class Registry(object):
The service address to be saved.
"""
if key in self.service_list:
trace_error_handler(log)
log.error('Duplicate service exception %s' % key)
raise KeyError('Duplicate service exception %s' % key)
else:
@ -134,6 +138,7 @@ class Registry(object):
The function to be called when the event happens.
"""
if self.running_under_test is False:
trace_error_handler(log)
log.error('Invalid Method call for key %s' % event)
raise KeyError('Invalid Method call for key %s' % event)
if event in self.functions_list:
@ -161,7 +166,9 @@ class Registry(object):
results.append(result)
except TypeError:
# Who has called me can help in debugging
import inspect
log.debug(inspect.currentframe().f_back.f_locals)
trace_error_handler(log)
log.exception('Exception for function %s', function)
else:
trace_error_handler(log)
log.error("Event %s not called by not registered" % event)
return results

View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2013 Raoul Snyman #
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# This program 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; version 2 of the License. #
# #
# This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Provide Registry Services
"""
from openlp.core.common import Registry, de_hump
class RegistryMixin(object):
"""
This adds registry components to classes to use at run time.
"""
def __init__(self):
"""
Register the class and bootstrap hooks.
"""
Registry().register(de_hump(self.__class__.__name__), self)
Registry().register_function('bootstrap_initialise', self.bootstrap_initialise)
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
super().__init__()
def bootstrap_initialise(self):
"""
Dummy method to be overridden
"""
pass
def bootstrap_post_set_up(self):
"""
Dummy method to be overridden
"""
pass

View File

@ -34,10 +34,10 @@ import sys
import imp
from openlp.core.lib import Plugin, PluginStatus
from openlp.core.common import AppLocation, Registry, OpenLPMixin
from openlp.core.common import AppLocation, Registry, OpenLPMixin, RegistryMixin
class PluginManager(OpenLPMixin):
class PluginManager(OpenLPMixin, RegistryMixin):
"""
This is the Plugin manager, which loads all the plugins,
and executes all the hooks, as and when necessary.
@ -49,8 +49,6 @@ class PluginManager(OpenLPMixin):
"""
super(PluginManager, self).__init__()
self.log_info('Plugin manager Initialising')
Registry().register('plugin_manager', self)
Registry().register_function('bootstrap_initialise', self.bootstrap_initialise)
self.base_path = os.path.abspath(AppLocation.get_directory(AppLocation.PluginsDir))
self.log_debug('Base path %s ' % self.base_path)
self.plugins = []

View File

@ -41,14 +41,13 @@ from datetime import datetime
from PyQt4 import QtCore, QtGui
from openlp.core.common import Registry
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, translate
from openlp.core.lib import Renderer, OpenLPDockWidget, PluginManager, ImageManager, PluginStatus, ScreenList, \
build_icon
from openlp.core.lib.ui import UiStrings, create_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, SlideController, PluginForm, \
MediaDockManager, ShortcutListForm, FormattingTagForm
from openlp.core.common import AppLocation, Settings, check_directory_exists, translate
from openlp.core.ui.media import MediaController
from openlp.core.utils import LanguageManager, add_actions, get_application_version
from openlp.core.utils.actions import ActionList, CategoryOrder

View File

@ -37,7 +37,7 @@ from collections import deque
from PyQt4 import QtCore, QtGui
from openlp.core.common import Registry, Settings, SlideLimits, UiStrings, translate
from openlp.core.common import Registry, Settings, SlideLimits, UiStrings, translate, RegistryMixin, OpenLPMixin
from openlp.core.lib import OpenLPToolbar, ItemCapabilities, ServiceItem, ImageSource, ServiceItemAction, \
ScreenList, build_icon, build_html
from openlp.core.ui import HideMode, MainDisplay, Display, DisplayControllerType
@ -48,7 +48,7 @@ from openlp.core.ui.listpreviewwidget import ListPreviewWidget
log = logging.getLogger(__name__)
# Threshold which has to be trespassed to toggle.
HIDE_MENU_THRESHOLD = 27
HIDE_MENU_THRESHOLD = 27
AUDIO_TIME_LABEL_STYLESHEET = 'background-color: palette(background); ' \
'border-top-color: palette(shadow); ' \
'border-left-color: palette(shadow); ' \
@ -57,6 +57,24 @@ AUDIO_TIME_LABEL_STYLESHEET = 'background-color: palette(background); ' \
'border-radius: 3px; border-style: inset; ' \
'border-width: 1; font-family: monospace; margin: 2px;'
NARROW_MENU = [
'hide_menu'
]
LOOP_LIST = [
'play_slides_menu',
'loop_separator',
'delay_spin_box'
]
AUDIO_LIST = [
'audioPauseItem',
'audio_time_label'
]
WIDE_MENU = [
'blank_screen_button',
'theme_screen_button',
'desktop_screen_button'
]
class DisplayController(QtGui.QWidget):
"""
@ -92,30 +110,12 @@ class SlideController(DisplayController):
Set up the Slide Controller.
"""
super(SlideController, self).__init__(parent, is_live)
Registry().register_function('bootstrap_post_set_up', self.screen_size_changed)
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
self.screens = ScreenList()
try:
self.ratio = self.screens.current['size'].width() / self.screens.current['size'].height()
except ZeroDivisionError:
self.ratio = 1
self.loop_list = [
'play_slides_menu',
'loop_separator',
'delay_spin_box'
]
# audioPauseItem is also in Settings so any changes need to be paired
self.audio_list = [
'audioPauseItem',
'audio_time_label'
]
self.wide_menu = [
'blank_screen_button',
'theme_screen_button',
'desktop_screen_button'
]
self.narrow_menu = [
'hide_menu'
]
self.timer_id = 0
self.song_edit = False
self.selected_row = 0
@ -123,7 +123,7 @@ class SlideController(DisplayController):
self.slide_limits = None
self.update_slide_limits()
self.panel = QtGui.QWidget(parent.control_splitter)
self.slideList = {}
self.slide_list = {}
self.slide_count = 0
self.slide_image = None
# Layout for holding panel
@ -172,17 +172,19 @@ class SlideController(DisplayController):
size_toolbar_policy.setHeightForWidth(self.toolbar.sizePolicy().hasHeightForWidth())
self.toolbar.setSizePolicy(size_toolbar_policy)
self.previous_item = create_action(self, 'previousItem_' + self.type_prefix,
text=translate('OpenLP.SlideController', 'Previous Slide'), icon=':/slides/slide_previous.png',
tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.on_slide_selected_previous)
text=translate('OpenLP.SlideController', 'Previous Slide'),
icon=':/slides/slide_previous.png',
tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.on_slide_selected_previous)
self.toolbar.addAction(self.previous_item)
self.nextItem = create_action(self, 'nextItem_' + self.type_prefix,
text=translate('OpenLP.SlideController', 'Next Slide'), icon=':/slides/slide_next.png',
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.on_slide_selected_next_action)
self.toolbar.addAction(self.nextItem)
self.next_item = create_action(self, 'nextItem_' + self.type_prefix,
text=translate('OpenLP.SlideController', 'Next Slide'),
icon=':/slides/slide_next.png',
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.on_slide_selected_next_action)
self.toolbar.addAction(self.next_item)
self.toolbar.addSeparator()
self.controller_type = DisplayControllerType.Preview
if self.is_live:
@ -195,16 +197,20 @@ class SlideController(DisplayController):
self.hide_menu.setMenu(QtGui.QMenu(translate('OpenLP.SlideController', 'Hide'), self.toolbar))
self.toolbar.add_toolbar_widget(self.hide_menu)
self.blank_screen = create_action(self, 'blankScreen',
text=translate('OpenLP.SlideController', 'Blank Screen'), icon=':/slides/slide_blank.png',
checked=False, can_shortcuts=True, category=self.category, triggers=self.on_blank_display)
text=translate('OpenLP.SlideController', 'Blank Screen'),
icon=':/slides/slide_blank.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_blank_display)
self.theme_screen = create_action(self, 'themeScreen',
text=translate('OpenLP.SlideController', 'Blank to Theme'), icon=':/slides/slide_theme.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_theme_display)
text=translate('OpenLP.SlideController', 'Blank to Theme'),
icon=':/slides/slide_theme.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_theme_display)
self.desktop_screen = create_action(self, 'desktopScreen',
text=translate('OpenLP.SlideController', 'Show Desktop'), icon=':/slides/slide_desktop.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_hide_display)
text=translate('OpenLP.SlideController', 'Show Desktop'),
icon=':/slides/slide_desktop.png',
checked=False, can_shortcuts=True, category=self.category,
triggers=self.on_hide_display)
self.hide_menu.setDefaultAction(self.blank_screen)
self.hide_menu.menu().addAction(self.blank_screen)
self.hide_menu.menu().addAction(self.theme_screen)
@ -231,11 +237,11 @@ class SlideController(DisplayController):
self.play_slides_menu.setMenu(QtGui.QMenu(translate('OpenLP.SlideController', 'Play Slides'), self.toolbar))
self.toolbar.add_toolbar_widget(self.play_slides_menu)
self.play_slides_loop = create_action(self, 'playSlidesLoop', text=UiStrings().PlaySlidesInLoop,
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
category=self.category, triggers=self.on_play_slides_loop)
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
category=self.category, triggers=self.on_play_slides_loop)
self.play_slides_once = create_action(self, 'playSlidesOnce', text=UiStrings().PlaySlidesToEnd,
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
category=self.category, triggers=self.on_play_slides_once)
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
category=self.category, triggers=self.on_play_slides_once)
if Settings().value(self.main_window.advanced_settings_section + '/slide limits') == SlideLimits.Wrap:
self.play_slides_menu.setDefaultAction(self.play_slides_loop)
else:
@ -251,12 +257,15 @@ class SlideController(DisplayController):
self.toolbar.add_toolbar_widget(self.delay_spin_box)
else:
self.toolbar.add_toolbar_action('goLive', icon=':/general/general_live.png',
tooltip=translate('OpenLP.SlideController', 'Move to live.'), triggers=self.on_go_live)
tooltip=translate('OpenLP.SlideController', 'Move to live.'),
triggers=self.on_go_live)
self.toolbar.add_toolbar_action('addToService', icon=':/general/general_add.png',
tooltip=translate('OpenLP.SlideController', 'Add to Service.'), triggers=self.on_preview_add_to_service)
tooltip=translate('OpenLP.SlideController', 'Add to Service.'),
triggers=self.on_preview_add_to_service)
self.toolbar.addSeparator()
self.toolbar.add_toolbar_action('editSong', icon=':/general/general_edit.png',
tooltip=translate('OpenLP.SlideController', 'Edit and reload song preview.'), triggers=self.on_edit_song)
tooltip=translate('OpenLP.SlideController', 'Edit and reload song preview.')
, triggers=self.on_edit_song)
self.controller_layout.addWidget(self.toolbar)
# Build the Media Toolbar
self.media_controller.register_controller(self)
@ -280,25 +289,28 @@ class SlideController(DisplayController):
self.audio_pause_item.setParent(self.toolbar)
self.toolbar.widgetForAction(self.audio_pause_item).setPopupMode(
QtGui.QToolButton.MenuButtonPopup)
self.nextTrackItem = create_action(self, 'nextTrackItem', text=UiStrings().NextTrack,
icon=':/slides/media_playback_next.png',
tooltip=translate('OpenLP.SlideController', 'Go to next audio track.'),
category=self.category, can_shortcuts=True, triggers=self.on_next_track_clicked)
self.audio_menu.addAction(self.nextTrackItem)
self.trackMenu = self.audio_menu.addMenu(translate('OpenLP.SlideController', 'Tracks'))
self.next_track_item = create_action(self, 'nextTrackItem', text=UiStrings().NextTrack,
icon=':/slides/media_playback_next.png',
tooltip=translate('OpenLP.SlideController',
'Go to next audio track.'),
category=self.category,
can_shortcuts=True,
triggers=self.on_next_track_clicked)
self.audio_menu.addAction(self.next_track_item)
self.track_menu = self.audio_menu.addMenu(translate('OpenLP.SlideController', 'Tracks'))
self.audio_time_label = QtGui.QLabel(' 00:00 ', self.toolbar)
self.audio_time_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter)
self.audio_time_label.setStyleSheet(AUDIO_TIME_LABEL_STYLESHEET)
self.audio_time_label.setObjectName('audio_time_label')
self.toolbar.add_toolbar_widget(self.audio_time_label)
self.toolbar.set_widget_visible(self.audio_list, False)
self.toolbar.set_widget_visible(AUDIO_LIST, False)
self.toolbar.set_widget_visible(['song_menu'], False)
# Screen preview area
self.preview_frame = QtGui.QFrame(self.splitter)
self.preview_frame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio))
self.preview_frame.setMinimumHeight(100)
self.preview_frame.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Ignored,
QtGui.QSizePolicy.Label))
QtGui.QSizePolicy.Label))
self.preview_frame.setFrameShape(QtGui.QFrame.StyledPanel)
self.preview_frame.setFrameShadow(QtGui.QFrame.Sunken)
self.preview_frame.setObjectName('preview_frame')
@ -331,9 +343,9 @@ class SlideController(DisplayController):
self.grid.addLayout(self.slide_layout, 0, 0, 1, 1)
if self.is_live:
self.current_shortcut = ''
self.shortcutTimer = QtCore.QTimer()
self.shortcutTimer.setObjectName('shortcutTimer')
self.shortcutTimer.setSingleShot(True)
self.shortcut_timer = QtCore.QTimer()
self.shortcut_timer.setObjectName('shortcut_timer')
self.shortcut_timer.setSingleShot(True)
shortcuts = [
{'key': 'V', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Verse"')},
{'key': 'C', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Chorus"')},
@ -345,51 +357,55 @@ class SlideController(DisplayController):
{'key': 'O', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Other"')}
]
shortcuts.extend([{'key': str(number)} for number in range(10)])
self.controller.addActions([create_action(self,
'shortcutAction_%s' % s['key'], text=s.get('text'),
can_shortcuts=True,
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category if s.get('configurable') else None,
triggers=self._slide_shortcut_activated) for s in shortcuts])
self.shortcutTimer.timeout.connect(self._slide_shortcut_activated)
self.controller.addActions([create_action(self, 'shortcutAction_%s' % s['key'],
text=s.get('text'),
can_shortcuts=True,
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category if s.get('configurable') else None,
triggers=self._slide_shortcut_activated) for s in shortcuts])
self.shortcut_timer.timeout.connect(self._slide_shortcut_activated)
# Signals
self.preview_widget.clicked.connect(self.on_slide_selected)
if self.is_live:
# Need to use event as called across threads and UI is updated
QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_toggle_display'), self.toggle_display)
Registry().register_function('slidecontroller_live_spin_delay', self.receive_spin_delay)
self.toolbar.set_widget_visible(self.loop_list, False)
self.toolbar.set_widget_visible(self.wide_menu, False)
self.toolbar.set_widget_visible(LOOP_LIST, False)
self.toolbar.set_widget_visible(WIDE_MENU, False)
else:
self.preview_widget.doubleClicked.connect(self.on_preview_add_to_service)
self.toolbar.set_widget_visible(['editSong'], False)
if self.is_live:
self.set_live_hotkeys(self)
self.set_live_hot_keys(self)
self.__add_actions_to_widget(self.controller)
else:
self.controller.addActions([self.nextItem, self.previous_item])
self.controller.addActions([self.next_item, self.previous_item])
Registry().register_function('slidecontroller_%s_stop_loop' % self.type_prefix, self.on_stop_loop)
Registry().register_function('slidecontroller_%s_change' % self.type_prefix, self.on_slide_change)
Registry().register_function('slidecontroller_%s_blank' % self.type_prefix, self.on_slide_blank)
Registry().register_function('slidecontroller_%s_unblank' % self.type_prefix, self.on_slide_unblank)
Registry().register_function('slidecontroller_update_slide_limits', self.update_slide_limits)
QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_%s_set' % self.type_prefix),
self.on_slide_selected_index)
self.on_slide_selected_index)
QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_%s_next' % self.type_prefix),
self.on_slide_selected_next)
self.on_slide_selected_next)
QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_%s_previous' % self.type_prefix),
self.on_slide_selected_previous)
self.on_slide_selected_previous)
def bootstrap_post_set_up(self):
"""
Call by bootstrap functions
"""
self.screen_size_changed()
def _slide_shortcut_activated(self):
"""
Called, when a shortcut has been activated to jump to a chorus, verse,
etc.
Called, when a shortcut has been activated to jump to a chorus, verse, etc.
**Note**: This implementation is based on shortcuts. But it rather works
like "key sequenes". You have to press one key after the other and
**not** at the same time.
For example to jump to "V3" you have to press "V" and afterwards but
within a time frame of 350ms you have to press "3".
**Note**: This implementation is based on shortcuts. But it rather works like "key sequenes". You have to
press one key after the other and **not** at the same time.
For example to jump to "V3" you have to press "V" and afterwards but within a time frame of 350ms
you have to press "3".
"""
try:
from openlp.plugins.songs.lib import VerseType
@ -420,43 +436,45 @@ class SlideController(DisplayController):
self.current_shortcut += verse_type
elif verse_type:
self.current_shortcut = verse_type
keys = list(self.slideList.keys())
matches = [match for match in keys
if match.startswith(self.current_shortcut)]
keys = list(self.slide_list.keys())
matches = [match for match in keys if match.startswith(self.current_shortcut)]
if len(matches) == 1:
self.shortcutTimer.stop()
self.shortcut_timer.stop()
self.current_shortcut = ''
self.preview_widget.change_slide(self.slideList[matches[0]])
self.preview_widget.change_slide(self.slide_list[matches[0]])
self.slide_selected()
elif sender_name != 'shortcutTimer':
elif sender_name != 'shortcut_timer':
# Start the time as we did not have any match.
self.shortcutTimer.start(350)
self.shortcut_timer.start(350)
else:
# The timer timed out.
if self.current_shortcut in keys:
# We had more than one match for example "V1" and "V10", but
# "V1" was the slide we wanted to go.
self.preview_widget.change_slide(self.slideList[self.current_shortcut])
self.preview_widget.change_slide(self.slide_list[self.current_shortcut])
self.slide_selected()
# Reset the shortcut.
self.current_shortcut = ''
def set_live_hotkeys(self, parent=None):
def set_live_hot_keys(self, parent=None):
"""
Set the live hotkeys
"""
self.previousService = create_action(parent, 'previousService',
text=translate('OpenLP.SlideController', 'Previous Service'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category,
triggers=self.service_previous)
self.nextService = create_action(parent, 'nextService',
text=translate('OpenLP.SlideController', 'Next Service'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category,
triggers=self.service_next)
self.escapeItem = create_action(parent, 'escapeItem',
text=translate('OpenLP.SlideController', 'Escape Item'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category,
triggers=self.live_escape)
self.previous_service = create_action(parent, 'previousService',
text=translate('OpenLP.SlideController', 'Previous Service'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category,
triggers=self.service_previous)
self.next_service = create_action(parent, 'nextService',
text=translate('OpenLP.SlideController', 'Next Service'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category,
triggers=self.service_next)
self.escape_item = create_action(parent, 'escapeItem',
text=translate('OpenLP.SlideController', 'Escape Item'),
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category,
triggers=self.live_escape)
def live_escape(self):
"""
@ -502,10 +520,10 @@ class SlideController(DisplayController):
if self.keypress_queue:
while len(self.keypress_queue) and not self.keypress_loop:
self.keypress_loop = True
keypressCommand = self.keypress_queue.popleft()
if keypressCommand == ServiceItemAction.Previous:
keypress_command = self.keypress_queue.popleft()
if keypress_command == ServiceItemAction.Previous:
self.service_manager.previous_item()
elif keypressCommand == ServiceItemAction.PreviousLastSlide:
elif keypress_command == ServiceItemAction.PreviousLastSlide:
# Go to the last slide of the previous item
self.service_manager.previous_item(last_slide=True)
else:
@ -535,7 +553,7 @@ class SlideController(DisplayController):
self.preview_display.setup()
service_item = ServiceItem()
self.preview_display.web_view.setHtml(build_html(service_item, self.preview_display.screen, None, self.is_live,
plugins=self.plugin_manager.plugins))
plugins=self.plugin_manager.plugins))
self.media_controller.setup_display(self.preview_display, True)
if self.service_item:
self.refresh_service_item()
@ -545,9 +563,9 @@ class SlideController(DisplayController):
Add actions to the widget specified by `widget`
"""
widget.addActions([
self.previous_item, self.nextItem,
self.previousService, self.nextService,
self.escapeItem])
self.previous_item, self.next_item,
self.previous_service, self.next_service,
self.escape_item])
def preview_size_changed(self):
"""
@ -579,19 +597,19 @@ class SlideController(DisplayController):
used_space = self.toolbar.size().width() + self.hide_menu.size().width()
# Add the threshold to prevent flickering.
if width > used_space + HIDE_MENU_THRESHOLD and self.hide_menu.isVisible():
self.toolbar.set_widget_visible(self.narrow_menu, False)
self.toolbar.set_widget_visible(self.wide_menu)
self.toolbar.set_widget_visible(NARROW_MENU, False)
self.toolbar.set_widget_visible(WIDE_MENU)
# Take away a threshold to prevent flickering.
elif width < used_space - HIDE_MENU_THRESHOLD and not self.hide_menu.isVisible():
self.toolbar.set_widget_visible(self.wide_menu, False)
self.toolbar.set_widget_visible(self.narrow_menu)
self.toolbar.set_widget_visible(WIDE_MENU, False)
self.toolbar.set_widget_visible(NARROW_MENU)
def on_song_bar_handler(self):
"""
Some song handler
"""
request = self.sender().text()
slide_no = self.slideList[request]
slide_no = self.slide_list[request]
width = self.main_window.control_splitter.sizes()[self.split]
self.preview_widget.replace_service_item(self.service_item, width, slide_no)
self.slide_selected()
@ -626,7 +644,7 @@ class SlideController(DisplayController):
self.toolbar.hide()
self.mediabar.hide()
self.song_menu.hide()
self.toolbar.set_widget_visible(self.loop_list, False)
self.toolbar.set_widget_visible(LOOP_LIST, False)
self.toolbar.set_widget_visible(['song_menu'], False)
# Reset the button
self.play_slides_once.setChecked(False)
@ -634,14 +652,14 @@ class SlideController(DisplayController):
self.play_slides_loop.setChecked(False)
self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
if item.is_text():
if Settings().value(self.main_window.songs_settings_section + '/display songbar') and self.slideList:
if Settings().value(self.main_window.songs_settings_section + '/display songbar') and self.slide_list:
self.toolbar.set_widget_visible(['song_menu'], True)
if item.is_capable(ItemCapabilities.CanLoop) and len(item.get_frames()) > 1:
self.toolbar.set_widget_visible(self.loop_list)
self.toolbar.set_widget_visible(LOOP_LIST)
if item.is_media():
self.mediabar.show()
self.previous_item.setVisible(not item.is_media())
self.nextItem.setVisible(not item.is_media())
self.next_item.setVisible(not item.is_media())
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.show()
@ -660,7 +678,7 @@ class SlideController(DisplayController):
elif item.is_media():
self.mediabar.show()
self.previous_item.setVisible(not item.is_media())
self.nextItem.setVisible(not item.is_media())
self.next_item.setVisible(not item.is_media())
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.show()
@ -703,15 +721,15 @@ class SlideController(DisplayController):
log.debug('add_service_manager_item live = %s' % self.is_live)
# If no valid slide number is specified we take the first one, but we remember the initial value to see if we
# should reload the song or not
slidenum = slide_no
slide_num = slide_no
if slide_no == -1:
slidenum = 0
slide_num = 0
# If service item is the same as the current one, only change slide
if slide_no >= 0 and item == self.service_item:
self.preview_widget.change_slide(slidenum)
self.preview_widget.change_slide(slide_num)
self.slide_selected()
else:
self._process_item(item, slidenum)
self._process_item(item, slide_num)
if self.is_live and item.auto_play_slides_loop and item.timed_slide_interval > 0:
self.play_slides_loop.setChecked(item.auto_play_slides_loop)
self.delay_spin_box.setValue(int(item.timed_slide_interval))
@ -721,7 +739,7 @@ class SlideController(DisplayController):
self.delay_spin_box.setValue(int(item.timed_slide_interval))
self.on_play_slides_once()
def _process_item(self, service_item, slideno):
def _process_item(self, service_item, slide_no):
"""
Loads a ServiceItem into the system from ServiceManager. Display the slide number passed.
"""
@ -733,8 +751,8 @@ class SlideController(DisplayController):
if old_item and self.is_live and old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
self._reset_blank()
Registry().execute(
'%s_start' % service_item.name.lower(), [service_item, self.is_live, self.hide_mode(), slideno])
self.slideList = {}
'%s_start' % service_item.name.lower(), [service_item, self.is_live, self.hide_mode(), slide_no])
self.slide_list = {}
if self.is_live:
self.song_menu.menu().clear()
self.display.audio_player.reset()
@ -744,13 +762,13 @@ class SlideController(DisplayController):
if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
log.debug('Starting to play...')
self.display.audio_player.add_to_playlist(self.service_item.background_audio)
self.trackMenu.clear()
self.track_menu.clear()
for counter in range(len(self.service_item.background_audio)):
action = self.trackMenu.addAction(os.path.basename(self.service_item.background_audio[counter]))
action = self.track_menu.addAction(os.path.basename(self.service_item.background_audio[counter]))
action.setData(counter)
action.triggered.connect(self.on_track_triggered)
self.display.audio_player.repeat = Settings().value(
self.main_window.general_settings_section + '/audio repeat list')
self.display.audio_player.repeat = \
Settings().value(self.main_window.general_settings_section + '/audio repeat list')
if Settings().value(self.main_window.general_settings_section + '/audio start paused'):
self.audio_pause_item.setChecked(True)
self.display.audio_player.pause()
@ -767,21 +785,21 @@ class SlideController(DisplayController):
verse_def = '%s%s' % (verse_def[0], verse_def[1:])
two_line_def = '%s\n%s' % (verse_def[0], verse_def[1:])
row = two_line_def
if verse_def not in self.slideList:
self.slideList[verse_def] = framenumber
if verse_def not in self.slide_list:
self.slide_list[verse_def] = framenumber
if self.is_live:
self.song_menu.menu().addAction(verse_def, self.on_song_bar_handler)
else:
row += 1
self.slideList[str(row)] = row - 1
self.slide_list[str(row)] = row - 1
else:
row += 1
self.slideList[str(row)] = row - 1
self.slide_list[str(row)] = row - 1
# If current slide set background to image
if not self.service_item.is_command() and framenumber == slideno:
self.service_item.bg_image_bytes = self.image_manager.get_image_bytes(frame['path'],
ImageSource.ImagePlugin)
self.preview_widget.replace_service_item(self.service_item, width, slideno)
if not self.service_item.is_command() and framenumber == slide_no:
self.service_item.bg_image_bytes = \
self.image_manager.get_image_bytes(frame['path'], ImageSource.ImagePlugin)
self.preview_widget.replace_service_item(self.service_item, width, slide_no)
self.enable_tool_bar(service_item)
# Pass to display for viewing.
# Postpone image build, we need to do this later to avoid the theme
@ -915,8 +933,8 @@ class SlideController(DisplayController):
if hide_mode:
if not self.service_item.is_command():
Registry().execute('live_display_hide', hide_mode)
Registry().execute('%s_blank' % self.service_item.name.lower(),
[self.service_item, self.is_live, hide_mode])
Registry().execute('%s_blank' %
self.service_item.name.lower(), [self.service_item, self.is_live, hide_mode])
else:
if not self.service_item.is_command():
Registry().execute('live_display_show')
@ -962,8 +980,8 @@ class SlideController(DisplayController):
if -1 < row < self.preview_widget.slide_count():
if self.service_item.is_command():
if self.is_live and not start:
Registry().execute('%s_slide' % self.service_item.name.lower(),
[self.service_item, self.is_live, row])
Registry().execute('%s_slide' %
self.service_item.name.lower(), [self.service_item, self.is_live, row])
else:
to_display = self.service_item.get_rendered_frame(row)
if self.service_item.is_text():
@ -1142,7 +1160,7 @@ class SlideController(DisplayController):
"""
Set the visibility of the audio stuff
"""
self.toolbar.set_widget_visible(self.audio_list, visible)
self.toolbar.set_widget_visible(AUDIO_LIST, visible)
def set_audio_pause_clicked(self, checked):
"""
@ -1332,4 +1350,3 @@ class SlideController(DisplayController):
return self._main_window
main_window = property(_get_main_window)