More cleanups

This commit is contained in:
Tim Bentley 2013-02-20 19:31:51 +00:00
parent 5ca6d36935
commit ad7d78ff26
8 changed files with 198 additions and 212 deletions

View File

@ -247,7 +247,7 @@ class Renderer(object):
serviceItem.footer = footer serviceItem.footer = footer
serviceItem.render(True) serviceItem.render(True)
if not self.force_page: if not self.force_page:
self.display.buildHtml(serviceItem) self.display.build_html(serviceItem)
raw_html = serviceItem.get_rendered_frame(0) raw_html = serviceItem.get_rendered_frame(0)
self.display.text(raw_html, False) self.display.text(raw_html, False)
preview = self.display.preview() preview = self.display.preview()

View File

@ -85,37 +85,34 @@ class Display(QtGui.QGraphicsView):
log.debug(u'Start Display base setup (live = %s)' % self.isLive) log.debug(u'Start Display base setup (live = %s)' % self.isLive)
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
log.debug(u'Setup webView') log.debug(u'Setup webView')
self.webView = QtWebKit.QWebView(self) self.web_view = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0, self.screen[u'size'].width(), self.screen[u'size'].height()) self.web_view.setGeometry(0, 0, self.screen[u'size'].width(), self.screen[u'size'].height())
self.webView.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True) self.web_view.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True)
palette = self.webView.palette() palette = self.web_view.palette()
palette.setBrush(QtGui.QPalette.Base, QtCore.Qt.transparent) palette.setBrush(QtGui.QPalette.Base, QtCore.Qt.transparent)
self.webView.page().setPalette(palette) self.web_view.page().setPalette(palette)
self.webView.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, False) self.web_view.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, False)
self.page = self.webView.page() self.page = self.web_view.page()
self.frame = self.page.mainFrame() self.frame = self.page.mainFrame()
if self.isLive and log.getEffectiveLevel() == logging.DEBUG: if self.isLive and log.getEffectiveLevel() == logging.DEBUG:
self.webView.settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True) self.web_view.settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
QtCore.QObject.connect(self.webView, self.web_view.loadFinished.connect(self.is_web_loaded)
QtCore.SIGNAL(u'loadFinished(bool)'), self.isWebLoaded)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical, self.frame.setScrollBarPolicy(QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)
QtCore.Qt.ScrollBarAlwaysOff) self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal,
QtCore.Qt.ScrollBarAlwaysOff)
def resizeEvent(self, event): def resizeEvent(self, event):
""" """
React to resizing of this display React to resizing of this display
""" """
self.webView.setGeometry(0, 0, self.width(), self.height()) self.web_view.setGeometry(0, 0, self.width(), self.height())
def isWebLoaded(self): def is_web_loaded(self):
""" """
Called by webView event to show display is fully loaded Called by webView event to show display is fully loaded
""" """
log.debug(u'Webloaded') log.debug(u'is web loaded')
self.webLoaded = True self.webLoaded = True
@ -129,11 +126,11 @@ class MainDisplay(Display):
""" """
Display.__init__(self, parent, live, controller) Display.__init__(self, parent, live, controller)
self.screens = ScreenList() self.screens = ScreenList()
self.rebuildCSS = False self.rebuild_css = False
self.hideMode = None self.hide_mode = None
self.override = {} self.override = {}
self.retranslateUi() self.retranslateUi()
self.mediaObject = None self.media_object = None
if live: if live:
self.audioPlayer = AudioPlayer(self) self.audioPlayer = AudioPlayer(self)
else: else:
@ -156,14 +153,14 @@ class MainDisplay(Display):
self.setWindowState(QtCore.Qt.WindowFullScreen) self.setWindowState(QtCore.Qt.WindowFullScreen)
self.setWindowFlags(windowFlags) self.setWindowFlags(windowFlags)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setTransparency(False) self.set_transparency(False)
if self.isLive: if self.isLive:
Registry().register_function(u'live_display_hide', self.hide_display) Registry().register_function(u'live_display_hide', self.hide_display)
Registry().register_function(u'live_display_show', self.show_display) Registry().register_function(u'live_display_show', self.show_display)
Registry().register_function(u'update_display_css', self.css_changed) Registry().register_function(u'update_display_css', self.css_changed)
Registry().register_function(u'config_updated', self.config_changed) Registry().register_function(u'config_updated', self.config_changed)
def setTransparency(self, enabled): def set_transparency(self, enabled):
""" """
Set the transparency of the window Set the transparency of the window
""" """
@ -178,17 +175,17 @@ class MainDisplay(Display):
""" """
We may need to rebuild the CSS on the live display. We may need to rebuild the CSS on the live display.
""" """
self.rebuildCSS = True self.rebuild_css = True
def config_changed(self): def config_changed(self):
""" """
Call the plugins to rebuild the Live display CSS as the screen has Call the plugins to rebuild the Live display CSS as the screen has
not been rebuild on exit of config. not been rebuild on exit of config.
""" """
if self.rebuildCSS and self.plugin_manager.plugins: if self.rebuild_css and self.plugin_manager.plugins:
for plugin in self.plugin_manager.plugins: for plugin in self.plugin_manager.plugins:
plugin.refreshCss(self.frame) plugin.refreshCss(self.frame)
self.rebuildCSS = False self.rebuild_css = False
def retranslateUi(self): def retranslateUi(self):
""" """
@ -225,7 +222,7 @@ class MainDisplay(Display):
splash_image) splash_image)
serviceItem = ServiceItem() serviceItem = ServiceItem()
serviceItem.bg_image_bytes = image_to_byte(self.initialFrame) serviceItem.bg_image_bytes = image_to_byte(self.initialFrame)
self.webView.setHtml(build_html(serviceItem, self.screen, self.isLive, None, self.web_view.setHtml(build_html(serviceItem, self.screen, self.isLive, None,
plugins=self.plugin_manager.plugins)) plugins=self.plugin_manager.plugins))
self.__hideMouse() self.__hideMouse()
log.debug(u'Finished MainDisplay setup') log.debug(u'Finished MainDisplay setup')
@ -288,7 +285,7 @@ class MainDisplay(Display):
self.setVisible(False) self.setVisible(False)
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
def directImage(self, path, background): def direct_image(self, path, background):
""" """
API for replacement backgrounds so Images are added directly to cache. API for replacement backgrounds so Images are added directly to cache.
""" """
@ -318,7 +315,7 @@ class MainDisplay(Display):
self.controller.media_controller.media_reset(self.controller) self.controller.media_controller.media_reset(self.controller)
self.displayImage(image) self.displayImage(image)
def displayImage(self, image): def display_image(self, image):
""" """
Display an image, as is. Display an image, as is.
""" """
@ -329,16 +326,16 @@ class MainDisplay(Display):
js = u'show_image("");' js = u'show_image("");'
self.frame.evaluateJavaScript(js) self.frame.evaluateJavaScript(js)
def resetImage(self): def reset_image(self):
""" """
Reset the backgound image to the service item image. Used after the Reset the backgound image to the service item image. Used after the
image plugin has changed the background. image plugin has changed the background.
""" """
log.debug(u'resetImage') log.debug(u'resetImage')
if hasattr(self, u'serviceItem'): if hasattr(self, u'serviceItem'):
self.displayImage(self.serviceItem.bg_image_bytes) self.display_image(self.serviceItem.bg_image_bytes)
else: else:
self.displayImage(None) self.display_image(None)
# clear the cache # clear the cache
self.override = {} self.override = {}
@ -361,8 +358,8 @@ class MainDisplay(Display):
self.application.process_events() self.application.process_events()
# if was hidden keep it hidden # if was hidden keep it hidden
if self.isLive: if self.isLive:
if self.hideMode: if self.hide_mode:
self.hide_display(self.hideMode) self.hide_display(self.hide_mode)
else: else:
# Single screen active # Single screen active
if self.screens.display_count == 1: if self.screens.display_count == 1:
@ -373,12 +370,12 @@ class MainDisplay(Display):
self.setVisible(True) self.setVisible(True)
return QtGui.QPixmap.grabWidget(self) return QtGui.QPixmap.grabWidget(self)
def buildHtml(self, serviceItem, image_path=u''): def build_html(self, serviceItem, image_path=u''):
""" """
Store the serviceItem and build the new HTML from it. Add the Store the serviceItem and build the new HTML from it. Add the
HTML to the display HTML to the display
""" """
log.debug(u'buildHtml') log.debug(u'build_html')
self.webLoaded = False self.webLoaded = False
self.initialFrame = None self.initialFrame = None
self.serviceItem = serviceItem self.serviceItem = serviceItem
@ -396,12 +393,11 @@ class MainDisplay(Display):
else: else:
# replace the background # replace the background
background = self.image_manager.get_image_bytes(self.override[u'image'], ImageSource.ImagePlugin) background = self.image_manager.get_image_bytes(self.override[u'image'], ImageSource.ImagePlugin)
self.setTransparency(self.serviceItem.themedata.background_type == self.set_transparency(self.serviceItem.themedata.background_type ==
BackgroundType.to_string(BackgroundType.Transparent)) BackgroundType.to_string(BackgroundType.Transparent))
if self.serviceItem.themedata.background_filename: if self.serviceItem.themedata.background_filename:
self.serviceItem.bg_image_bytes = self.image_manager.get_image_bytes( self.serviceItem.bg_image_bytes = self.image_manager.get_image_bytes(
self.serviceItem.themedata.background_filename, self.serviceItem.themedata.background_filename, ImageSource.Theme
ImageSource.Theme
) )
if image_path: if image_path:
image_bytes = self.image_manager.get_image_bytes(image_path, ImageSource.ImagePlugin) image_bytes = self.image_manager.get_image_bytes(image_path, ImageSource.ImagePlugin)
@ -410,16 +406,16 @@ class MainDisplay(Display):
html = build_html(self.serviceItem, self.screen, self.isLive, background, image_bytes, html = build_html(self.serviceItem, self.screen, self.isLive, background, image_bytes,
plugins=self.plugin_manager.plugins) plugins=self.plugin_manager.plugins)
log.debug(u'buildHtml - pre setHtml') log.debug(u'buildHtml - pre setHtml')
self.webView.setHtml(html) self.web_view.setHtml(html)
log.debug(u'buildHtml - post setHtml') log.debug(u'buildHtml - post setHtml')
if serviceItem.foot_text: if serviceItem.foot_text:
self.footer(serviceItem.foot_text) self.footer(serviceItem.foot_text)
# if was hidden keep it hidden # if was hidden keep it hidden
if self.hideMode and self.isLive and not serviceItem.is_media(): if self.hide_mode and self.isLive and not serviceItem.is_media():
if Settings().value(u'general/auto unblank'): if Settings().value(u'general/auto unblank'):
Registry().execute(u'slidecontroller_live_unblank') Registry().execute(u'slidecontroller_live_unblank')
else: else:
self.hide_display(self.hideMode) self.hide_display(self.hide_mode)
self.__hideMouse() self.__hideMouse()
def footer(self, text): def footer(self, text):
@ -450,13 +446,12 @@ class MainDisplay(Display):
if mode != HideMode.Screen: if mode != HideMode.Screen:
if self.isHidden(): if self.isHidden():
self.setVisible(True) self.setVisible(True)
self.webView.setVisible(True) self.web_view.setVisible(True)
self.hideMode = mode self.hide_mode = mode
def show_display(self): def show_display(self):
""" """
Show the stored layers so the screen reappears as it was Show the stored layers so the screen reappears as it was originally.
originally.
Make the stored images None to release memory. Make the stored images None to release memory.
""" """
log.debug(u'show_display') log.debug(u'show_display')
@ -467,7 +462,7 @@ class MainDisplay(Display):
self.frame.evaluateJavaScript('show_blank("show");') self.frame.evaluateJavaScript('show_blank("show");')
if self.isHidden(): if self.isHidden():
self.setVisible(True) self.setVisible(True)
self.hideMode = None self.hide_mode = None
# Trigger actions when display is active again. # Trigger actions when display is active again.
if self.isLive: if self.isLive:
Registry().execute(u'live_display_active') Registry().execute(u'live_display_active')
@ -533,38 +528,38 @@ class AudioPlayer(QtCore.QObject):
self.currentIndex = -1 self.currentIndex = -1
self.playlist = [] self.playlist = []
self.repeat = False self.repeat = False
self.mediaObject = Phonon.MediaObject() self.media_object = Phonon.MediaObject()
self.mediaObject.setTickInterval(100) self.media_object.setTickInterval(100)
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory) self.audio_object = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self.audioObject) Phonon.createPath(self.media_object, self.audio_object)
QtCore.QObject.connect(self.mediaObject, QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish) self.media_object.aboutToFinish.connect(self.on_about_to_finish)
QtCore.QObject.connect(self.mediaObject, QtCore.SIGNAL(u'finished()'), self.onFinished) self.media_object.finished.connect(self.on_finished)
def __del__(self): def __del__(self):
""" """
Shutting down so clean up connections Shutting down so clean up connections
""" """
self.stop() self.stop()
for path in self.mediaObject.outputPaths(): for path in self.media_object.outputPaths():
path.disconnect() path.disconnect()
def onAboutToFinish(self): def on_about_to_finish(self):
""" """
Just before the audio player finishes the current track, queue the next Just before the audio player finishes the current track, queue the next
item in the playlist, if there is one. item in the playlist, if there is one.
""" """
self.currentIndex += 1 self.currentIndex += 1
if len(self.playlist) > self.currentIndex: if len(self.playlist) > self.currentIndex:
self.mediaObject.enqueue(self.playlist[self.currentIndex]) self.media_object.enqueue(self.playlist[self.currentIndex])
def onFinished(self): def on_finished(self):
""" """
When the audio track finishes. When the audio track finishes.
""" """
if self.repeat: if self.repeat:
log.debug(u'Repeat is enabled... here we go again!') log.debug(u'Repeat is enabled... here we go again!')
self.mediaObject.clearQueue() self.media_object.clearQueue()
self.mediaObject.clear() self.media_object.clear()
self.currentIndex = -1 self.currentIndex = -1
self.play() self.play()
@ -572,7 +567,7 @@ class AudioPlayer(QtCore.QObject):
""" """
Connect the volume slider to the output channel. Connect the volume slider to the output channel.
""" """
slider.setAudioOutput(self.audioObject) slider.setAudioOutput(self.audio_object)
def reset(self): def reset(self):
""" """
@ -581,7 +576,7 @@ class AudioPlayer(QtCore.QObject):
self.currentIndex = -1 self.currentIndex = -1
self.playlist = [] self.playlist = []
self.stop() self.stop()
self.mediaObject.clear() self.media_object.clear()
def play(self): def play(self):
""" """
@ -589,24 +584,24 @@ class AudioPlayer(QtCore.QObject):
""" """
log.debug(u'AudioPlayer.play() called') log.debug(u'AudioPlayer.play() called')
if self.currentIndex == -1: if self.currentIndex == -1:
self.onAboutToFinish() self.on_about_to_finish()
self.mediaObject.play() self.media_object.play()
def pause(self): def pause(self):
""" """
Pause the Audio Pause the Audio
""" """
log.debug(u'AudioPlayer.pause() called') log.debug(u'AudioPlayer.pause() called')
self.mediaObject.pause() self.media_object.pause()
def stop(self): def stop(self):
""" """
Stop the Audio and clean up Stop the Audio and clean up
""" """
log.debug(u'AudioPlayer.stop() called') log.debug(u'AudioPlayer.stop() called')
self.mediaObject.stop() self.media_object.stop()
def addToPlaylist(self, filenames): def add_to_playlist(self, filenames):
""" """
Add another file to the playlist. Add another file to the playlist.
@ -623,31 +618,24 @@ class AudioPlayer(QtCore.QObject):
""" """
if not self.repeat and self.currentIndex + 1 >= len(self.playlist): if not self.repeat and self.currentIndex + 1 >= len(self.playlist):
return return
isPlaying = self.mediaObject.state() == Phonon.PlayingState isPlaying = self.media_object.state() == Phonon.PlayingState
self.currentIndex += 1 self.currentIndex += 1
if self.repeat and self.currentIndex == len(self.playlist): if self.repeat and self.currentIndex == len(self.playlist):
self.currentIndex = 0 self.currentIndex = 0
self.mediaObject.clearQueue() self.media_object.clearQueue()
self.mediaObject.clear() self.media_object.clear()
self.mediaObject.enqueue(self.playlist[self.currentIndex]) self.media_object.enqueue(self.playlist[self.currentIndex])
if isPlaying: if isPlaying:
self.mediaObject.play() self.media_object.play()
def goTo(self, index): def go_to(self, index):
""" """
Go to a particular track in the list Go to a particular track in the list
""" """
isPlaying = self.mediaObject.state() == Phonon.PlayingState isPlaying = self.media_object.state() == Phonon.PlayingState
self.mediaObject.clearQueue() self.media_object.clearQueue()
self.mediaObject.clear() self.media_object.clear()
self.currentIndex = index self.currentIndex = index
self.mediaObject.enqueue(self.playlist[self.currentIndex]) self.media_object.enqueue(self.playlist[self.currentIndex])
if isPlaying: if isPlaying:
self.mediaObject.play() self.media_object.play()
#@todo is this used?
def connectSlot(self, signal, slot):
"""
Connect a slot to a signal on the media object
"""
QtCore.QObject.connect(self.mediaObject, signal, slot)

View File

@ -307,8 +307,8 @@ class WebkitPlayer(MediaPlayer):
""" """
Set up the player Set up the player
""" """
display.webView.resize(display.size()) display.web_view.resize(display.size())
display.webView.raise_() display.web_view.raise_()
self.hasOwnWidget = False self.hasOwnWidget = False
def check_available(self): def check_available(self):
@ -333,7 +333,7 @@ class WebkitPlayer(MediaPlayer):
loop = u'true' loop = u'true'
else: else:
loop = u'false' loop = u'false'
display.webView.setVisible(True) display.web_view.setVisible(True)
if controller.media_info.file_info.suffix() == u'swf': if controller.media_info.file_info.suffix() == u'swf':
controller.media_info.is_flash = True controller.media_info.is_flash = True
js = u'show_flash("load","%s");' % (path.replace(u'\\', u'\\\\')) js = u'show_flash("load","%s");' % (path.replace(u'\\', u'\\\\'))
@ -346,14 +346,14 @@ class WebkitPlayer(MediaPlayer):
""" """
Resize the player Resize the player
""" """
display.webView.resize(display.size()) display.web_view.resize(display.size())
def play(self, display): def play(self, display):
""" """
Play a video Play a video
""" """
controller = display.controller controller = display.controller
display.webLoaded = True display.web_loaded = True
length = 0 length = 0
start_time = 0 start_time = 0
if self.state != MediaState.Paused and controller.media_info.start_time > 0: if self.state != MediaState.Paused and controller.media_info.start_time > 0:
@ -368,7 +368,7 @@ class WebkitPlayer(MediaPlayer):
# TODO add playing check and get the correct media length # TODO add playing check and get the correct media length
controller.media_info.length = length controller.media_info.length = length
self.state = MediaState.Playing self.state = MediaState.Playing
display.webView.raise_() display.web_view.raise_()
return True return True
def pause(self, display): def pause(self, display):

View File

@ -538,7 +538,7 @@ class SlideController(DisplayController):
self.previewSizeChanged() self.previewSizeChanged()
self.previewDisplay.setup() self.previewDisplay.setup()
serviceItem = ServiceItem() serviceItem = ServiceItem()
self.previewDisplay.webView.setHtml(build_html(serviceItem, self.previewDisplay.screen, None, self.isLive, self.previewDisplay.web_view.setHtml(build_html(serviceItem, self.previewDisplay.screen, None, self.isLive,
plugins=self.plugin_manager.plugins)) plugins=self.plugin_manager.plugins))
self.media_controller.setup_display(self.previewDisplay, True) self.media_controller.setup_display(self.previewDisplay, True)
if self.serviceItem: if self.serviceItem:
@ -760,7 +760,7 @@ class SlideController(DisplayController):
# If the current item has background audio # If the current item has background audio
if self.serviceItem.is_capable(ItemCapabilities.HasBackgroundAudio): if self.serviceItem.is_capable(ItemCapabilities.HasBackgroundAudio):
log.debug(u'Starting to play...') log.debug(u'Starting to play...')
self.display.audioPlayer.addToPlaylist(self.serviceItem.background_audio) self.display.audioPlayer.add_to_playlist(self.serviceItem.background_audio)
self.trackMenu.clear() self.trackMenu.clear()
for counter in range(len(self.serviceItem.background_audio)): for counter in range(len(self.serviceItem.background_audio)):
action = self.trackMenu.addAction(os.path.basename(self.serviceItem.background_audio[counter])) action = self.trackMenu.addAction(os.path.basename(self.serviceItem.background_audio[counter]))
@ -831,7 +831,7 @@ class SlideController(DisplayController):
# Postpone image build, we need to do this later to avoid the theme # Postpone image build, we need to do this later to avoid the theme
# flashing on the screen # flashing on the screen
if not self.serviceItem.is_image(): if not self.serviceItem.is_image():
self.display.buildHtml(self.serviceItem) self.display.build_html(self.serviceItem)
if serviceItem.is_media(): if serviceItem.is_media():
self.onMediaStart(serviceItem) self.onMediaStart(serviceItem)
self.slideSelected(True) self.slideSelected(True)
@ -1025,7 +1025,7 @@ class SlideController(DisplayController):
self.display.text(to_display) self.display.text(to_display)
else: else:
if start: if start:
self.display.buildHtml(self.serviceItem, to_display) self.display.build_html(self.serviceItem, to_display)
else: else:
self.display.image(to_display) self.display.image(to_display)
# reset the store used to display first image # reset the store used to display first image
@ -1333,7 +1333,7 @@ class SlideController(DisplayController):
Start playing a track Start playing a track
""" """
action = self.sender() action = self.sender()
self.display.audioPlayer.goTo(action.data()) self.display.audioPlayer.go_to(action.data())
def _get_plugin_manager(self): def _get_plugin_manager(self):
""" """

View File

@ -192,7 +192,7 @@ class ImageMediaItem(MediaManagerItem):
Called to reset the Live background with the image selected, Called to reset the Live background with the image selected,
""" """
self.resetAction.setVisible(False) self.resetAction.setVisible(False)
self.live_controller.display.resetImage() self.live_controller.display.reset_image()
def live_theme_changed(self): def live_theme_changed(self):
""" """
@ -211,7 +211,7 @@ class ImageMediaItem(MediaManagerItem):
bitem = self.listView.item(item.row()) bitem = self.listView.item(item.row())
filename = bitem.data(QtCore.Qt.UserRole) filename = bitem.data(QtCore.Qt.UserRole)
if os.path.exists(filename): if os.path.exists(filename):
if self.live_controller.display.directImage(filename, background): if self.live_controller.display.direct_image(filename, background):
self.resetAction.setVisible(True) self.resetAction.setVisible(True)
else: else:
critical_error_message_box(UiStrings().LiveBGError, critical_error_message_box(UiStrings().LiveBGError,

View File

@ -129,6 +129,7 @@ from openlp.core.utils import AppLocation, translate
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class HttpResponse(object): class HttpResponse(object):
""" """
A simple object to encapsulate a pseudo-http response. A simple object to encapsulate a pseudo-http response.
@ -178,7 +179,7 @@ class HttpServer(object):
self.server.listen(QtNetwork.QHostAddress(address), port) self.server.listen(QtNetwork.QHostAddress(address), port)
Registry().register_function(u'slidecontroller_live_changed', self.slide_change) Registry().register_function(u'slidecontroller_live_changed', self.slide_change)
Registry().register_function(u'slidecontroller_live_started', self.item_change) Registry().register_function(u'slidecontroller_live_started', self.item_change)
QtCore.QObject.connect(self.server, QtCore.SIGNAL(u'newConnection()'), self.new_connection) self.server.newConnection.connect(self.new_connection)
log.debug(u'TCP listening on port %d' % port) log.debug(u'TCP listening on port %d' % port)
def slide_change(self, row): def slide_change(self, row):
@ -245,8 +246,8 @@ class HttpConnection(object):
(r'^/api/(.*)/live$', self.go_live), (r'^/api/(.*)/live$', self.go_live),
(r'^/api/(.*)/add$', self.add_to_service) (r'^/api/(.*)/add$', self.add_to_service)
] ]
QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'readyRead()'), self.ready_read) self.socket.readyRead.connect(self.ready_read)
QtCore.QObject.connect(self.socket, QtCore.SIGNAL(u'disconnected()'), self.disconnected) self.socket.disconnected.connect(self.disconnected)
self.translate() self.translate()
def _get_service_items(self): def _get_service_items(self):
@ -255,7 +256,7 @@ class HttpConnection(object):
current_unique_identifier = self.parent.current_item.unique_identifier current_unique_identifier = self.parent.current_item.unique_identifier
else: else:
current_unique_identifier = None current_unique_identifier = None
for item in self.service_manager.serviceItems: for item in self.service_manager.service_items:
service_item = item[u'service_item'] service_item = item[u'service_item']
service_items.append({ service_items.append({
u'id': unicode(service_item.unique_identifier), u'id': unicode(service_item.unique_identifier),
@ -389,13 +390,12 @@ class HttpConnection(object):
u'service': self.service_manager.service_id, u'service': self.service_manager.service_id,
u'slide': self.parent.current_slide or 0, u'slide': self.parent.current_slide or 0,
u'item': self.parent.current_item.unique_identifier if self.parent.current_item else u'', u'item': self.parent.current_item.unique_identifier if self.parent.current_item else u'',
u'twelve':Settings().value(u'remotes/twelve hour'), u'twelve': Settings().value(u'remotes/twelve hour'),
u'blank': self.live_controller.blankScreen.isChecked(), u'blank': self.live_controller.blankScreen.isChecked(),
u'theme': self.live_controller.themeScreen.isChecked(), u'theme': self.live_controller.themeScreen.isChecked(),
u'display': self.live_controller.desktopScreen.isChecked() u'display': self.live_controller.desktopScreen.isChecked()
} }
return HttpResponse(json.dumps({u'results': result}), return HttpResponse(json.dumps({u'results': result}), {u'Content-Type': u'application/json'})
{u'Content-Type': u'application/json'})
def display(self, action): def display(self, action):
""" """
@ -426,18 +426,17 @@ class HttpConnection(object):
return HttpResponse(json.dumps({u'results': {u'success': success}}), return HttpResponse(json.dumps({u'results': {u'success': success}}),
{u'Content-Type': u'application/json'}) {u'Content-Type': u'application/json'})
def controller(self, type, action): def controller(self, display_type, action):
""" """
Perform an action on the slide controller. Perform an action on the slide controller.
``type`` ``display_type``
This is the type of slide controller, either ``preview`` or This is the type of slide controller, either ``preview`` or ``live``.
``live``.
``action`` ``action``
The action to perform. The action to perform.
""" """
event = u'slidecontroller_%s_%s' % (type, action) event = u'slidecontroller_%s_%s' % (display_type, action)
if action == u'text': if action == u'text':
current_item = self.parent.current_item current_item = self.parent.current_item
data = [] data = []
@ -473,10 +472,15 @@ class HttpConnection(object):
else: else:
Registry().execute(event) Registry().execute(event)
json_data = {u'results': {u'success': True}} json_data = {u'results': {u'success': True}}
return HttpResponse(json.dumps(json_data), return HttpResponse(json.dumps(json_data), {u'Content-Type': u'application/json'})
{u'Content-Type': u'application/json'})
def service(self, action): def service(self, action):
"""
Handles requests for service items
``action``
The action to perform.
"""
event = u'servicemanager_%s' % action event = u'servicemanager_%s' % action
if action == u'list': if action == u'list':
return HttpResponse(json.dumps({u'results': {u'items': self._get_service_items()}}), return HttpResponse(json.dumps({u'results': {u'items': self._get_service_items()}}),
@ -491,8 +495,7 @@ class HttpConnection(object):
Registry().execute(event, data[u'request'][u'id']) Registry().execute(event, data[u'request'][u'id'])
else: else:
Registry().execute(event) Registry().execute(event)
return HttpResponse(json.dumps({u'results': {u'success': True}}), return HttpResponse(json.dumps({u'results': {u'success': True}}), {u'Content-Type': u'application/json'})
{u'Content-Type': u'application/json'})
def pluginInfo(self, action): def pluginInfo(self, action):
""" """
@ -507,15 +510,13 @@ class HttpConnection(object):
for plugin in self.plugin_manager.plugins: for plugin in self.plugin_manager.plugins:
if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch: if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch:
searches.append([plugin.name, unicode(plugin.textStrings[StringContent.Name][u'plural'])]) searches.append([plugin.name, unicode(plugin.textStrings[StringContent.Name][u'plural'])])
return HttpResponse( return HttpResponse(json.dumps({u'results': {u'items': searches}}), {u'Content-Type': u'application/json'})
json.dumps({u'results': {u'items': searches}}),
{u'Content-Type': u'application/json'})
def search(self, type): def search(self, plugin_name):
""" """
Return a list of items that match the search text. Return a list of items that match the search text.
``type`` ``plugin``
The plugin name to search in. The plugin name to search in.
""" """
try: try:
@ -523,36 +524,35 @@ class HttpConnection(object):
except KeyError, ValueError: except KeyError, ValueError:
return HttpResponse(code=u'400 Bad Request') return HttpResponse(code=u'400 Bad Request')
text = urllib.unquote(text) text = urllib.unquote(text)
plugin = self.plugin_manager.get_plugin_by_name(type) plugin = self.plugin_manager.get_plugin_by_name(plugin_name)
if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch: if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch:
results = plugin.mediaItem.search(text, False) results = plugin.mediaItem.search(text, False)
else: else:
results = [] results = []
return HttpResponse(json.dumps({u'results': {u'items': results}}), return HttpResponse(json.dumps({u'results': {u'items': results}}), {u'Content-Type': u'application/json'})
{u'Content-Type': u'application/json'})
def go_live(self, type): def go_live(self, plugin_name):
""" """
Go live on an item of type ``type``. Go live on an item of type ``plugin``.
""" """
try: try:
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id'] id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
except KeyError, ValueError: except KeyError, ValueError:
return HttpResponse(code=u'400 Bad Request') return HttpResponse(code=u'400 Bad Request')
plugin = self.plugin_manager.get_plugin_by_name(type) plugin = self.plugin_manager.get_plugin_by_name(plugin_name)
if plugin.status == PluginStatus.Active and plugin.mediaItem: if plugin.status == PluginStatus.Active and plugin.mediaItem:
plugin.mediaItem.goLive(id, remote=True) plugin.mediaItem.goLive(id, remote=True)
return HttpResponse(code=u'200 OK') return HttpResponse(code=u'200 OK')
def add_to_service(self, type): def add_to_service(self, plugin_name):
""" """
Add item of type ``type`` to the end of the service. Add item of type ``plugin_name`` to the end of the service.
""" """
try: try:
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id'] id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
except KeyError, ValueError: except KeyError, ValueError:
return HttpResponse(code=u'400 Bad Request') return HttpResponse(code=u'400 Bad Request')
plugin = self.plugin_manager.get_plugin_by_name(type) plugin = self.plugin_manager.get_plugin_by_name(plugin_name)
if plugin.status == PluginStatus.Active and plugin.mediaItem: if plugin.status == PluginStatus.Active and plugin.mediaItem:
item_id = plugin.mediaItem.createItemFromId(id) item_id = plugin.mediaItem.createItemFromId(id)
plugin.mediaItem.addToService(item_id, remote=True) plugin.mediaItem.addToService(item_id, remote=True)

View File

@ -45,117 +45,115 @@ class RemoteTab(SettingsTab):
def setupUi(self): def setupUi(self):
self.setObjectName(u'RemoteTab') self.setObjectName(u'RemoteTab')
SettingsTab.setupUi(self) SettingsTab.setupUi(self)
self.serverSettingsGroupBox = QtGui.QGroupBox(self.leftColumn) self.server_settings_group_box = QtGui.QGroupBox(self.leftColumn)
self.serverSettingsGroupBox.setObjectName(u'serverSettingsGroupBox') self.server_settings_group_box.setObjectName(u'server_settings_group_box')
self.serverSettingsLayout = QtGui.QFormLayout(self.serverSettingsGroupBox) self.server_settings_layout = QtGui.QFormLayout(self.server_settings_group_box)
self.serverSettingsLayout.setObjectName(u'serverSettingsLayout') self.server_settings_layout.setObjectName(u'server_settings_layout')
self.addressLabel = QtGui.QLabel(self.serverSettingsGroupBox) self.address_label = QtGui.QLabel(self.server_settings_group_box)
self.addressLabel.setObjectName(u'addressLabel') self.address_label.setObjectName(u'address_label')
self.addressEdit = QtGui.QLineEdit(self.serverSettingsGroupBox) self.address_edit = QtGui.QLineEdit(self.server_settings_group_box)
self.addressEdit.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) self.address_edit.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
self.addressEdit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp( self.address_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(
u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), self)) u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), self))
self.addressEdit.setObjectName(u'addressEdit') self.address_edit.setObjectName(u'address_edit')
QtCore.QObject.connect(self.addressEdit, QtCore.SIGNAL(u'textChanged(const QString&)'), self.setUrls) self.server_settings_layout.addRow(self.address_label, self.address_edit)
self.serverSettingsLayout.addRow(self.addressLabel, self.addressEdit) self.twelve_hour_check_box = QtGui.QCheckBox(self.server_settings_group_box)
self.twelveHourCheckBox = QtGui.QCheckBox(self.serverSettingsGroupBox) self.twelve_hour_check_box.setObjectName(u'twelve_hour_check_box')
self.twelveHourCheckBox.setObjectName(u'twelveHourCheckBox') self.server_settings_layout.addRow(self.twelve_hour_check_box)
self.serverSettingsLayout.addRow(self.twelveHourCheckBox) self.portLabel = QtGui.QLabel(self.server_settings_group_box)
self.portLabel = QtGui.QLabel(self.serverSettingsGroupBox)
self.portLabel.setObjectName(u'portLabel') self.portLabel.setObjectName(u'portLabel')
self.portSpinBox = QtGui.QSpinBox(self.serverSettingsGroupBox) self.port_spin_box = QtGui.QSpinBox(self.server_settings_group_box)
self.portSpinBox.setMaximum(32767) self.port_spin_box.setMaximum(32767)
self.portSpinBox.setObjectName(u'portSpinBox') self.port_spin_box.setObjectName(u'port_spin_box')
QtCore.QObject.connect(self.portSpinBox, QtCore.SIGNAL(u'valueChanged(int)'), self.setUrls) self.server_settings_layout.addRow(self.portLabel, self.port_spin_box)
self.serverSettingsLayout.addRow(self.portLabel, self.portSpinBox) self.remote_url_label = QtGui.QLabel(self.server_settings_group_box)
self.remoteUrlLabel = QtGui.QLabel(self.serverSettingsGroupBox) self.remote_url_label.setObjectName(u'remote_url_label')
self.remoteUrlLabel.setObjectName(u'remoteUrlLabel') self.remote_url = QtGui.QLabel(self.server_settings_group_box)
self.remoteUrl = QtGui.QLabel(self.serverSettingsGroupBox) self.remote_url.setObjectName(u'remote_url')
self.remoteUrl.setObjectName(u'remoteUrl') self.remote_url.setOpenExternalLinks(True)
self.remoteUrl.setOpenExternalLinks(True) self.server_settings_layout.addRow(self.remote_url_label, self.remote_url)
self.serverSettingsLayout.addRow(self.remoteUrlLabel, self.remoteUrl) self.stage_url_label = QtGui.QLabel(self.server_settings_group_box)
self.stageUrlLabel = QtGui.QLabel(self.serverSettingsGroupBox) self.stage_url_label.setObjectName(u'stage_url_label')
self.stageUrlLabel.setObjectName(u'stageUrlLabel') self.stage_url = QtGui.QLabel(self.server_settings_group_box)
self.stageUrl = QtGui.QLabel(self.serverSettingsGroupBox) self.stage_url.setObjectName(u'stage_url')
self.stageUrl.setObjectName(u'stageUrl') self.stage_url.setOpenExternalLinks(True)
self.stageUrl.setOpenExternalLinks(True) self.server_settings_layout.addRow(self.stage_url_label, self.stage_url)
self.serverSettingsLayout.addRow(self.stageUrlLabel, self.stageUrl) self.leftLayout.addWidget(self.server_settings_group_box)
self.leftLayout.addWidget(self.serverSettingsGroupBox) self.android_app_group_box = QtGui.QGroupBox(self.rightColumn)
self.androidAppGroupBox = QtGui.QGroupBox(self.rightColumn) self.android_app_group_box.setObjectName(u'android_app_group_box')
self.androidAppGroupBox.setObjectName(u'androidAppGroupBox') self.rightLayout.addWidget(self.android_app_group_box)
self.rightLayout.addWidget(self.androidAppGroupBox) self.qr_layout = QtGui.QVBoxLayout(self.android_app_group_box)
self.qrLayout = QtGui.QVBoxLayout(self.androidAppGroupBox) self.qr_layout.setObjectName(u'qr_layout')
self.qrLayout.setObjectName(u'qrLayout') self.qr_code_label = QtGui.QLabel(self.android_app_group_box)
self.qrCodeLabel = QtGui.QLabel(self.androidAppGroupBox) self.qr_code_label.setPixmap(QtGui.QPixmap(u':/remotes/android_app_qr.png'))
self.qrCodeLabel.setPixmap(QtGui.QPixmap(u':/remotes/android_app_qr.png')) self.qr_code_label.setAlignment(QtCore.Qt.AlignCenter)
self.qrCodeLabel.setAlignment(QtCore.Qt.AlignCenter) self.qr_code_label.setObjectName(u'qr_code_label')
self.qrCodeLabel.setObjectName(u'qrCodeLabel') self.qr_layout.addWidget(self.qr_code_label)
self.qrLayout.addWidget(self.qrCodeLabel) self.qr_description_label = QtGui.QLabel(self.android_app_group_box)
self.qrDescriptionLabel = QtGui.QLabel(self.androidAppGroupBox) self.qr_description_label.setObjectName(u'qr_description_label')
self.qrDescriptionLabel.setObjectName(u'qrDescriptionLabel') self.qr_description_label.setOpenExternalLinks(True)
self.qrDescriptionLabel.setOpenExternalLinks(True) self.qr_description_label.setWordWrap(True)
self.qrDescriptionLabel.setWordWrap(True) self.qr_layout.addWidget(self.qr_description_label)
self.qrLayout.addWidget(self.qrDescriptionLabel)
self.leftLayout.addStretch() self.leftLayout.addStretch()
self.rightLayout.addStretch() self.rightLayout.addStretch()
QtCore.QObject.connect(self.twelveHourCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.twelve_hour_check_box.stateChanged.connect(self.onTwelveHourCheckBoxChanged)
self.onTwelveHourCheckBoxChanged) self.address_edit.textChanged.connect(self.set_urls)
self.port_spin_box.valueChanged.connect(self.set_urls)
def retranslateUi(self): def retranslateUi(self):
self.serverSettingsGroupBox.setTitle( self.server_settings_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'Server Settings'))
translate('RemotePlugin.RemoteTab', 'Server Settings')) self.address_label.setText(translate('RemotePlugin.RemoteTab', 'Serve on IP address:'))
self.addressLabel.setText(translate('RemotePlugin.RemoteTab', 'Serve on IP address:'))
self.portLabel.setText(translate('RemotePlugin.RemoteTab', 'Port number:')) self.portLabel.setText(translate('RemotePlugin.RemoteTab', 'Port number:'))
self.remoteUrlLabel.setText(translate('RemotePlugin.RemoteTab', 'Remote URL:')) self.remote_url_label.setText(translate('RemotePlugin.RemoteTab', 'Remote URL:'))
self.stageUrlLabel.setText(translate('RemotePlugin.RemoteTab', 'Stage view URL:')) self.stage_url_label.setText(translate('RemotePlugin.RemoteTab', 'Stage view URL:'))
self.twelveHourCheckBox.setText(translate('RemotePlugin.RemoteTab', 'Display stage time in 12h format')) self.twelve_hour_check_box.setText(translate('RemotePlugin.RemoteTab', 'Display stage time in 12h format'))
self.androidAppGroupBox.setTitle(translate('RemotePlugin.RemoteTab', 'Android App')) self.android_app_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'Android App'))
self.qrDescriptionLabel.setText(translate('RemotePlugin.RemoteTab', self.qr_description_label.setText(translate('RemotePlugin.RemoteTab',
'Scan the QR code or click <a href="https://play.google.com/store/' 'Scan the QR code or click <a href="https://play.google.com/store/'
'apps/details?id=org.openlp.android">download</a> to install the ' 'apps/details?id=org.openlp.android">download</a> to install the '
'Android app from Google Play.')) 'Android app from Google Play.'))
def setUrls(self): def set_urls(self):
ipAddress = u'localhost' ipAddress = u'localhost'
if self.addressEdit.text() == ZERO_URL: if self.address_edit.text() == ZERO_URL:
ifaces = QtNetwork.QNetworkInterface.allInterfaces() interfaces = QtNetwork.QNetworkInterface.allInterfaces()
for iface in ifaces: for interface in interfaces:
if not iface.isValid(): if not interface.isValid():
continue continue
if not (iface.flags() & (QtNetwork.QNetworkInterface.IsUp | QtNetwork.QNetworkInterface.IsRunning)): if not (interface.flags() & (QtNetwork.QNetworkInterface.IsUp | QtNetwork.QNetworkInterface.IsRunning)):
continue continue
for addr in iface.addressEntries(): for address in interface.addressEntries():
ip = addr.ip() ip = address.ip()
if ip.protocol() == 0 and ip != QtNetwork.QHostAddress.LocalHost: if ip.protocol() == 0 and ip != QtNetwork.QHostAddress.LocalHost:
ipAddress = ip ipAddress = ip
break break
else: else:
ipAddress = self.addressEdit.text() ipAddress = self.address_edit.text()
url = u'http://%s:%s/' % (ipAddress, self.portSpinBox.value()) url = u'http://%s:%s/' % (ipAddress, self.port_spin_box.value())
self.remoteUrl.setText(u'<a href="%s">%s</a>' % (url, url)) self.remote_url.setText(u'<a href="%s">%s</a>' % (url, url))
url += u'stage' url += u'stage'
self.stageUrl.setText(u'<a href="%s">%s</a>' % (url, url)) self.stage_url.setText(u'<a href="%s">%s</a>' % (url, url))
def load(self): def load(self):
self.portSpinBox.setValue(Settings().value(self.settingsSection + u'/port')) self.port_spin_box.setValue(Settings().value(self.settingsSection + u'/port'))
self.addressEdit.setText(Settings().value(self.settingsSection + u'/ip address')) self.address_edit.setText(Settings().value(self.settingsSection + u'/ip address'))
self.twelveHour = Settings().value(self.settingsSection + u'/twelve hour') self.twelve_hour = Settings().value(self.settingsSection + u'/twelve hour')
self.twelveHourCheckBox.setChecked(self.twelveHour) self.twelve_hour_check_box.setChecked(self.twelve_hour)
self.setUrls() self.set_urls()
def save(self): def save(self):
changed = False changed = False
if Settings().value(self.settingsSection + u'/ip address') != self.addressEdit.text() or \ if Settings().value(self.settingsSection + u'/ip address') != self.address_edit.text() or \
Settings().value(self.settingsSection + u'/port') != self.portSpinBox.value(): Settings().value(self.settingsSection + u'/port') != self.port_spin_box.value():
changed = True changed = True
Settings().setValue(self.settingsSection + u'/port', self.portSpinBox.value()) Settings().setValue(self.settingsSection + u'/port', self.port_spin_box.value())
Settings().setValue(self.settingsSection + u'/ip address', self.addressEdit.text()) Settings().setValue(self.settingsSection + u'/ip address', self.address_edit.text())
Settings().setValue(self.settingsSection + u'/twelve hour', self.twelveHour) Settings().setValue(self.settingsSection + u'/twelve hour', self.twelve_hour)
if changed: if changed:
Registry().register_function(u'remotes_config_updated') Registry().register_function(u'remotes_config_updated')
def onTwelveHourCheckBoxChanged(self, check_state): def onTwelveHourCheckBoxChanged(self, check_state):
self.twelveHour = False self.twelve_hour = False
# we have a set value convert to True/False # we have a set value convert to True/False
if check_state == QtCore.Qt.Checked: if check_state == QtCore.Qt.Checked:
self.twelveHour = True self.twelve_hour = True

View File

@ -38,7 +38,7 @@ __default_settings__ = {
u'remotes/twelve hour': True, u'remotes/twelve hour': True,
u'remotes/port': 4316, u'remotes/port': 4316,
u'remotes/ip address': u'0.0.0.0' u'remotes/ip address': u'0.0.0.0'
} }
class RemotesPlugin(Plugin): class RemotesPlugin(Plugin):