forked from openlp/openlp
Fix up Main display
This commit is contained in:
parent
3a5c15a29a
commit
7fe95731f9
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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('&nbsp;', ' '),
|
||||
'html': html_data.replace('&nbsp;', ' '),
|
||||
'verseTag': verse_tag
|
||||
})
|
||||
elif self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command:
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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()}
|
||||
|
Loading…
Reference in New Issue
Block a user