Fix up Main display

This commit is contained in:
Tim Bentley 2014-01-11 17:52:01 +00:00
parent 3a5c15a29a
commit 7fe95731f9
9 changed files with 139 additions and 106 deletions

View File

@ -33,7 +33,8 @@ import logging
import inspect
from openlp.core.common import trace_error_handler
DO_NOT_TRACE_EVENTS = ['timerEvent', 'paintEvent', 'drag_enter_event', 'drop_event']
DO_NOT_TRACE_EVENTS = ['timerEvent', 'paintEvent', 'drag_enter_event', 'drop_event', 'on_controller_size_changed',
'preview_size_changed', 'resizeEvent']
class OpenLPMixin(object):

View File

@ -60,6 +60,8 @@ class Renderer(OpenLPMixin, RegistryMixin):
print("Renderer - before super")
super(Renderer, self).__init__(None)
print("Renderer - after super")
# Need live behaviour if this is also working as a pseudo MainDisplay.
self.is_live = True
self.screens = ScreenList()
self.theme_level = ThemeLevel.Global
self.global_theme_name = ''
@ -77,7 +79,7 @@ class Renderer(OpenLPMixin, RegistryMixin):
"""
Initialise functions
"""
self.display = MainDisplay(None, False, self)
self.display = MainDisplay(self)
self.display.setup()
def update_display(self):
@ -87,7 +89,7 @@ class Renderer(OpenLPMixin, RegistryMixin):
self._calculate_default()
if self.display:
self.display.close()
self.display = MainDisplay(None, False, self)
self.display = MainDisplay(self)
self.display.setup()
self._theme_dimensions = {}
@ -114,6 +116,7 @@ class Renderer(OpenLPMixin, RegistryMixin):
:param theme_name: The theme name
"""
self.log_debug("_set_theme with theme %s" % theme_name)
if theme_name not in self._theme_dimensions:
theme_data = self.theme_manager.get_theme_data(theme_name)
main_rect = self.get_main_rectangle(theme_data)
@ -169,9 +172,6 @@ class Renderer(OpenLPMixin, RegistryMixin):
def set_global_theme(self):
"""
Set the global-level theme name.
``global_theme_name``
The global-level theme's name.
"""
global_theme_name = Settings().value('themes/global theme')
self._set_theme(global_theme_name)
@ -192,6 +192,7 @@ class Renderer(OpenLPMixin, RegistryMixin):
:param item_theme_name: The item theme's name.
"""
self.log_debug("set_item_theme with theme %s" % item_theme_name)
self._set_theme(item_theme_name)
self.item_theme_name = item_theme_name
@ -202,7 +203,6 @@ class Renderer(OpenLPMixin, RegistryMixin):
:param theme_data: The theme to generated a preview for.
:param force_page: Flag to tell message lines per page need to be generated.
"""
self.log_debug('generate preview')
# save value for use in format_slide
self.force_page = force_page
# build a service item to generate preview

View File

@ -31,8 +31,8 @@ The :mod:`serviceitem` provides the service item functionality including the
type and capability of an item.
"""
import cgi
import datetime
import html
import logging
import os
import uuid
@ -241,9 +241,8 @@ class ServiceItem(object):
self.theme_data, self.main, self.footer = self.renderer.pre_render()
if self.service_item_type == ServiceItemType.Text:
log.debug('Formatting slides: %s' % self.title)
# Save rendered pages to this dict. In the case that a slide is used
# twice we can use the pages saved to the dict instead of rendering
# them again.
# Save rendered pages to this dict. In the case that a slide is used twice we can use the pages saved to
# the dict instead of rendering them again.
previous_pages = {}
for slide in self._raw_frames:
verse_tag = slide['verseTag']
@ -254,11 +253,11 @@ class ServiceItem(object):
previous_pages[verse_tag] = (slide['raw_slide'], pages)
for page in pages:
page = page.replace('<br>', '{br}')
html = expand_tags(cgi.escape(page.rstrip()))
html_data = expand_tags(html.escape(page.rstrip()))
self._display_frames.append({
'title': clean_tags(page),
'text': clean_tags(page.rstrip()),
'html': html.replace('&amp;nbsp;', '&nbsp;'),
'html': html_data.replace('&amp;nbsp;', '&nbsp;'),
'verseTag': verse_tag
})
elif self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command:

View File

@ -44,7 +44,7 @@ import sys
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
from PyQt4.phonon import Phonon
from openlp.core.common import Registry, Settings, translate
from openlp.core.common import Registry, OpenLPMixin, Settings, translate
from openlp.core.lib import ServiceItem, ImageSource, build_html, expand_tags, image_to_byte
from openlp.core.lib.theme import BackgroundType
@ -59,20 +59,22 @@ class Display(QtGui.QGraphicsView):
This is a general display screen class. Here the general display settings will done. It will be used as
specialized classes by Main Display and Preview display.
"""
def __init__(self, parent, live, controller):
def __init__(self, parent):
"""
Constructor
"""
print("Display - before super")
if live:
print("Display - before super", parent, type(parent))
self.is_live = False
if hasattr(parent, 'is_live') and parent.is_live:
self.is_live = True
if self.is_live:
super(Display, self).__init__()
# Overwrite the parent() method.
self.parent = lambda: parent
else:
super(Display, self).__init__(parent)
print("Display - after super")
self.is_live = live
self.controller = controller
self.controller = parent
self.screen = {}
# FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with
# OpenGL. Only white blank screen is shown on the 2nd monitor all the
@ -85,9 +87,7 @@ class Display(QtGui.QGraphicsView):
"""
Set up and build the screen base
"""
log.debug('Start Display base setup (live = %s)' % self.is_live)
self.setGeometry(self.screen['size'])
log.debug('Setup webView')
self.web_view = QtWebKit.QWebView(self)
self.web_view.setGeometry(0, 0, self.screen['size'].width(), self.screen['size'].height())
self.web_view.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True)
@ -108,27 +108,28 @@ class Display(QtGui.QGraphicsView):
def resizeEvent(self, event):
"""
React to resizing of this display
:param event: The event to be handled
"""
self.web_view.setGeometry(0, 0, self.width(), self.height())
def is_web_loaded(self):
def is_web_loaded(self, field=None):
"""
Called by webView event to show display is fully loaded
"""
log.debug('is web loaded')
self.web_loaded = True
class MainDisplay(Display):
class MainDisplay(OpenLPMixin, Display):
"""
This is the display screen as a specialized class from the Display class
"""
def __init__(self, parent, live, controller):
def __init__(self, parent):
"""
Constructor
"""
print("MainDisplay - before super")
super(MainDisplay, self).__init__(parent, live, controller)
super(MainDisplay, self).__init__(parent)
print("MainDisplay - after super")
self.screens = ScreenList()
self.rebuild_css = False
@ -136,7 +137,7 @@ class MainDisplay(Display):
self.override = {}
self.retranslateUi()
self.media_object = None
if live:
if self.is_live:
self.audio_player = AudioPlayer(self)
else:
self.audio_player = None
@ -167,6 +168,8 @@ class MainDisplay(Display):
def set_transparency(self, enabled):
"""
Set the transparency of the window
:param enabled: Is transparency enabled
"""
if enabled:
self.setAutoFillBackground(False)
@ -192,7 +195,7 @@ class MainDisplay(Display):
"""
Set up and build the output screen
"""
log.debug('Start MainDisplay setup (live = %s)' % self.is_live)
self.log_debug('Start MainDisplay setup (live = %s)' % self.is_live)
self.screen = self.screens.current
self.setVisible(False)
Display.setup(self)
@ -219,20 +222,15 @@ class MainDisplay(Display):
service_item.bg_image_bytes = image_to_byte(self.initial_fame)
self.web_view.setHtml(build_html(service_item, self.screen, self.is_live, None,
plugins=self.plugin_manager.plugins))
self.__hideMouse()
log.debug('Finished MainDisplay setup')
self._hide_mouse()
def text(self, slide, animate=True):
"""
Add the slide text from slideController
``slide``
The slide text to be displayed
``animate``
Perform transitions if applicable when setting the text
:param slide: The slide text to be displayed
:param animate: Perform transitions if applicable when setting the text
"""
log.debug('text to display')
# Wait for the webview to update before displaying text.
while not self.web_loaded:
self.application.process_events()
@ -251,10 +249,9 @@ class MainDisplay(Display):
"""
Display an alert.
``text``
The text to be displayed.
:param text: The text to be displayed.
:param location: Where on the screen is the text to be displayed
"""
log.debug('alert to display')
# First we convert <>& marks to html variants, then apply
# formattingtags, finally we double all backslashes for JavaScript.
text_prepared = expand_tags(cgi.escape(text)).replace('\\', '\\\\').replace('\"', '\\\"')
@ -281,6 +278,9 @@ class MainDisplay(Display):
def direct_image(self, path, background):
"""
API for replacement backgrounds so Images are added directly to cache.
:param path: Path to Image
:param background: The background color
"""
self.image_manager.add_image(path, ImageSource.ImagePlugin, background)
if not hasattr(self, 'service_item'):
@ -298,12 +298,9 @@ class MainDisplay(Display):
Add an image as the background. The image has already been added to the
cache.
``path``
The path to the image to be displayed. **Note**, the path is only
passed to identify the image. If the image has changed it has to be
re-added to the image manager.
:param path: The path to the image to be displayed. **Note**, the path is only passed to identify the image.
If the image has changed it has to be re-added to the image manager.
"""
log.debug('image to display')
image = self.image_manager.get_image_bytes(path, ImageSource.ImagePlugin)
self.controller.media_controller.media_reset(self.controller)
self.display_image(image)
@ -311,6 +308,8 @@ class MainDisplay(Display):
def display_image(self, image):
"""
Display an image, as is.
:param image: The image to be displayed
"""
self.setGeometry(self.screen['size'])
if image:
@ -321,10 +320,8 @@ class MainDisplay(Display):
def reset_image(self):
"""
Reset the background image to the service item image. Used after the
image plugin has changed the background.
Reset the background image to the service item image. Used after the image plugin has changed the background.
"""
log.debug('reset_image')
if hasattr(self, 'service_item'):
self.display_image(self.service_item.bg_image_bytes)
else:
@ -339,7 +336,6 @@ class MainDisplay(Display):
"""
Generates a preview of the image displayed.
"""
log.debug('preview for %s', self.is_live)
was_visible = self.isVisible()
self.application.process_events()
# We must have a service item to preview.
@ -371,10 +367,11 @@ class MainDisplay(Display):
def build_html(self, service_item, image_path=''):
"""
Store the service_item and build the new HTML from it. Add the
HTML to the display
Store the service_item and build the new HTML from it. Add the HTML to the display
:param service_item: The Service item to be used
:param image_path: Where the image resides.
"""
log.debug('build_html')
self.web_loaded = False
self.initial_fame = None
self.service_item = service_item
@ -396,17 +393,14 @@ class MainDisplay(Display):
BackgroundType.to_string(BackgroundType.Transparent))
if self.service_item.theme_data.background_filename:
self.service_item.bg_image_bytes = self.image_manager.get_image_bytes(
self.service_item.theme_data.background_filename, ImageSource.Theme
)
self.service_item.theme_data.background_filename, ImageSource.Theme)
if image_path:
image_bytes = self.image_manager.get_image_bytes(image_path, ImageSource.ImagePlugin)
else:
image_bytes = None
html = build_html(self.service_item, self.screen, self.is_live, background, image_bytes,
plugins=self.plugin_manager.plugins)
log.debug('buildHtml - pre setHtml')
self.web_view.setHtml(html)
log.debug('buildHtml - post setHtml')
if service_item.foot_text:
self.footer(service_item.foot_text)
# if was hidden keep it hidden
@ -415,22 +409,24 @@ class MainDisplay(Display):
Registry().execute('slidecontroller_live_unblank')
else:
self.hide_display(self.hide_mode)
self.__hideMouse()
self._hide_mouse()
def footer(self, text):
"""
Display the Footer
:param text: footer text to be displayed
"""
log.debug('footer')
js = 'show_footer(\'' + text.replace('\\', '\\\\').replace('\'', '\\\'') + '\')'
self.frame.evaluateJavaScript(js)
def hide_display(self, mode=HideMode.Screen):
"""
Hide the display by making all layers transparent
Store the images so they can be replaced when required
Hide the display by making all layers transparent Store the images so they can be replaced when required
:param mode: How the screen is to be hidden
"""
log.debug('hide_display mode = %d', mode)
self.log_debug('hide_display mode = %d' % mode)
if self.screens.display_count == 1:
# Only make visible if setting enabled.
if not Settings().value('core/display on monitor'):
@ -453,7 +449,6 @@ class MainDisplay(Display):
Show the stored layers so the screen reappears as it was originally.
Make the stored images None to release memory.
"""
log.debug('show_display')
if self.screens.display_count == 1:
# Only make visible if setting enabled.
if not Settings().value('core/display on monitor'):
@ -466,7 +461,7 @@ class MainDisplay(Display):
if self.is_live:
Registry().execute('live_display_active')
def __hideMouse(self):
def _hide_mouse(self):
"""
Hide mouse cursor when moved over display.
"""
@ -522,11 +517,10 @@ class MainDisplay(Display):
live_controller = property(_get_live_controller)
class AudioPlayer(QtCore.QObject):
class AudioPlayer(OpenLPMixin, QtCore.QObject):
"""
This Class will play audio only allowing components to work with a soundtrack independent of the user interface.
"""
log.info('AudioPlayer Loaded')
def __init__(self, parent):
"""
@ -535,7 +529,6 @@ class AudioPlayer(QtCore.QObject):
``parent``
The parent widget.
"""
log.debug('AudioPlayer Initialisation started')
super(AudioPlayer, self).__init__(parent)
self.current_index = -1
self.playlist = []
@ -569,7 +562,7 @@ class AudioPlayer(QtCore.QObject):
When the audio track finishes.
"""
if self.repeat:
log.debug('Repeat is enabled... here we go again!')
self.log_debug('Repeat is enabled... here we go again!')
self.media_object.clearQueue()
self.media_object.clear()
self.current_index = -1
@ -594,7 +587,6 @@ class AudioPlayer(QtCore.QObject):
"""
We want to play the file so start it
"""
log.debug('AudioPlayer.play() called')
if self.current_index == -1:
self.on_about_to_finish()
self.media_object.play()
@ -603,22 +595,19 @@ class AudioPlayer(QtCore.QObject):
"""
Pause the Audio
"""
log.debug('AudioPlayer.pause() called')
self.media_object.pause()
def stop(self):
"""
Stop the Audio and clean up
"""
log.debug('AudioPlayer.stop() called')
self.media_object.stop()
def add_to_playlist(self, file_names):
"""
Add another file to the playlist.
``file_names``
A list with files to be added to the playlist.
:param file_names: A list with files to be added to the playlist.
"""
if not isinstance(file_names, list):
file_names = [file_names]
@ -643,6 +632,8 @@ class AudioPlayer(QtCore.QObject):
def go_to(self, index):
"""
Go to a particular track in the list
:param index: The track to go to
"""
is_playing = self.media_object.state() == Phonon.PlayingState
self.media_object.clearQueue()
@ -655,6 +646,9 @@ class AudioPlayer(QtCore.QObject):
def connectSlot(self, signal, slot):
"""
Connect a slot to a signal on the media object. Used by slidecontroller to connect to audio object.
:param slot: The slot the signal is attached to.
:param signal: The signal to be fired
"""
QtCore.QObject.connect(self.media_object, signal, slot)

View File

@ -548,6 +548,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.live_controller.panel.setVisible(Settings().value('user interface/live panel'))
self.load_settings()
self.restore_current_media_manager_item()
Registry().execute('theme_update_global')
def restore_current_media_manager_item(self):
"""
@ -676,7 +677,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
else:
self.active_plugin.toggle_status(PluginStatus.Inactive)
# Set global theme and
Registry().execute('theme_update_global', self.theme_manager_contents.global_theme)
Registry().execute('theme_update_global')
self.theme_manager_contents.load_first_time_themes()
# Check if any Bibles downloaded. If there are, they will be processed.
Registry().execute('bibles_load_list', True)

View File

@ -1024,9 +1024,9 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
"""
Called by the SlideController to select the next service item.
"""
if not self.service_manager_list.selected_items():
if not self.service_manager_list.selectedItems():
return
selected = self.service_manager_list.selected_items()[0]
selected = self.service_manager_list.selectedItems()[0]
look_for = 0
service_iterator = QtGui.QTreeWidgetItemIterator(self.service_manager_list)
while service_iterator.value():
@ -1044,9 +1044,9 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
:param last_slide: Is this the last slide in the service_item.
"""
if not self.service_manager_list.selected_items():
if not self.service_manager_list.selectedItems():
return
selected = self.service_manager_list.selected_items()[0]
selected = self.service_manager_list.selectedItems()[0]
prev_item = None
prev_item_last_slide = None
service_iterator = QtGui.QTreeWidgetItemIterator(self.service_manager_list)

View File

@ -93,8 +93,7 @@ class DisplayController(QtGui.QWidget):
def send_to_plugins(self, *args):
"""
This is the generic function to send signal for control widgets,
created from within other plugins
This is the generic function to send signal for control widgets, created from within other plugins
This function is needed to catch the current controller
"""
sender = self.sender().objectName() if self.sender().objectName() else self.sender().text()
@ -277,7 +276,8 @@ class SlideController(DisplayController):
self.toolbar.add_toolbar_widget(self.song_menu)
# Stuff for items with background audio.
# FIXME: object name should be changed. But this requires that we migrate the shortcut.
self.audio_pause_item = self.toolbar.add_toolbar_action('audioPauseItem',
self.audio_pause_item = self.toolbar.add_toolbar_action(
'audioPauseItem',
icon=':/slides/media_playback_pause.png', text=translate('OpenLP.SlideController', 'Pause Audio'),
tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
checked=False, visible=False, category=self.category, context=QtCore.Qt.WindowShortcut,
@ -318,7 +318,7 @@ class SlideController(DisplayController):
self.slide_layout.setSpacing(0)
self.slide_layout.setMargin(0)
self.slide_layout.setObjectName('SlideLayout')
self.preview_display = Display(self, self.is_live, self)
self.preview_display = Display(self)
self.preview_display.setGeometry(QtCore.QRect(0, 0, 300, 300))
self.preview_display.screen = {'size': self.preview_display.geometry()}
self.preview_display.setup()
@ -532,7 +532,7 @@ class SlideController(DisplayController):
# rebuild display as screen size changed
if self.display:
self.display.close()
self.display = MainDisplay(self, self.is_live, self)
self.display = MainDisplay(self)
self.display.setup()
if self.is_live:
self.__add_actions_to_widget(self.display)
@ -566,17 +566,15 @@ class SlideController(DisplayController):
def preview_size_changed(self):
"""
Takes care of the SlidePreview's size. Is called when one of the the
splitters is moved or when the screen size is changed. Note, that this
method is (also) called frequently from the mainwindow *paintEvent*.
Takes care of the SlidePreview's size. Is called when one of the the splitters is moved or when the screen
size is changed. Note, that this method is (also) called frequently from the mainwindow *paintEvent*.
"""
if self.ratio < self.preview_frame.width() / self.preview_frame.height():
# We have to take the height as limit.
max_height = self.preview_frame.height() - self.grid.margin() * 2
self.slide_preview.setFixedSize(QtCore.QSize(max_height * self.ratio, max_height))
self.preview_display.setFixedSize(QtCore.QSize(max_height * self.ratio, max_height))
self.preview_display.screen = {
'size': self.preview_display.geometry()}
self.preview_display.screen = {'size': self.preview_display.geometry()}
else:
# We have to take the width as limit.
max_width = self.preview_frame.width() - self.grid.margin() * 2
@ -683,6 +681,8 @@ class SlideController(DisplayController):
def enable_preview_tool_bar(self, item):
"""
Allows the Preview toolbar to be customised
:param item: The current service item
"""
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
@ -712,6 +712,8 @@ class SlideController(DisplayController):
"""
Method to install the service item into the controller
Called by plugins
:param item: The current service item
"""
item.render()
slide_no = 0
@ -723,6 +725,8 @@ class SlideController(DisplayController):
def replace_service_manager_item(self, item):
"""
Replacement item following a remote edit
:param item: The current service item
"""
if item == self.service_item:
self._process_item(item, self.preview_widget.current_slide_number())
@ -731,6 +735,9 @@ class SlideController(DisplayController):
"""
Method to install the service item into the controller and request the correct toolbar for the plugin. Called by
:class:`~openlp.core.ui.ServiceManager`
:param item: The current service item
:param slide_no: The slide number to select
"""
# 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
@ -755,6 +762,9 @@ class SlideController(DisplayController):
def _process_item(self, service_item, slide_no):
"""
Loads a ServiceItem into the system from ServiceManager. Display the slide number passed.
:param service_item: The current service item
:param slide_no: The slide number to select
"""
self.on_stop_loop()
old_item = self.service_item
@ -762,8 +772,9 @@ class SlideController(DisplayController):
self.service_item = copy.copy(service_item)
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(), slide_no])
if service_item.is_command():
Registry().execute(
'%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()
@ -789,7 +800,7 @@ class SlideController(DisplayController):
self.set_audio_items_visibility(True)
row = 0
width = self.main_window.control_splitter.sizes()[self.split]
for framenumber, frame in enumerate(self.service_item.get_frames()):
for frame_number, frame in enumerate(self.service_item.get_frames()):
if self.service_item.is_text():
if frame['verseTag']:
# These tags are already translated.
@ -798,7 +809,7 @@ class SlideController(DisplayController):
two_line_def = '%s\n%s' % (verse_def[0], verse_def[1:])
row = two_line_def
if verse_def not in self.slide_list:
self.slide_list[verse_def] = framenumber
self.slide_list[verse_def] = frame_number
if self.is_live:
self.song_menu.menu().addAction(verse_def, self.on_song_bar_handler)
else:
@ -808,7 +819,7 @@ class SlideController(DisplayController):
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 == slide_no:
if not self.service_item.is_command() and frame_number == 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)
@ -832,10 +843,11 @@ class SlideController(DisplayController):
self.on_media_close()
Registry().execute('slidecontroller_%s_started' % self.type_prefix, [service_item])
# Screen event methods
def on_slide_selected_index(self, message):
"""
Go to the requested slide
:param message: remote message to be processed.
"""
index = int(message[0])
if not self.service_item:
@ -880,6 +892,8 @@ class SlideController(DisplayController):
def on_blank_display(self, checked=None):
"""
Handle the blank screen button actions
:param checked: the new state of the of the widget
"""
if checked is None:
checked = self.blank_screen.isChecked()
@ -899,6 +913,8 @@ class SlideController(DisplayController):
def on_theme_display(self, checked=None):
"""
Handle the Theme screen button
:param checked: the new state of the of the widget
"""
if checked is None:
checked = self.theme_screen.isChecked()
@ -918,6 +934,8 @@ class SlideController(DisplayController):
def on_hide_display(self, checked=None):
"""
Handle the Hide screen button
:param checked: the new state of the of the widget
"""
if checked is None:
checked = self.desktop_screen.isChecked()
@ -984,8 +1002,9 @@ class SlideController(DisplayController):
def slide_selected(self, start=False):
"""
Generate the preview when you click on a slide.
if this is the Live Controller also display on the screen
Generate the preview when you click on a slide. If this is the Live Controller also display on the screen
:param start:
"""
row = self.preview_widget.current_slide_number()
self.selected_row = 0
@ -1008,12 +1027,13 @@ class SlideController(DisplayController):
self.update_preview()
self.selected_row = row
self.preview_widget.change_slide(row)
Registry().execute('slidecontroller_%s_changed' % self.type_prefix, row)
self.display.setFocus()
def on_slide_change(self, row):
"""
The slide has been changed. Update the slidecontroller accordingly
:param row: Row to be selected
"""
self.preview_widget.change_slide(row)
self.update_preview()
@ -1046,20 +1066,24 @@ class SlideController(DisplayController):
def on_slide_selected_next_action(self, checked):
"""
Wrapper function from create_action so we can throw away the
incorrect parameter
Wrapper function from create_action so we can throw away the incorrect parameter
:param checked: the new state of the of the widget
"""
self.on_slide_selected_next()
def on_slide_selected_next(self, wrap=None):
"""
Go to the next slide.
:param wrap: Are we wrapping round the service item
"""
if not self.service_item:
return
Registry().execute('%s_next' % self.service_item.name.lower(), [self.service_item, self.is_live])
if self.service_item.is_command() and self.is_live:
self.update_preview()
if self.service_item.is_command():
Registry().execute('%s_next' % self.service_item.name.lower(), [self.service_item, self.is_live])
if self.is_live:
self.update_preview()
else:
row = self.preview_widget.current_slide_number() + 1
if row == self.preview_widget.slide_count():
@ -1084,9 +1108,10 @@ class SlideController(DisplayController):
"""
if not self.service_item:
return
Registry().execute('%s_previous' % self.service_item.name.lower(), [self.service_item, self.is_live])
if self.service_item.is_command() and self.is_live:
self.update_preview()
if self.service_item.is_command():
Registry().execute('%s_previous' % self.service_item.name.lower(), [self.service_item, self.is_live])
if self.is_live:
self.update_preview()
else:
row = self.preview_widget.current_slide_number() - 1
if row == -1:
@ -1129,6 +1154,8 @@ class SlideController(DisplayController):
def on_play_slides_loop(self, checked=None):
"""
Start or stop 'Play Slides in Loop'
:param checked: is the check box checked.
"""
if checked is None:
checked = self.play_slides_loop.isChecked()
@ -1150,6 +1177,8 @@ class SlideController(DisplayController):
def on_play_slides_once(self, checked=None):
"""
Start or stop 'Play Slides to End'
:param checked: is the check box checked.
"""
if checked is None:
checked = self.play_slides_once.isChecked()
@ -1177,6 +1206,8 @@ class SlideController(DisplayController):
def set_audio_pause_clicked(self, checked):
"""
Pause the audio player
:param checked: is the check box checked.
"""
if not self.audio_pause_item.isVisible():
return
@ -1188,6 +1219,8 @@ class SlideController(DisplayController):
def timerEvent(self, event):
"""
If the timer event is for this window select next slide
:param event: The triggered event
"""
if event.timerId() == self.timer_id:
self.on_slide_selected_next(self.play_slides_loop.isChecked())
@ -1235,6 +1268,8 @@ class SlideController(DisplayController):
def on_media_start(self, item):
"""
Respond to the arrival of a media service item
:param item: The service item to be processed
"""
self.media_controller.video(self.controller_type, item, self.hide_mode())
if not self.is_live:
@ -1288,6 +1323,8 @@ class SlideController(DisplayController):
def on_audio_time_remaining(self, time):
"""
Update how much time is remaining
:param time: the time remainings
"""
seconds = self.display.audio_player.media_object.remainingTime() // 1000
minutes = seconds // 60
@ -1335,7 +1372,7 @@ class SlideController(DisplayController):
"""
Adds the service manager to the class dynamically
"""
if not hasattr(self, '_service_manager'):
if not hasattr(self, '_service_manager') or not self._service_manager:
self._service_manager = Registry().get('service_manager')
return self._service_manager

View File

@ -515,8 +515,9 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ThemeManager):
def over_write_message_box(self, theme_name):
"""
Display a warning box to the user that a theme already exists
:param theme_name: Name of the theme.
:return Confirm if the theme is to be overeritten.
:return Confirm if the theme is to be overwritten.
"""
ret = QtGui.QMessageBox.question(self, translate('OpenLP.ThemeManager', 'Theme Already Exists'),
translate('OpenLP.ThemeManager',

View File

@ -74,7 +74,7 @@ class MediaMediaItem(MediaManagerItem):
self.display_controller.controller_layout = QtGui.QVBoxLayout()
self.media_controller.register_controller(self.display_controller)
self.media_controller.set_controls_visible(self.display_controller, False)
self.display_controller.preview_display = Display(self.display_controller, False, self.display_controller)
self.display_controller.preview_display = Display(self.display_controller)
self.display_controller.preview_display.hide()
self.display_controller.preview_display.setGeometry(QtCore.QRect(0, 0, 300, 300))
self.display_controller.preview_display.screen = {'size': self.display_controller.preview_display.geometry()}