Merge HEAD

This commit is contained in:
Arjan Schrijver 2013-03-07 12:23:52 +01:00
commit 52523224ec
34 changed files with 1063 additions and 1034 deletions

View File

@ -127,7 +127,7 @@ sup {
document.getElementById('footer').innerHTML = footertext;
}
function show_text(newtext){
function show_text(new_text){
var match = /-webkit-text-fill-color:[^;\"]+/gi;
if(timer != null)
clearTimeout(timer);
@ -142,57 +142,47 @@ sup {
if(outline != null)
txt = outline;
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
newtext = newtext.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
new_text = new_text.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
function(match) {
return '</span>' + match + '<span>';
});
newtext = '<span>' + newtext + '</span>';
new_text = '<span>' + new_text + '</span>';
}
}
text_fade('lyricsmain', newtext);
text_fade('lyricsoutline', newtext);
text_fade('lyricsshadow', newtext.replace(match, ''));
if(text_opacity() == 1) return;
timer = setTimeout(function(){
show_text(newtext);
}, 100);
text_fade('lyricsmain', new_text);
text_fade('lyricsoutline', new_text);
text_fade('lyricsshadow', new_text.replace(match, ''));
}
function text_fade(id, newtext){
function text_fade(id, new_text){
/*
Using -webkit-transition: opacity 1s linear; would have been preferred
but it isn't currently quick enough when animating multiple layers of
large areas of large text. Therefore do it manually as best we can.
Hopefully in the future we can revisit and do more interesting
transitions using -webkit-transition and -webkit-transform.
However we need to ensure interrupted transitions (quickly change 2
slides) still looks pretty and is zippy.
Show the text.
*/
var text = document.getElementById(id);
if(text == null) return;
if(!transition){
text.innerHTML = newtext;
text.innerHTML = new_text;
return;
}
if(newtext == text.innerHTML){
text.style.opacity = parseFloat(text.style.opacity) + 0.3;
if(text.style.opacity > 0.7)
text.style.opacity = 1;
} else {
text.style.opacity = parseFloat(text.style.opacity) - 0.3;
if(text.style.opacity <= 0.1){
text.innerHTML = newtext;
}
}
// Fade text out. 0.2 to minimize the time "nothing" is shown on the screen.
text.style.opacity = '0.2';
// Fade new text in after the old text has finished fading out.
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
}
function text_opacity(){
var text = document.getElementById('lyricsmain');
return getComputedStyle(text, '').opacity;
function _show_text(text, new_text) {
/*
Helper function to show the new_text delayed.
*/
text.innerHTML = new_text;
text.style.opacity = '1';
// Wait until the text is completely visible. We want to save the timer id, to be able to call
// clearTimeout(timer) when the text has changed before finishing fading.
timer = window.setTimeout(function(){timer = null;}, 400);
}
function show_text_complete(){
return (text_opacity() == 1);
function show_text_completed(){
return (timer == null);
}
</script>
</head>
@ -218,7 +208,7 @@ def build_html(item, screen, is_live, background, image=None, plugins=None):
``screen``
Current display information
``islive``
``is_live``
Item is going live, rather than preview/theme building
``background``
@ -336,6 +326,7 @@ def build_lyrics_css(item, webkit_ver):
.lyricscell {
display: table-cell;
word-wrap: break-word;
-webkit-transition: opacity 0.4s ease;
%s
}
.lyricsmain {

View File

@ -148,7 +148,7 @@ class Plugin(QtCore.QObject):
QtCore.QObject.__init__(self)
self.name = name
self.textStrings = {}
self.setPluginTextStrings()
self.set_plugin_text_strings()
self.nameStrings = self.textStrings[StringContent.Name]
if version:
self.version = version
@ -311,7 +311,7 @@ class Plugin(QtCore.QObject):
# Now save the list to the config using our Settings class.
Settings().setValue(u'%s/%s files' % (self.settingsSection, self.name), loaded_list)
def usesTheme(self, theme):
def uses_theme(self, theme):
"""
Called to find out if a plugin is currently using a theme.
@ -319,7 +319,7 @@ class Plugin(QtCore.QObject):
"""
return False
def renameTheme(self, oldTheme, newTheme):
def rename_theme(self, oldTheme, newTheme):
"""
Renames a theme a plugin is using making the plugin use the new name.

View File

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

View File

@ -68,7 +68,7 @@ class Display(QtGui.QGraphicsView):
self.parent = lambda: parent
else:
QtGui.QGraphicsView.__init__(self, parent)
self.isLive = live
self.is_live = live
self.controller = controller
self.screen = {}
# FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with
@ -82,40 +82,37 @@ class Display(QtGui.QGraphicsView):
"""
Set up and build the screen base
"""
log.debug(u'Start Display base setup (live = %s)' % self.isLive)
log.debug(u'Start Display base setup (live = %s)' % self.is_live)
self.setGeometry(self.screen[u'size'])
log.debug(u'Setup webView')
self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0, self.screen[u'size'].width(), self.screen[u'size'].height())
self.webView.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True)
palette = self.webView.palette()
self.web_view = QtWebKit.QWebView(self)
self.web_view.setGeometry(0, 0, self.screen[u'size'].width(), self.screen[u'size'].height())
self.web_view.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True)
palette = self.web_view.palette()
palette.setBrush(QtGui.QPalette.Base, QtCore.Qt.transparent)
self.webView.page().setPalette(palette)
self.webView.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, False)
self.page = self.webView.page()
self.web_view.page().setPalette(palette)
self.web_view.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, False)
self.page = self.web_view.page()
self.frame = self.page.mainFrame()
if self.isLive and log.getEffectiveLevel() == logging.DEBUG:
self.webView.settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
QtCore.QObject.connect(self.webView,
QtCore.SIGNAL(u'loadFinished(bool)'), self.isWebLoaded)
if self.is_live and log.getEffectiveLevel() == logging.DEBUG:
self.web_view.settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
self.web_view.loadFinished.connect(self.is_web_loaded)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical,
QtCore.Qt.ScrollBarAlwaysOff)
self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal,
QtCore.Qt.ScrollBarAlwaysOff)
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)
self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
def resizeEvent(self, event):
"""
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
"""
log.debug(u'Webloaded')
log.debug(u'is web loaded')
self.webLoaded = True
@ -129,11 +126,11 @@ class MainDisplay(Display):
"""
Display.__init__(self, parent, live, controller)
self.screens = ScreenList()
self.rebuildCSS = False
self.hideMode = None
self.rebuild_css = False
self.hide_mode = None
self.override = {}
self.retranslateUi()
self.mediaObject = None
self.media_object = None
if live:
self.audioPlayer = AudioPlayer(self)
else:
@ -156,14 +153,14 @@ class MainDisplay(Display):
self.setWindowState(QtCore.Qt.WindowFullScreen)
self.setWindowFlags(windowFlags)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setTransparency(False)
if self.isLive:
self.set_transparency(False)
if self.is_live:
Registry().register_function(u'live_display_hide', self.hide_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'config_updated', self.config_changed)
def setTransparency(self, enabled):
def set_transparency(self, enabled):
"""
Set the transparency of the window
"""
@ -178,17 +175,17 @@ class MainDisplay(Display):
"""
We may need to rebuild the CSS on the live display.
"""
self.rebuildCSS = True
self.rebuild_css = True
def config_changed(self):
"""
Call the plugins to rebuild the Live display CSS as the screen has
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:
plugin.refreshCss(self.frame)
self.rebuildCSS = False
self.rebuild_css = False
def retranslateUi(self):
"""
@ -200,11 +197,11 @@ class MainDisplay(Display):
"""
Set up and build the output screen
"""
log.debug(u'Start MainDisplay setup (live = %s)' % self.isLive)
log.debug(u'Start MainDisplay setup (live = %s)' % self.is_live)
self.screen = self.screens.current
self.setVisible(False)
Display.setup(self)
if self.isLive:
if self.is_live:
# Build the initial frame.
background_color = QtGui.QColor()
background_color.setNamedColor(Settings().value(u'advanced/default color'))
@ -225,7 +222,7 @@ class MainDisplay(Display):
splash_image)
serviceItem = ServiceItem()
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.is_live, None,
plugins=self.plugin_manager.plugins))
self.__hideMouse()
log.debug(u'Finished MainDisplay setup')
@ -288,7 +285,7 @@ class MainDisplay(Display):
self.setVisible(False)
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.
"""
@ -299,7 +296,7 @@ class MainDisplay(Display):
self.override[u'theme'] = self.serviceItem.themedata.background_filename
self.image(path)
# Update the preview frame.
if self.isLive:
if self.is_live:
self.live_controller.updatePreview()
return True
@ -316,9 +313,9 @@ class MainDisplay(Display):
log.debug(u'image to display')
image = self.image_manager.get_image_bytes(path, ImageSource.ImagePlugin)
self.controller.media_controller.media_reset(self.controller)
self.displayImage(image)
self.display_image(image)
def displayImage(self, image):
def display_image(self, image):
"""
Display an image, as is.
"""
@ -329,16 +326,16 @@ class MainDisplay(Display):
js = u'show_image("");'
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 background image to the service item image. Used after the
image plugin has changed the background.
"""
log.debug(u'resetImage')
log.debug(u'reset_image')
if hasattr(self, u'serviceItem'):
self.displayImage(self.serviceItem.bg_image_bytes)
self.display_image(self.serviceItem.bg_image_bytes)
else:
self.displayImage(None)
self.display_image(None)
# clear the cache
self.override = {}
@ -346,24 +343,27 @@ class MainDisplay(Display):
"""
Generates a preview of the image displayed.
"""
log.debug(u'preview for %s', self.isLive)
log.debug(u'preview for %s', self.is_live)
was_visible = self.isVisible()
self.application.process_events()
# We must have a service item to preview.
if self.isLive and hasattr(self, u'serviceItem'):
if self.is_live and hasattr(self, u'serviceItem'):
# Wait for the fade to finish before geting the preview.
# Important otherwise preview will have incorrect text if at all!
if self.serviceItem.themedata and self.serviceItem.themedata.display_slide_transition:
while self.frame.evaluateJavaScript(u'show_text_complete()') == u'false':
while not self.frame.evaluateJavaScript(u'show_text_completed()'):
self.application.process_events()
# Wait for the webview to update before getting the preview.
# Important otherwise first preview will miss the background !
while not self.webLoaded:
self.application.process_events()
# if was hidden keep it hidden
if self.isLive:
if self.hideMode:
self.hide_display(self.hideMode)
else:
if self.is_live:
if self.hide_mode:
self.hide_display(self.hide_mode)
# Only continue if the visibility wasn't changed during method call.
elif was_visible == self.isVisible():
# Single screen active
if self.screens.display_count == 1:
# Only make visible if setting enabled.
@ -373,12 +373,12 @@ class MainDisplay(Display):
self.setVisible(True)
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
HTML to the display
"""
log.debug(u'buildHtml')
log.debug(u'build_html')
self.webLoaded = False
self.initialFrame = None
self.serviceItem = serviceItem
@ -396,30 +396,29 @@ class MainDisplay(Display):
else:
# replace the background
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))
if self.serviceItem.themedata.background_filename:
self.serviceItem.bg_image_bytes = self.image_manager.get_image_bytes(
self.serviceItem.themedata.background_filename,
ImageSource.Theme
self.serviceItem.themedata.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.serviceItem, self.screen, self.isLive, background, image_bytes,
html = build_html(self.serviceItem, self.screen, self.is_live, background, image_bytes,
plugins=self.plugin_manager.plugins)
log.debug(u'buildHtml - pre setHtml')
self.webView.setHtml(html)
self.web_view.setHtml(html)
log.debug(u'buildHtml - post setHtml')
if serviceItem.foot_text:
self.footer(serviceItem.foot_text)
# if was hidden keep it hidden
if self.hideMode and self.isLive and not serviceItem.is_media():
if self.hide_mode and self.is_live and not serviceItem.is_media():
if Settings().value(u'general/auto unblank'):
Registry().execute(u'slidecontroller_live_unblank')
else:
self.hide_display(self.hideMode)
self.hide_display(self.hide_mode)
self.__hideMouse()
def footer(self, text):
@ -450,13 +449,12 @@ class MainDisplay(Display):
if mode != HideMode.Screen:
if self.isHidden():
self.setVisible(True)
self.webView.setVisible(True)
self.hideMode = mode
self.web_view.setVisible(True)
self.hide_mode = mode
def show_display(self):
"""
Show the stored layers so the screen reappears as it was
originally.
Show the stored layers so the screen reappears as it was originally.
Make the stored images None to release memory.
"""
log.debug(u'show_display')
@ -467,9 +465,9 @@ class MainDisplay(Display):
self.frame.evaluateJavaScript('show_blank("show");')
if self.isHidden():
self.setVisible(True)
self.hideMode = None
self.hide_mode = None
# Trigger actions when display is active again.
if self.isLive:
if self.is_live:
Registry().execute(u'live_display_active')
def __hideMouse(self):
@ -543,38 +541,38 @@ class AudioPlayer(QtCore.QObject):
self.currentIndex = -1
self.playlist = []
self.repeat = False
self.mediaObject = Phonon.MediaObject()
self.mediaObject.setTickInterval(100)
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self.audioObject)
QtCore.QObject.connect(self.mediaObject, QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish)
QtCore.QObject.connect(self.mediaObject, QtCore.SIGNAL(u'finished()'), self.onFinished)
self.media_object = Phonon.MediaObject()
self.media_object.setTickInterval(100)
self.audio_object = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.media_object, self.audio_object)
self.media_object.aboutToFinish.connect(self.on_about_to_finish)
self.media_object.finished.connect(self.on_finished)
def __del__(self):
"""
Shutting down so clean up connections
"""
self.stop()
for path in self.mediaObject.outputPaths():
for path in self.media_object.outputPaths():
path.disconnect()
def onAboutToFinish(self):
def on_about_to_finish(self):
"""
Just before the audio player finishes the current track, queue the next
item in the playlist, if there is one.
"""
self.currentIndex += 1
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.
"""
if self.repeat:
log.debug(u'Repeat is enabled... here we go again!')
self.mediaObject.clearQueue()
self.mediaObject.clear()
self.media_object.clearQueue()
self.media_object.clear()
self.currentIndex = -1
self.play()
@ -582,7 +580,7 @@ class AudioPlayer(QtCore.QObject):
"""
Connect the volume slider to the output channel.
"""
slider.setAudioOutput(self.audioObject)
slider.setAudioOutput(self.audio_object)
def reset(self):
"""
@ -591,7 +589,7 @@ class AudioPlayer(QtCore.QObject):
self.currentIndex = -1
self.playlist = []
self.stop()
self.mediaObject.clear()
self.media_object.clear()
def play(self):
"""
@ -599,24 +597,24 @@ class AudioPlayer(QtCore.QObject):
"""
log.debug(u'AudioPlayer.play() called')
if self.currentIndex == -1:
self.onAboutToFinish()
self.mediaObject.play()
self.on_about_to_finish()
self.media_object.play()
def pause(self):
"""
Pause the Audio
"""
log.debug(u'AudioPlayer.pause() called')
self.mediaObject.pause()
self.media_object.pause()
def stop(self):
"""
Stop the Audio and clean up
"""
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.
@ -633,31 +631,30 @@ class AudioPlayer(QtCore.QObject):
"""
if not self.repeat and self.currentIndex + 1 >= len(self.playlist):
return
isPlaying = self.mediaObject.state() == Phonon.PlayingState
isPlaying = self.media_object.state() == Phonon.PlayingState
self.currentIndex += 1
if self.repeat and self.currentIndex == len(self.playlist):
self.currentIndex = 0
self.mediaObject.clearQueue()
self.mediaObject.clear()
self.mediaObject.enqueue(self.playlist[self.currentIndex])
self.media_object.clearQueue()
self.media_object.clear()
self.media_object.enqueue(self.playlist[self.currentIndex])
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
"""
isPlaying = self.mediaObject.state() == Phonon.PlayingState
self.mediaObject.clearQueue()
self.mediaObject.clear()
isPlaying = self.media_object.state() == Phonon.PlayingState
self.media_object.clearQueue()
self.media_object.clear()
self.currentIndex = index
self.mediaObject.enqueue(self.playlist[self.currentIndex])
self.media_object.enqueue(self.playlist[self.currentIndex])
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
Connect a slot to a signal on the media object. Used by slidecontroller to connect to audio object.
"""
QtCore.QObject.connect(self.mediaObject, signal, slot)
QtCore.QObject.connect(self.media_object, signal, slot)

View File

@ -489,7 +489,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Settings().remove_obsolete_settings()
self.serviceNotSaved = False
self.aboutForm = AboutForm(self)
self.media_controller = MediaController(self)
self.media_controller = MediaController()
self.settingsForm = SettingsForm(self)
self.formattingTagForm = FormattingTagForm(self)
self.shortcutForm = ShortcutListForm(self)
@ -536,9 +536,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Registry().register_function(u'openlp_version_check', self.version_notice)
Registry().register_function(u'config_screen_changed', self.screen_changed)
self.renderer = Renderer()
# Create the displays as all necessary components are loaded.
self.preview_controller.screenSizeChanged()
self.live_controller.screenSizeChanged()
log.info(u'Load data from Settings')
if Settings().value(u'advanced/save current plugin'):
savedPlugin = Settings().value(u'advanced/current media plugin')

View File

@ -61,8 +61,8 @@ class MediaSlider(QtGui.QSlider):
"""
Override event to allow hover time to be displayed.
"""
timevalue = QtGui.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width())
self.setToolTip(u'%s' % datetime.timedelta(seconds=int(timevalue / 1000)))
time_value = QtGui.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width())
self.setToolTip(u'%s' % datetime.timedelta(seconds=int(time_value / 1000)))
QtGui.QSlider.mouseMoveEvent(self, event)
def mousePressEvent(self, event):
@ -88,21 +88,20 @@ class MediaController(object):
slidecontroller or plugin which built them. ControllerType is the class
containing the key values.
mediaPlayers are an array of media players keyed on player name.
media_players are an array of media players keyed on player name.
currentMediaPlayer is an array of player instances keyed on ControllerType.
current_media_players is an array of player instances keyed on ControllerType.
"""
def __init__(self, parent):
def __init__(self):
"""
Constructor
"""
self.mainWindow = parent
Registry().register(u'media_controller', self)
Registry().register_function(u'bootstrap_initialise', self.check_available_media_players)
self.mediaPlayers = {}
self.media_players = {}
self.displayControllers = {}
self.currentMediaPlayer = {}
self.current_media_players = {}
# Timer for video state
self.timer = QtCore.QTimer()
self.timer.setInterval(200)
@ -127,22 +126,22 @@ class MediaController(object):
Set the active players and available media files
"""
savedPlayers = get_media_players()[0]
for player in self.mediaPlayers.keys():
self.mediaPlayers[player].isActive = player in savedPlayers
for player in self.media_players.keys():
self.media_players[player].isActive = player in savedPlayers
def _generate_extensions_lists(self):
"""
Set the active players and available media files
"""
self.audio_extensions_list = []
for player in self.mediaPlayers.values():
for player in self.media_players.values():
if player.isActive:
for item in player.audio_extensions_list:
if not item in self.audio_extensions_list:
self.audio_extensions_list.append(item)
self.service_manager.supported_suffixes(item[2:])
self.video_extensions_list = []
for player in self.mediaPlayers.values():
for player in self.media_players.values():
if player.isActive:
for item in player.video_extensions_list:
if item not in self.video_extensions_list:
@ -157,16 +156,14 @@ class MediaController(object):
``player``
Individual player class which has been enabled
"""
self.mediaPlayers[player.name] = player
self.media_players[player.name] = player
def check_available_media_players(self):
"""
Check to see if we have any media Player's available.
"""
log.debug(u'_check_available_media_players')
controller_dir = os.path.join(
AppLocation.get_directory(AppLocation.AppDir),
u'core', u'ui', u'media')
controller_dir = os.path.join(AppLocation.get_directory(AppLocation.AppDir), u'core', u'ui', u'media')
for filename in os.listdir(controller_dir):
if filename.endswith(u'player.py') and not filename == 'mediaplayer.py':
path = os.path.join(controller_dir, filename)
@ -183,13 +180,13 @@ class MediaController(object):
for player_class in player_classes:
player = player_class(self)
self.register_players(player)
if not self.mediaPlayers:
if not self.media_players:
return False
savedPlayers, overriddenPlayer = get_media_players()
invalidMediaPlayers = [mediaPlayer for mediaPlayer in savedPlayers
if not mediaPlayer in self.mediaPlayers or not self.mediaPlayers[mediaPlayer].check_available()]
if invalidMediaPlayers:
for invalidPlayer in invalidMediaPlayers:
invalid_media_players = [mediaPlayer for mediaPlayer in savedPlayers
if not mediaPlayer in self.media_players or not self.media_players[mediaPlayer].check_available()]
if invalid_media_players:
for invalidPlayer in invalid_media_players:
savedPlayers.remove(invalidPlayer)
set_media_players(savedPlayers, overriddenPlayer)
self._set_active_players()
@ -201,22 +198,22 @@ class MediaController(object):
Check if there is a running media Player and do updating stuff (e.g.
update the UI)
"""
if not self.currentMediaPlayer.keys():
if not self.current_media_players.keys():
self.timer.stop()
else:
any_active = False
for source in self.currentMediaPlayer.keys():
for source in self.current_media_players.keys():
display = self._define_display(self.displayControllers[source])
self.currentMediaPlayer[source].resize(display)
self.currentMediaPlayer[source].update_ui(display)
if self.currentMediaPlayer[source].state == MediaState.Playing:
self.current_media_players[source].resize(display)
self.current_media_players[source].update_ui(display)
if self.current_media_players[source].state == MediaState.Playing:
any_active = True
# There are still any active players - no need to stop timer.
if any_active:
return
# no players are active anymore
for source in self.currentMediaPlayer.keys():
if self.currentMediaPlayer[source].state != MediaState.Paused:
for source in self.current_media_players.keys():
if self.current_media_players[source].state != MediaState.Paused:
display = self._define_display(self.displayControllers[source])
display.controller.seekSlider.setSliderPosition(0)
self.timer.stop()
@ -226,7 +223,7 @@ class MediaController(object):
Add css style sheets to htmlbuilder
"""
css = u''
for player in self.mediaPlayers.values():
for player in self.media_players.values():
if player.isActive:
css += player.get_media_display_css()
return css
@ -236,7 +233,7 @@ class MediaController(object):
Add javascript functions to htmlbuilder
"""
js = u''
for player in self.mediaPlayers.values():
for player in self.media_players.values():
if player.isActive:
js += player.get_media_display_javascript()
return js
@ -246,7 +243,7 @@ class MediaController(object):
Add html code to htmlbuilder
"""
html = u''
for player in self.mediaPlayers.values():
for player in self.media_players.values():
if player.isActive:
html += player.get_media_display_html()
return html
@ -258,7 +255,7 @@ class MediaController(object):
``controller``
The controller where a player will be placed
"""
self.displayControllers[controller.controllerType] = controller
self.displayControllers[controller.controller_type] = controller
self.setup_generic_controls(controller)
def setup_generic_controls(self, controller):
@ -273,13 +270,13 @@ class MediaController(object):
controller.mediabar = OpenLPToolbar(controller)
controller.mediabar.addToolbarAction(u'playbackPlay', text=u'media_playback_play',
icon=u':/slides/media_playback_start.png',
tooltip=translate('OpenLP.SlideController', 'Start playing media.'), triggers=controller.sendToPlugins)
tooltip=translate('OpenLP.SlideController', 'Start playing media.'), triggers=controller.send_to_plugins)
controller.mediabar.addToolbarAction(u'playbackPause', text=u'media_playback_pause',
icon=u':/slides/media_playback_pause.png',
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'), triggers=controller.sendToPlugins)
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'), triggers=controller.send_to_plugins)
controller.mediabar.addToolbarAction(u'playbackStop', text=u'media_playback_stop',
icon=u':/slides/media_playback_stop.png',
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'), triggers=controller.sendToPlugins)
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'), triggers=controller.send_to_plugins)
# Build the seekSlider.
controller.seekSlider = MediaSlider(QtCore.Qt.Horizontal, self, controller)
controller.seekSlider.setMaximum(1000)
@ -301,15 +298,15 @@ class MediaController(object):
controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
controller.volumeSlider.setObjectName(u'volumeSlider')
controller.mediabar.addToolbarWidget(controller.volumeSlider)
controller.controllerLayout.addWidget(controller.mediabar)
controller.controller_layout.addWidget(controller.mediabar)
controller.mediabar.setVisible(False)
# Signals
QtCore.QObject.connect(controller.seekSlider, QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
QtCore.QObject.connect(controller.volumeSlider, QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
controller.seekSlider.valueChanged.connect(controller.send_to_plugins)
controller.volumeSlider.valueChanged.connect(controller.send_to_plugins)
def setup_display(self, display, preview):
"""
After a new display is configured, all media related widget will be
After a new display is configured, all media related widgets will be
created too
``display``
@ -323,11 +320,11 @@ class MediaController(object):
# update player status
self._set_active_players()
display.hasAudio = True
if display.isLive and preview:
if display.is_live and preview:
return
if preview:
display.hasAudio = False
for player in self.mediaPlayers.values():
for player in self.media_players.values():
if player.isActive:
player.setup(display)
@ -344,10 +341,10 @@ class MediaController(object):
"""
# Generic controls
controller.mediabar.setVisible(value)
if controller.isLive and controller.display:
if self.currentMediaPlayer and value:
if self.currentMediaPlayer[controller.controllerType] != self.mediaPlayers[u'webkit']:
controller.display.setTransparency(False)
if controller.is_live and controller.display:
if self.current_media_players and value:
if self.current_media_players[controller.controller_type] != self.media_players[u'webkit']:
controller.display.set_transparency(False)
def resize(self, display, player):
"""
@ -388,7 +385,7 @@ class MediaController(object):
controller.media_info.is_background = videoBehindText
controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path())
display = self._define_display(controller)
if controller.isLive:
if controller.is_live:
isValid = self._check_file_type(controller, display, serviceItem)
display.override[u'theme'] = u''
display.override[u'video'] = True
@ -399,7 +396,7 @@ class MediaController(object):
else:
controller.media_info.start_time = serviceItem.start_time
controller.media_info.end_time = serviceItem.end_time
elif controller.previewDisplay:
elif controller.preview_display:
isValid = self._check_file_type(controller, display, serviceItem)
if not isValid:
# Media could not be loaded correctly
@ -407,12 +404,12 @@ class MediaController(object):
translate('MediaPlugin.MediaItem', 'Unsupported File'))
return False
# dont care about actual theme, set a black background
if controller.isLive and not controller.media_info.is_background:
if controller.is_live and not controller.media_info.is_background:
display.frame.evaluateJavaScript(u'show_video( "setBackBoard", null, null, null,"visible");')
# now start playing - Preview is autoplay!
autoplay = False
# Preview requested
if not controller.isLive:
if not controller.is_live:
autoplay = True
# Visible or background requested or Service Item wants to autostart
elif not hidden or controller.media_info.is_background or serviceItem.will_auto_start:
@ -426,7 +423,7 @@ class MediaController(object):
translate('MediaPlugin.MediaItem', 'Unsupported File'))
return False
self.set_controls_visible(controller, True)
log.debug(u'use %s controller' % self.currentMediaPlayer[controller.controllerType])
log.debug(u'use %s controller' % self.current_media_players[controller.controller_type])
return True
def media_length(self, serviceItem):
@ -443,7 +440,7 @@ class MediaController(object):
controller.media_info = MediaInfo()
controller.media_info.volume = 0
controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path())
display = controller.previewDisplay
display = controller._display
if not self._check_file_type(controller, display, serviceItem):
# Media could not be loaded correctly
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
@ -455,7 +452,7 @@ class MediaController(object):
return False
serviceItem.set_media_length(controller.media_info.length)
self.media_stop(controller)
log.debug(u'use %s controller' % self.currentMediaPlayer[controller.controllerType])
log.debug(u'use %s controller' % self.current_media_players[controller.controller_type])
return True
def _check_file_type(self, controller, display, serviceItem):
@ -474,27 +471,27 @@ class MediaController(object):
if controller.media_info.file_info.isFile():
suffix = u'*.%s' % controller.media_info.file_info.suffix().lower()
for title in usedPlayers:
player = self.mediaPlayers[title]
player = self.media_players[title]
if suffix in player.video_extensions_list:
if not controller.media_info.is_background or controller.media_info.is_background and \
player.canBackground:
self.resize(display, player)
if player.load(display):
self.currentMediaPlayer[controller.controllerType] = player
self.current_media_players[controller.controller_type] = player
controller.media_info.media_type = MediaType.Video
return True
if suffix in player.audio_extensions_list:
if player.load(display):
self.currentMediaPlayer[controller.controllerType] = player
self.current_media_players[controller.controller_type] = player
controller.media_info.media_type = MediaType.Audio
return True
else:
for title in usedPlayers:
player = self.mediaPlayers[title]
player = self.media_players[title]
if player.canFolder:
self.resize(display, player)
if player.load(display):
self.currentMediaPlayer[controller.controllerType] = player
self.current_media_players[controller.controller_type] = player
controller.media_info.media_type = MediaType.Video
return True
# no valid player found
@ -521,7 +518,7 @@ class MediaController(object):
controller.seekSlider.blockSignals(True)
controller.volumeSlider.blockSignals(True)
display = self._define_display(controller)
if not self.currentMediaPlayer[controller.controllerType].play(display):
if not self.current_media_players[controller.controller_type].play(display):
controller.seekSlider.blockSignals(False)
controller.volumeSlider.blockSignals(False)
return False
@ -531,7 +528,7 @@ class MediaController(object):
self.media_volume(controller, controller.media_info.volume)
if status:
display.frame.evaluateJavaScript(u'show_blank("desktop");')
self.currentMediaPlayer[controller.controllerType].set_visible(display, True)
self.current_media_players[controller.controller_type].set_visible(display, True)
# Flash needs to be played and will not AutoPlay
if controller.media_info.is_flash:
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
@ -540,9 +537,9 @@ class MediaController(object):
controller.mediabar.actions[u'playbackPlay'].setVisible(False)
controller.mediabar.actions[u'playbackPause'].setVisible(True)
controller.mediabar.actions[u'playbackStop'].setVisible(True)
if controller.isLive:
if controller.hideMenu.defaultAction().isChecked():
controller.hideMenu.defaultAction().trigger()
if controller.is_live:
if controller.hide_menu.defaultAction().isChecked():
controller.hide_menu.defaultAction().trigger()
# Start Timer for ui updates
if not self.timer.isActive():
self.timer.start()
@ -569,7 +566,7 @@ class MediaController(object):
"""
log.debug(u'media_pause')
display = self._define_display(controller)
self.currentMediaPlayer[controller.controllerType].pause(display)
self.current_media_players[controller.controller_type].pause(display)
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
controller.mediabar.actions[u'playbackStop'].setVisible(True)
controller.mediabar.actions[u'playbackPause'].setVisible(False)
@ -593,10 +590,10 @@ class MediaController(object):
"""
log.debug(u'media_stop')
display = self._define_display(controller)
if controller.controllerType in self.currentMediaPlayer:
if controller.controller_type in self.current_media_players:
display.frame.evaluateJavaScript(u'show_blank("black");')
self.currentMediaPlayer[controller.controllerType].stop(display)
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
self.current_media_players[controller.controller_type].stop(display)
self.current_media_players[controller.controller_type].set_visible(display, False)
controller.seekSlider.setSliderPosition(0)
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
controller.mediabar.actions[u'playbackStop'].setVisible(False)
@ -622,7 +619,7 @@ class MediaController(object):
"""
log.debug(u'media_volume %d' % volume)
display = self._define_display(controller)
self.currentMediaPlayer[controller.controllerType].volume(display, volume)
self.current_media_players[controller.controller_type].volume(display, volume)
controller.volumeSlider.setValue(volume)
def media_seek_msg(self, msg):
@ -648,7 +645,7 @@ class MediaController(object):
"""
log.debug(u'media_seek')
display = self._define_display(controller)
self.currentMediaPlayer[controller.controllerType].seek(display, seekVal)
self.current_media_players[controller.controller_type].seek(display, seekVal)
def media_reset(self, controller):
"""
@ -657,12 +654,12 @@ class MediaController(object):
log.debug(u'media_reset')
self.set_controls_visible(controller, False)
display = self._define_display(controller)
if controller.controllerType in self.currentMediaPlayer:
if controller.controller_type in self.current_media_players:
display.override = {}
self.currentMediaPlayer[controller.controllerType].reset(display)
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
self.current_media_players[controller.controller_type].reset(display)
self.current_media_players[controller.controller_type].set_visible(display, False)
display.frame.evaluateJavaScript(u'show_video( "setBackBoard", null, null, null,"hidden");')
del self.currentMediaPlayer[controller.controllerType]
del self.current_media_players[controller.controller_type]
def media_hide(self, msg):
"""
@ -671,15 +668,14 @@ class MediaController(object):
``msg``
First element is the boolean for Live indication
"""
isLive = msg[1]
if not isLive:
is_live = msg[1]
if not is_live:
return
controller = self.mainWindow.liveController
display = self._define_display(controller)
if controller.controllerType in self.currentMediaPlayer and \
self.currentMediaPlayer[controller.controllerType].state == MediaState.Playing:
self.currentMediaPlayer[controller.controllerType].pause(display)
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
display = self._define_display(self.live_controller)
if self.live_controller.controller_type in self.current_media_players and \
self.current_media_players[self.live_controller.controller_type].state == MediaState.Playing:
self.current_media_players[self.live_controller.controller_type].pause(display)
self.current_media_players[self.live_controller.controller_type].set_visible(display, False)
def media_blank(self, msg):
"""
@ -689,16 +685,15 @@ class MediaController(object):
First element is the boolean for Live indication
Second element is the hide mode
"""
isLive = msg[1]
is_live = msg[1]
hide_mode = msg[2]
if not isLive:
if not is_live:
return
Registry().execute(u'live_display_hide', hide_mode)
controller = self.mainWindow.liveController
display = self._define_display(controller)
if self.currentMediaPlayer[controller.controllerType].state == MediaState.Playing:
self.currentMediaPlayer[controller.controllerType].pause(display)
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
display = self._define_display(self.live_controller)
if self.current_media_players[self.live_controller.controller_type].state == MediaState.Playing:
self.current_media_players[self.live_controller.controller_type].pause(display)
self.current_media_players[self.live_controller.controller_type].set_visible(display, False)
def media_unblank(self, msg):
"""
@ -709,15 +704,14 @@ class MediaController(object):
Second element is the boolean for Live indication
"""
Registry().execute(u'live_display_show')
isLive = msg[1]
if not isLive:
is_live = msg[1]
if not is_live:
return
controller = self.mainWindow.liveController
display = self._define_display(controller)
if controller.controllerType in self.currentMediaPlayer and \
self.currentMediaPlayer[controller.controllerType].state != MediaState.Playing:
if self.currentMediaPlayer[controller.controllerType].play(display):
self.currentMediaPlayer[controller.controllerType].set_visible(display, True)
display = self._define_display(self.live_controller)
if self.live_controller.controller_type in self.current_media_players and \
self.current_media_players[self.live_controller.controller_type].state != MediaState.Playing:
if self.current_media_players[self.live_controller.controller_type].play(display):
self.current_media_players[self.live_controller.controller_type].set_visible(display, True)
# Start Timer for ui updates
if not self.timer.isActive():
self.timer.start()
@ -737,9 +731,9 @@ class MediaController(object):
``controller``
Controller to be used
"""
if controller.isLive:
if controller.is_live:
return controller.display
return controller.previewDisplay
return controller.preview_display
def _get_service_manager(self):
"""
@ -750,3 +744,13 @@ class MediaController(object):
return self._service_manager
service_manager = property(_get_service_manager)
def _get_live_controller(self):
"""
Adds the live controller to the class dynamically
"""
if not hasattr(self, u'_live_controller'):
self._live_controller = Registry().get(u'live_controller')
return self._live_controller
live_controller = property(_get_live_controller)

View File

@ -55,7 +55,7 @@ class PlayerTab(SettingsTab):
"""
Constructor
"""
self.mediaPlayers = self.media_controller.mediaPlayers
self.media_players = self.media_controller.media_players
self.savedUsedPlayers = None
self.iconPath = u':/media/multimedia-player.png'
player_translated = translate('OpenLP.PlayerTab', 'Players')
@ -171,7 +171,7 @@ class PlayerTab(SettingsTab):
self.playerCheckBoxes[u'%s' % player].setEnabled(False)
else:
self.playerCheckBoxes[u'%s' % player].setEnabled(True)
self.playerOrderlistWidget.addItem(self.mediaPlayers[unicode(player)].original_name)
self.playerOrderlistWidget.addItem(self.media_players[unicode(player)].original_name)
def onUpButtonClicked(self):
"""
@ -237,8 +237,8 @@ class PlayerTab(SettingsTab):
Late setup for players as the MediaController has to be initialised
first.
"""
for key, player in self.mediaPlayers.iteritems():
player = self.mediaPlayers[key]
for key, player in self.media_players.iteritems():
player = self.media_players[key]
checkbox = MediaQCheckBox(self.mediaPlayerGroupBox)
checkbox.setEnabled(player.available)
checkbox.setObjectName(player.name + u'CheckBox')
@ -258,8 +258,8 @@ class PlayerTab(SettingsTab):
"""
Translations for players is dependent on their setup as well
"""
for key in self.mediaPlayers:
player = self.mediaPlayers[key]
for key in self.media_players:
player = self.media_players[key]
checkbox = self.playerCheckBoxes[player.name]
checkbox.setPlayerName(player.name)
if player.available:

View File

@ -122,7 +122,7 @@ class VlcPlayer(MediaPlayer):
command_line_options = u'--no-video-title-show'
if not display.hasAudio:
command_line_options += u' --no-audio --no-video-title-show'
if Settings().value(u'advanced/hide mouse') and display.controller.isLive:
if Settings().value(u'advanced/hide mouse') and display.controller.is_live:
command_line_options += u' --mouse-hide-timeout=0'
display.vlcInstance = vlc.Instance(command_line_options)
# creating an empty vlc media player

View File

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

View File

@ -1413,7 +1413,7 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog):
critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager',
'Your item cannot be displayed as the plugin required to display it is missing or inactive'))
self.application.set_normal_cursor()
self.application.set_normal_cursor()
def remote_edit(self):
"""

File diff suppressed because it is too large Load Diff

View File

@ -253,8 +253,8 @@ class ThemeManager(QtGui.QWidget):
self.cloneThemeData(old_theme_data, new_theme_name)
self.delete_theme(old_theme_name)
for plugin in self.plugin_manager.plugins:
if plugin.usesTheme(old_theme_name):
plugin.renameTheme(old_theme_name, new_theme_name)
if plugin.uses_theme(old_theme_name):
plugin.rename_theme(old_theme_name, new_theme_name)
self.renderer.update_theme(new_theme_name, old_theme_name)
self.load_themes()
@ -280,8 +280,7 @@ class ThemeManager(QtGui.QWidget):
save_to = None
save_from = None
if theme_data.background_type == u'image':
save_to = os.path.join(self.path, new_theme_name,
os.path.split(unicode(theme_data.background_filename))[1])
save_to = os.path.join(self.path, new_theme_name, os.path.split(unicode(theme_data.background_filename))[1])
save_from = theme_data.background_filename
theme_data.theme_name = new_theme_name
theme_data.extend_image_filename(self.path)
@ -407,7 +406,7 @@ class ThemeManager(QtGui.QWidget):
theme_file = os.path.join(self.path, theme_file)
self.unzip_theme(theme_file, self.path)
delete_file(theme_file)
files = AppLocation.get_files(self.settingsSection, u'.otz')
files = AppLocation.get_files(self.settingsSection, u'.png')
# No themes have been found so create one
if not files:
theme = ThemeXML()
@ -748,7 +747,7 @@ class ThemeManager(QtGui.QWidget):
# check for use in the system else where.
if testPlugin:
for plugin in self.plugin_manager.plugins:
if plugin.usesTheme(theme):
if plugin.uses_theme(theme):
critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', 'Theme %s is used in the %s plugin.') %
(theme, plugin.name))

View File

@ -185,7 +185,7 @@ class AlertsPlugin(Plugin):
'<br />The alert plugin controls the displaying of nursery alerts on the display screen.')
return about_text
def setPluginTextStrings(self):
def set_plugin_text_strings(self):
"""
Called to define all translatable texts of the plugin
"""

View File

@ -164,7 +164,7 @@ class BiblePlugin(Plugin):
'verses from different sources during the service.')
return about_text
def usesTheme(self, theme):
def uses_theme(self, theme):
"""
Called to find out if the bible plugin is currently using a theme.
Returns ``True`` if the theme is being used, otherwise returns
@ -172,7 +172,7 @@ class BiblePlugin(Plugin):
"""
return unicode(self.settingsTab.bible_theme) == theme
def renameTheme(self, oldTheme, newTheme):
def rename_theme(self, oldTheme, newTheme):
"""
Rename the theme the bible plugin is using making the plugin use the
new name.
@ -187,7 +187,7 @@ class BiblePlugin(Plugin):
self.settingsTab.bible_theme = newTheme
self.settingsTab.save()
def setPluginTextStrings(self):
def set_plugin_text_strings(self):
"""
Called to define all translatable texts of the plugin
"""

View File

@ -73,7 +73,7 @@ class CustomPlugin(Plugin):
'the same way songs are. This plugin provides greater freedom over the songs plugin.')
return about_text
def usesTheme(self, theme):
def uses_theme(self, theme):
"""
Called to find out if the custom plugin is currently using a theme.
@ -83,7 +83,7 @@ class CustomPlugin(Plugin):
return True
return False
def renameTheme(self, oldTheme, newTheme):
def rename_theme(self, oldTheme, newTheme):
"""
Renames a theme the custom plugin is using making the plugin use the
new name.
@ -94,12 +94,12 @@ class CustomPlugin(Plugin):
``newTheme``
The new name the plugin should now use.
"""
customsUsingTheme = self.manager.get_all_objects(CustomSlide, CustomSlide.theme_name == oldTheme)
for custom in customsUsingTheme:
customs_using_theme = self.manager.get_all_objects(CustomSlide, CustomSlide.theme_name == oldTheme)
for custom in customs_using_theme:
custom.theme_name = newTheme
self.manager.save_object(custom)
def setPluginTextStrings(self):
def set_plugin_text_strings(self):
"""
Called to define all translatable texts of the plugin
"""

View File

@ -32,84 +32,86 @@ from PyQt4 import QtGui
from openlp.core.lib import UiStrings, build_icon, translate
from openlp.core.lib.ui import create_button_box, create_button
class Ui_CustomEditDialog(object):
def setupUi(self, customEditDialog):
customEditDialog.setObjectName(u'customEditDialog')
customEditDialog.resize(450, 350)
customEditDialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
self.dialogLayout = QtGui.QVBoxLayout(customEditDialog)
self.dialogLayout.setObjectName(u'dialog_layout')
self.titleLayout = QtGui.QHBoxLayout()
self.titleLayout.setObjectName(u'titleLayout')
self.titleLabel = QtGui.QLabel(customEditDialog)
self.titleLabel.setObjectName(u'titleLabel')
self.titleLayout.addWidget(self.titleLabel)
self.titleEdit = QtGui.QLineEdit(customEditDialog)
self.titleLabel.setBuddy(self.titleEdit)
self.titleEdit.setObjectName(u'titleEdit')
self.titleLayout.addWidget(self.titleEdit)
self.dialogLayout.addLayout(self.titleLayout)
self.centralLayout = QtGui.QHBoxLayout()
self.centralLayout.setObjectName(u'centralLayout')
self.slideListView = QtGui.QListWidget(customEditDialog)
self.slideListView.setAlternatingRowColors(True)
self.slideListView.setObjectName(u'slideListView')
self.centralLayout.addWidget(self.slideListView)
self.buttonLayout = QtGui.QVBoxLayout()
self.buttonLayout.setObjectName(u'buttonLayout')
self.addButton = QtGui.QPushButton(customEditDialog)
self.addButton.setObjectName(u'addButton')
self.buttonLayout.addWidget(self.addButton)
self.editButton = QtGui.QPushButton(customEditDialog)
self.editButton.setEnabled(False)
self.editButton.setObjectName(u'editButton')
self.buttonLayout.addWidget(self.editButton)
self.editAllButton = QtGui.QPushButton(customEditDialog)
self.editAllButton.setObjectName(u'editAllButton')
self.buttonLayout.addWidget(self.editAllButton)
self.deleteButton = create_button(customEditDialog, u'deleteButton', role=u'delete',
click=customEditDialog.onDeleteButtonClicked)
self.deleteButton.setEnabled(False)
self.buttonLayout.addWidget(self.deleteButton)
self.buttonLayout.addStretch()
self.upButton = create_button(customEditDialog, u'upButton', role=u'up', enabled=False,
click=customEditDialog.onUpButtonClicked)
self.downButton = create_button(customEditDialog, u'downButton', role=u'down', enabled=False,
click=customEditDialog.onDownButtonClicked)
self.buttonLayout.addWidget(self.upButton)
self.buttonLayout.addWidget(self.downButton)
self.centralLayout.addLayout(self.buttonLayout)
self.dialogLayout.addLayout(self.centralLayout)
self.bottomFormLayout = QtGui.QFormLayout()
self.bottomFormLayout.setObjectName(u'bottomFormLayout')
self.themeLabel = QtGui.QLabel(customEditDialog)
self.themeLabel.setObjectName(u'themeLabel')
self.themeComboBox = QtGui.QComboBox(customEditDialog)
self.themeComboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
self.themeComboBox.setObjectName(u'themeComboBox')
self.themeLabel.setBuddy(self.themeComboBox)
self.bottomFormLayout.addRow(self.themeLabel, self.themeComboBox)
self.creditLabel = QtGui.QLabel(customEditDialog)
self.creditLabel.setObjectName(u'creditLabel')
self.creditEdit = QtGui.QLineEdit(customEditDialog)
self.creditEdit.setObjectName(u'creditEdit')
self.creditLabel.setBuddy(self.creditEdit)
self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit)
self.dialogLayout.addLayout(self.bottomFormLayout)
self.previewButton = QtGui.QPushButton()
self.button_box = create_button_box(customEditDialog, u'button_box', [u'cancel', u'save'], [self.previewButton])
self.dialogLayout.addWidget(self.button_box)
self.retranslateUi(customEditDialog)
def retranslateUi(self, customEditDialog):
customEditDialog.setWindowTitle(translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
self.titleLabel.setText(translate('CustomPlugin.EditCustomForm', '&Title:'))
self.addButton.setText(UiStrings().Add)
self.addButton.setToolTip(translate('CustomPlugin.EditCustomForm', 'Add a new slide at bottom.'))
self.editButton.setText(UiStrings().Edit)
self.editButton.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit the selected slide.'))
self.editAllButton.setText(translate('CustomPlugin.EditCustomForm', 'Ed&it All'))
self.editAllButton.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit all the slides at once.'))
self.themeLabel.setText(translate('CustomPlugin.EditCustomForm', 'The&me:'))
self.creditLabel.setText(translate('CustomPlugin.EditCustomForm', '&Credits:'))
self.previewButton.setText(UiStrings().SaveAndPreview)
class Ui_CustomEditDialog(object):
def setupUi(self, custom_edit_dialog):
custom_edit_dialog.setObjectName(u'custom_edit_dialog')
custom_edit_dialog.resize(450, 350)
custom_edit_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
self.dialog_layout = QtGui.QVBoxLayout(custom_edit_dialog)
self.dialog_layout.setObjectName(u'dialog_layout')
self.title_layout = QtGui.QHBoxLayout()
self.title_layout.setObjectName(u'title_layout')
self.title_label = QtGui.QLabel(custom_edit_dialog)
self.title_label.setObjectName(u'title_label')
self.title_layout.addWidget(self.title_label)
self.title_edit = QtGui.QLineEdit(custom_edit_dialog)
self.title_label.setBuddy(self.title_edit)
self.title_edit.setObjectName(u'title_edit')
self.title_layout.addWidget(self.title_edit)
self.dialog_layout.addLayout(self.title_layout)
self.central_layout = QtGui.QHBoxLayout()
self.central_layout.setObjectName(u'central_layout')
self.slide_list_view = QtGui.QListWidget(custom_edit_dialog)
self.slide_list_view.setAlternatingRowColors(True)
self.slide_list_view.setObjectName(u'slide_list_view')
self.central_layout.addWidget(self.slide_list_view)
self.button_layout = QtGui.QVBoxLayout()
self.button_layout.setObjectName(u'button_layout')
self.add_button = QtGui.QPushButton(custom_edit_dialog)
self.add_button.setObjectName(u'add_button')
self.button_layout.addWidget(self.add_button)
self.edit_button = QtGui.QPushButton(custom_edit_dialog)
self.edit_button.setEnabled(False)
self.edit_button.setObjectName(u'edit_button')
self.button_layout.addWidget(self.edit_button)
self.edit_all_button = QtGui.QPushButton(custom_edit_dialog)
self.edit_all_button.setObjectName(u'edit_all_button')
self.button_layout.addWidget(self.edit_all_button)
self.delete_button = create_button(custom_edit_dialog, u'delete_button', role=u'delete',
click=custom_edit_dialog.on_delete_button_clicked)
self.delete_button.setEnabled(False)
self.button_layout.addWidget(self.delete_button)
self.button_layout.addStretch()
self.up_button = create_button(custom_edit_dialog, u'up_button', role=u'up', enabled=False,
click=custom_edit_dialog.on_up_button_clicked)
self.down_button = create_button(custom_edit_dialog, u'down_button', role=u'down', enabled=False,
click=custom_edit_dialog.on_down_button_clicked)
self.button_layout.addWidget(self.up_button)
self.button_layout.addWidget(self.down_button)
self.central_layout.addLayout(self.button_layout)
self.dialog_layout.addLayout(self.central_layout)
self.bottom_form_layout = QtGui.QFormLayout()
self.bottom_form_layout.setObjectName(u'bottom_form_layout')
self.theme_label = QtGui.QLabel(custom_edit_dialog)
self.theme_label.setObjectName(u'theme_label')
self.theme_combo_box = QtGui.QComboBox(custom_edit_dialog)
self.theme_combo_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
self.theme_combo_box.setObjectName(u'theme_combo_box')
self.theme_label.setBuddy(self.theme_combo_box)
self.bottom_form_layout.addRow(self.theme_label, self.theme_combo_box)
self.credit_label = QtGui.QLabel(custom_edit_dialog)
self.credit_label.setObjectName(u'credit_label')
self.credit_edit = QtGui.QLineEdit(custom_edit_dialog)
self.credit_edit.setObjectName(u'credit_edit')
self.credit_label.setBuddy(self.credit_edit)
self.bottom_form_layout.addRow(self.credit_label, self.credit_edit)
self.dialog_layout.addLayout(self.bottom_form_layout)
self.preview_button = QtGui.QPushButton()
self.button_box = create_button_box(custom_edit_dialog, u'button_box', [u'cancel', u'save'],
[self.preview_button])
self.dialog_layout.addWidget(self.button_box)
self.retranslateUi(custom_edit_dialog)
def retranslateUi(self, custom_edit_dialog):
custom_edit_dialog.setWindowTitle(translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
self.title_label.setText(translate('CustomPlugin.EditCustomForm', '&Title:'))
self.add_button.setText(UiStrings().Add)
self.add_button.setToolTip(translate('CustomPlugin.EditCustomForm', 'Add a new slide at bottom.'))
self.edit_button.setText(UiStrings().Edit)
self.edit_button.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit the selected slide.'))
self.edit_all_button.setText(translate('CustomPlugin.EditCustomForm', 'Ed&it All'))
self.edit_all_button.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit all the slides at once.'))
self.theme_label.setText(translate('CustomPlugin.EditCustomForm', 'The&me:'))
self.credit_label.setText(translate('CustomPlugin.EditCustomForm', '&Credits:'))
self.preview_button.setText(UiStrings().SaveAndPreview)

View File

@ -29,7 +29,7 @@
import logging
from PyQt4 import QtCore, QtGui
from PyQt4 import QtGui
from openlp.core.lib import Registry, translate
from openlp.core.lib.ui import critical_error_message_box, find_and_set_in_combo_box
@ -56,14 +56,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.mediaitem = mediaitem
self.setupUi(self)
# Create other objects and forms.
self.editSlideForm = EditCustomSlideForm(self)
self.edit_slide_form = EditCustomSlideForm(self)
# Connecting signals and slots
self.previewButton.clicked.connect(self.on_preview_button_clicked)
self.addButton.clicked.connect(self.on_add_button_clicked)
self.editButton.clicked.connect(self.on_edit_button_clicked)
self.editAllButton.clicked.connect(self.on_edit_all_button_clicked)
self.slideListView.currentRowChanged.connect(self.on_current_row_changed)
self.slideListView.doubleClicked.connect(self.on_edit_button_clicked)
self.preview_button.clicked.connect(self.on_preview_button_clicked)
self.add_button.clicked.connect(self.on_add_button_clicked)
self.edit_button.clicked.connect(self.on_edit_button_clicked)
self.edit_all_button.clicked.connect(self.on_edit_all_button_clicked)
self.slide_list_view.currentRowChanged.connect(self.on_current_row_changed)
self.slide_list_view.doubleClicked.connect(self.on_edit_button_clicked)
Registry().register_function(u'theme_update_list', self.load_themes)
def load_themes(self, theme_list):
@ -73,11 +73,11 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
``theme_list``
The list of themes to load.
"""
self.themeComboBox.clear()
self.themeComboBox.addItem(u'')
self.themeComboBox.addItems(theme_list)
self.theme_combo_box.clear()
self.theme_combo_box.addItem(u'')
self.theme_combo_box.addItems(theme_list)
def loadCustom(self, id, preview=False):
def load_custom(self, id, preview=False):
"""
Called when editing or creating a new custom.
@ -88,111 +88,111 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
States whether the custom is edited while being previewed in the
preview panel.
"""
self.slideListView.clear()
self.slide_list_view.clear()
if id == 0:
self.customSlide = CustomSlide()
self.titleEdit.setText(u'')
self.creditEdit.setText(u'')
self.themeComboBox.setCurrentIndex(0)
self.custom_slide = CustomSlide()
self.title_edit.set_text(u'')
self.credit_edit.set_text(u'')
self.theme_combo_box.setCurrentIndex(0)
else:
self.customSlide = self.manager.get_object(CustomSlide, id)
self.titleEdit.setText(self.customSlide.title)
self.creditEdit.setText(self.customSlide.credits)
customXML = CustomXMLParser(self.customSlide.text)
slideList = customXML.get_verses()
for slide in slideList:
self.slideListView.addItem(slide[1])
theme = self.customSlide.theme_name
find_and_set_in_combo_box(self.themeComboBox, theme)
self.titleEdit.setFocus()
self.custom_slide = self.manager.get_object(CustomSlide, id)
self.title_edit.setText(self.custom_slide.title)
self.credit_edit.setText(self.custom_slide.credits)
custom_XML = CustomXMLParser(self.custom_slide.text)
slide_list = custom_XML.get_verses()
for slide in slide_list:
self.slide_list_view.addItem(slide[1])
theme = self.custom_slide.theme_name
find_and_set_in_combo_box(self.theme_combo_box, theme)
self.title_edit.setFocus()
# If not preview hide the preview button.
self.previewButton.setVisible(preview)
self.preview_button.setVisible(preview)
def accept(self):
"""
Override the QDialog method to check if the custom slide has been saved before closing the dialog.
"""
log.debug(u'accept')
if self.saveCustom():
if self.save_custom():
QtGui.QDialog.accept(self)
def saveCustom(self):
def save_custom(self):
"""
Saves the custom.
"""
if not self._validate():
return False
sxml = CustomXMLBuilder()
for count in range(self.slideListView.count()):
sxml.add_verse_to_lyrics(u'custom', unicode(count + 1), self.slideListView.item(count).text())
self.customSlide.title = self.titleEdit.text()
self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8')
self.customSlide.credits = self.creditEdit.text()
self.customSlide.theme_name = self.themeComboBox.currentText()
success = self.manager.save_object(self.customSlide)
self.mediaitem.autoSelectId = self.customSlide.id
for count in range(self.slide_list_view.count()):
sxml.add_verse_to_lyrics(u'custom', unicode(count + 1), self.slide_list_view.item(count).text())
self.custom_slide.title = self.title_edit.text()
self.custom_slide.text = unicode(sxml.extract_xml(), u'utf-8')
self.custom_slide.credits = self.credit_edit.text()
self.custom_slide.theme_name = self.theme_combo_box.currentText()
success = self.manager.save_object(self.custom_slide)
self.mediaitem.autoSelectId = self.custom_slide.id
return success
def onUpButtonClicked(self):
def on_up_button_clicked(self):
"""
Move a slide up in the list when the "Up" button is clicked.
"""
selectedRow = self.slideListView.currentRow()
selectedRow = self.slide_list_view.currentRow()
if selectedRow != 0:
qw = self.slideListView.takeItem(selectedRow)
self.slideListView.insertItem(selectedRow - 1, qw)
self.slideListView.setCurrentRow(selectedRow - 1)
qw = self.slide_list_view.takeItem(selectedRow)
self.slide_list_view.insertItem(selectedRow - 1, qw)
self.slide_list_view.setCurrentRow(selectedRow - 1)
def onDownButtonClicked(self):
def on_down_button_clicked(self):
"""
Move a slide down in the list when the "Down" button is clicked.
"""
selectedRow = self.slideListView.currentRow()
selectedRow = self.slide_list_view.currentRow()
# zero base arrays
if selectedRow != self.slideListView.count() - 1:
qw = self.slideListView.takeItem(selectedRow)
self.slideListView.insertItem(selectedRow + 1, qw)
self.slideListView.setCurrentRow(selectedRow + 1)
if selectedRow != self.slide_list_view.count() - 1:
qw = self.slide_list_view.takeItem(selectedRow)
self.slide_list_view.insertItem(selectedRow + 1, qw)
self.slide_list_view.setCurrentRow(selectedRow + 1)
def on_add_button_clicked(self):
"""
Add a new blank slide.
"""
self.editSlideForm.setText(u'')
if self.editSlideForm.exec_():
self.slideListView.addItems(self.editSlideForm.getText())
self.edit_slide_form.set_text(u'')
if self.edit_slide_form.exec_():
self.slide_list_view.addItems(self.edit_slide_form.get_text())
def on_edit_button_clicked(self):
"""
Edit the currently selected slide.
"""
self.editSlideForm.setText(self.slideListView.currentItem().text())
if self.editSlideForm.exec_():
self.updateSlideList(self.editSlideForm.getText())
self.edit_slide_form.set_text(self.slide_list_view.currentItem().text())
if self.edit_slide_form.exec_():
self.update_slide_list(self.edit_slide_form.get_text())
def on_edit_all_button_clicked(self):
"""
Edits all slides.
"""
slide_text = u''
for row in range(self.slideListView.count()):
item = self.slideListView.item(row)
for row in range(self.slide_list_view.count()):
item = self.slide_list_view.item(row)
slide_text += item.text()
if row != self.slideListView.count() - 1:
if row != self.slide_list_view.count() - 1:
slide_text += u'\n[===]\n'
self.editSlideForm.setText(slide_text)
if self.editSlideForm.exec_():
self.updateSlideList(self.editSlideForm.getText(), True)
self.edit_slide_form.set_text(slide_text)
if self.edit_slide_form.exec_():
self.update_slide_list(self.edit_slide_form.get_text(), True)
def on_preview_button_clicked(self):
"""
Save the custom item and preview it.
"""
log.debug(u'onPreview')
if self.saveCustom():
if self.save_custom():
Registry().execute(u'custom_preview')
def updateSlideList(self, slides, edit_all=False):
def update_slide_list(self, slides, edit_all=False):
"""
Updates the slide list after editing slides.
@ -203,60 +203,59 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
Indicates if all slides or only one slide has been edited.
"""
if edit_all:
self.slideListView.clear()
self.slideListView.addItems(slides)
self.slide_list_view.clear()
self.slide_list_view.addItems(slides)
else:
old_slides = []
old_row = self.slideListView.currentRow()
old_row = self.slide_list_view.currentRow()
# Create a list with all (old/unedited) slides.
old_slides = [self.slideListView.item(row).text() for row in
range(self.slideListView.count())]
self.slideListView.clear()
old_slides = [self.slide_list_view.item(row).text() for row in range(self.slide_list_view.count())]
self.slide_list_view.clear()
old_slides.pop(old_row)
# Insert all slides to make the old_slides list complete.
for slide in slides:
old_slides.insert(old_row, slide)
self.slideListView.addItems(old_slides)
self.slideListView.repaint()
self.slide_list_view.addItems(old_slides)
self.slide_list_view.repaint()
def onDeleteButtonClicked(self):
def on_delete_button_clicked(self):
"""
Removes the current row from the list.
"""
self.slideListView.takeItem(self.slideListView.currentRow())
self.on_current_row_changed(self.slideListView.currentRow())
self.slide_list_view.takeItem(self.slide_list_view.currentRow())
self.on_current_row_changed(self.slide_list_view.currentRow())
def on_current_row_changed(self, row):
"""
Called when the *slideListView*'s current row has been changed. This
Called when the *slide_list_view*'s current row has been changed. This
enables or disables buttons which require an slide to act on.
``row``
The row (int). If there is no current row, the value is -1.
"""
if row == -1:
self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False)
self.upButton.setEnabled(False)
self.downButton.setEnabled(False)
self.delete_button.setEnabled(False)
self.edit_button.setEnabled(False)
self.up_button.setEnabled(False)
self.down_button.setEnabled(False)
else:
self.deleteButton.setEnabled(True)
self.editButton.setEnabled(True)
self.delete_button.setEnabled(True)
self.edit_button.setEnabled(True)
# Decide if the up/down buttons should be enabled or not.
self.downButton.setEnabled(self.slideListView.count() - 1 != row)
self.upButton.setEnabled(row != 0)
self.down_button.setEnabled(self.slide_list_view.count() - 1 != row)
self.up_button.setEnabled(row != 0)
def _validate(self):
"""
Checks whether a custom is valid or not.
"""
# We must have a title.
if not self.titleEdit.displayText():
self.titleEdit.setFocus()
if not self.title_edit.displayText():
self.title_edit.setFocus()
critical_error_message_box(message=translate('CustomPlugin.EditCustomForm', 'You need to type in a title.'))
return False
# We must have at least one slide.
if self.slideListView.count() == 0:
if self.slide_list_view.count() == 0:
critical_error_message_box(message=translate('CustomPlugin.EditCustomForm',
'You need to add at least one slide'))
return False

View File

@ -33,24 +33,25 @@ from openlp.core.lib import SpellTextEdit, UiStrings, translate
from openlp.core.lib.ui import create_button, create_button_box
class Ui_CustomSlideEditDialog(object):
def setupUi(self, customSlideEditDialog):
customSlideEditDialog.setObjectName(u'customSlideEditDialog')
customSlideEditDialog.resize(350, 300)
self.dialogLayout = QtGui.QVBoxLayout(customSlideEditDialog)
self.slideTextEdit = SpellTextEdit(self)
self.slideTextEdit.setObjectName(u'slideTextEdit')
self.dialogLayout.addWidget(self.slideTextEdit)
self.splitButton = create_button(customSlideEditDialog, u'splitButton', icon=u':/general/general_add.png')
self.insertButton = create_button(customSlideEditDialog, u'insertButton', icon=u':/general/general_add.png')
self.button_box = create_button_box(customSlideEditDialog, u'button_box', [u'cancel', u'save'],
[self.splitButton, self.insertButton])
self.dialogLayout.addWidget(self.button_box)
self.retranslateUi(customSlideEditDialog)
def setupUi(self, custom_slide_edit_dialog):
custom_slide_edit_dialog.setObjectName(u'custom_slide_edit_dialog')
custom_slide_edit_dialog.resize(350, 300)
self.dialog_layout = QtGui.QVBoxLayout(custom_slide_edit_dialog)
self.slide_text_edit = SpellTextEdit(self)
self.slide_text_edit.setObjectName(u'slide_text_edit')
self.dialog_layout.addWidget(self.slide_text_edit)
self.split_button = create_button(custom_slide_edit_dialog, u'splitButton', icon=u':/general/general_add.png')
self.insert_button = create_button(custom_slide_edit_dialog, u'insertButton',
icon=u':/general/general_add.png')
self.button_box = create_button_box(custom_slide_edit_dialog, u'button_box', [u'cancel', u'save'],
[self.split_button, self.insert_button])
self.dialog_layout.addWidget(self.button_box)
self.retranslateUi(custom_slide_edit_dialog)
def retranslateUi(self, customSlideEditDialog):
customSlideEditDialog.setWindowTitle(translate('CustomPlugin.EditVerseForm', 'Edit Slide'))
self.splitButton.setText(UiStrings().Split)
self.splitButton.setToolTip(UiStrings().SplitToolTip)
self.insertButton.setText(translate('CustomPlugin.EditCustomForm', 'Insert Slide'))
self.insertButton.setToolTip(translate('CustomPlugin.EditCustomForm',
def retranslateUi(self, custom_slide_edit_dialog):
custom_slide_edit_dialog.setWindowTitle(translate('CustomPlugin.EditVerseForm', 'Edit Slide'))
self.split_button.setText(UiStrings().Split)
self.split_button.setToolTip(UiStrings().SplitToolTip)
self.insert_button.setText(translate('CustomPlugin.EditCustomForm', 'Insert Slide'))
self.insert_button.setToolTip(translate('CustomPlugin.EditCustomForm',
'Split a slide into two by inserting a slide splitter.'))

View File

@ -50,51 +50,49 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
super(EditCustomSlideForm, self).__init__(parent)
self.setupUi(self)
# Connecting signals and slots
QtCore.QObject.connect(self.insertButton, QtCore.SIGNAL(u'clicked()'), self.onInsertButtonClicked)
QtCore.QObject.connect(self.splitButton, QtCore.SIGNAL(u'clicked()'), self.onSplitButtonClicked)
self.insert_button.clicked.connect(self.on_insert_button_clicked)
self.split_button.clicked.connect(self.on_split_button_clicked)
def setText(self, text):
def set_text(self, text):
"""
Set the text for slideTextEdit.
Set the text for slide_text_edit.
``text``
The text (unicode).
"""
self.slideTextEdit.clear()
self.slide_text_edit.clear()
if text:
self.slideTextEdit.setPlainText(text)
self.slideTextEdit.setFocus()
self.slide_text_edit.setPlainText(text)
self.slide_text_edit.setFocus()
def getText(self):
def get_text(self):
"""
Returns a list with all slides.
"""
return self.slideTextEdit.toPlainText().split(u'\n[===]\n')
return self.slide_text_edit.toPlainText().split(u'\n[===]\n')
def onInsertButtonClicked(self):
def on_insert_button_clicked(self):
"""
Adds a slide split at the cursor.
"""
self.insertSingleLineTextAtCursor(u'[===]')
self.slideTextEdit.setFocus()
self.insert_single_line_text_at_cursor(u'[===]')
self.slide_text_edit.setFocus()
def onSplitButtonClicked(self):
def on_split_button_clicked(self):
"""
Adds an optional split at cursor.
"""
self.insertSingleLineTextAtCursor(u'[---]')
self.slideTextEdit.setFocus()
self.insert_single_line_text_at_cursor(u'[---]')
self.slide_text_edit.setFocus()
def insertSingleLineTextAtCursor(self, text):
def insert_single_line_text_at_cursor(self, text):
"""
Adds ``text`` in a single line at the cursor position.
"""
full_text = self.slideTextEdit.toPlainText()
position = self.slideTextEdit.textCursor().position()
full_text = self.slide_text_edit.toPlainText()
position = self.slide_text_edit.textCursor().position()
if position and full_text[position - 1] != u'\n':
text = u'\n' + text
if position == len(full_text) or full_text[position] != u'\n':
text += u'\n'
self.slideTextEdit.insertPlainText(text)
#lint:enable
self.slide_text_edit.insertPlainText(text)

View File

@ -45,38 +45,36 @@ class CustomTab(SettingsTab):
def setupUi(self):
self.setObjectName(u'CustomTab')
SettingsTab.setupUi(self)
self.customModeGroupBox = QtGui.QGroupBox(self.leftColumn)
self.customModeGroupBox.setObjectName(u'customModeGroupBox')
self.customModeLayout = QtGui.QFormLayout(self.customModeGroupBox)
self.customModeLayout.setObjectName(u'customModeLayout')
self.displayFooterCheckBox = QtGui.QCheckBox(self.customModeGroupBox)
self.displayFooterCheckBox.setObjectName(u'displayFooterCheckBox')
self.customModeLayout.addRow(self.displayFooterCheckBox)
self.add_from_service_checkbox = QtGui.QCheckBox(self.customModeGroupBox)
self.custom_mode_group_box = QtGui.QGroupBox(self.leftColumn)
self.custom_mode_group_box.setObjectName(u'custom_mode_group_box')
self.custom_mode_layout = QtGui.QFormLayout(self.custom_mode_group_box)
self.custom_mode_layout.setObjectName(u'custom_mode_layout')
self.display_footer_check_box = QtGui.QCheckBox(self.custom_mode_group_box)
self.display_footer_check_box.setObjectName(u'display_footer_check_box')
self.custom_mode_layout.addRow(self.display_footer_check_box)
self.add_from_service_checkbox = QtGui.QCheckBox(self.custom_mode_group_box)
self.add_from_service_checkbox.setObjectName(u'add_from_service_checkbox')
self.customModeLayout.addRow(self.add_from_service_checkbox)
self.leftLayout.addWidget(self.customModeGroupBox)
self.custom_mode_layout.addRow(self.add_from_service_checkbox)
self.leftLayout.addWidget(self.custom_mode_group_box)
self.leftLayout.addStretch()
self.rightLayout.addStretch()
QtCore.QObject.connect(self.displayFooterCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
self.onDisplayFooterCheckBoxChanged)
QtCore.QObject.connect(self.add_from_service_checkbox, QtCore.SIGNAL(u'stateChanged(int)'),
self.on_add_from_service_check_box_changed)
self.display_footer_check_box.stateChanged.connect(self.on_display_footer_check_box_changed)
self.add_from_service_checkbox.stateChanged.connect(self.on_add_from_service_check_box_changed)
def retranslateUi(self):
self.customModeGroupBox.setTitle(translate('CustomPlugin.CustomTab', 'Custom Display'))
self.displayFooterCheckBox.setText(translate('CustomPlugin.CustomTab', 'Display footer'))
self.custom_mode_group_box.setTitle(translate('CustomPlugin.CustomTab', 'Custom Display'))
self.display_footer_check_box.setText(translate('CustomPlugin.CustomTab', 'Display footer'))
self.add_from_service_checkbox.setText(translate('CustomPlugin.CustomTab',
'Import missing custom slides from service files'))
def onDisplayFooterCheckBoxChanged(self, check_state):
def on_display_footer_check_box_changed(self, check_state):
"""
Toggle the setting for displaying the footer.
"""
self.displayFooter = False
self.display_footer = False
# we have a set value convert to True/False
if check_state == QtCore.Qt.Checked:
self.displayFooter = True
self.display_footer = True
def on_add_from_service_check_box_changed(self, check_state):
self.update_load = (check_state == QtCore.Qt.Checked)
@ -84,15 +82,15 @@ class CustomTab(SettingsTab):
def load(self):
settings = Settings()
settings.beginGroup(self.settingsSection)
self.displayFooter = settings.value(u'display footer')
self.display_footer = settings.value(u'display footer')
self.update_load = settings.value(u'add custom from service')
self.displayFooterCheckBox.setChecked(self.displayFooter)
self.display_footer_check_box.setChecked(self.display_footer)
self.add_from_service_checkbox.setChecked(self.update_load)
settings.endGroup()
def save(self):
settings = Settings()
settings.beginGroup(self.settingsSection)
settings.setValue(u'display footer', self.displayFooter)
settings.setValue(u'display footer', self.display_footer)
settings.setValue(u'add custom from service', self.update_load)
settings.endGroup()

View File

@ -114,7 +114,7 @@ class CustomMediaItem(MediaManagerItem):
# active trigger it and clean up so it will not update again.
def onNewClick(self):
self.edit_custom_form.loadCustom(0)
self.edit_custom_form.load_custom(0)
self.edit_custom_form.exec_()
self.onClearTextButtonClick()
self.onSelectionChange()
@ -128,7 +128,7 @@ class CustomMediaItem(MediaManagerItem):
custom_id = int(custom_id)
valid = self.manager.get_object(CustomSlide, custom_id)
if valid:
self.edit_custom_form.loadCustom(custom_id, preview)
self.edit_custom_form.load_custom(custom_id, preview)
if self.edit_custom_form.exec_() == QtGui.QDialog.Accepted:
self.remoteTriggered = True
self.remoteCustom = custom_id
@ -148,7 +148,7 @@ class CustomMediaItem(MediaManagerItem):
if check_item_selected(self.listView, UiStrings().SelectEdit):
item = self.listView.currentItem()
item_id = item.data(QtCore.Qt.UserRole)
self.edit_custom_form.loadCustom(item_id, False)
self.edit_custom_form.load_custom(item_id, False)
self.edit_custom_form.exec_()
self.autoSelectId = -1
self.onSearchTextButtonClicked()

View File

@ -89,7 +89,7 @@ class ImagePlugin(Plugin):
log.debug(u'Importing images list from old config: %s' % files_from_config)
self.mediaItem.save_new_images_list(files_from_config)
def setPluginTextStrings(self):
def set_plugin_text_strings(self):
"""
Called to define all translatable texts of the plugin
"""

View File

@ -561,7 +561,7 @@ class ImageMediaItem(MediaManagerItem):
Called to reset the Live background with the image selected,
"""
self.resetAction.setVisible(False)
self.live_controller.display.resetImage()
self.live_controller.display.reset_image()
def live_theme_changed(self):
"""
@ -582,7 +582,7 @@ class ImageMediaItem(MediaManagerItem):
return
filename = bitem.data(0, QtCore.Qt.UserRole).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)
else:
critical_error_message_box(UiStrings().LiveBGError,

View File

@ -61,16 +61,16 @@ class MediaMediaItem(MediaManagerItem):
self.singleServiceItem = False
self.hasSearch = True
self.mediaObject = None
self.displayController = DisplayController(parent)
self.displayController.controllerLayout = QtGui.QVBoxLayout()
self.media_controller.register_controller(self.displayController)
self.media_controller.set_controls_visible(self.displayController, False)
self.displayController.previewDisplay = Display(self.displayController, False, self.displayController)
self.displayController.previewDisplay.hide()
self.displayController.previewDisplay.setGeometry(QtCore.QRect(0, 0, 300, 300))
self.displayController.previewDisplay.screen = {u'size':self.displayController.previewDisplay.geometry()}
self.displayController.previewDisplay.setup()
self.media_controller.setup_display(self.displayController.previewDisplay, False)
self.display_controller = DisplayController(parent)
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.hide()
self.display_controller.preview_display.setGeometry(QtCore.QRect(0, 0, 300, 300))
self.display_controller.preview_display.screen = {u'size': self.display_controller.preview_display.geometry()}
self.display_controller.preview_display.setup()
self.media_controller.setup_display(self.display_controller.preview_display, False)
Registry().register_function(u'video_background_replaced', self.video_background_replaced)
Registry().register_function(u'mediaitem_media_rebuild', self.rebuild_players)
Registry().register_function(u'config_screen_changed', self.display_setup)
@ -214,7 +214,7 @@ class MediaMediaItem(MediaManagerItem):
u' '.join(self.media_controller.audio_extensions_list), UiStrings().AllFiles)
def display_setup(self):
self.media_controller.setup_display(self.displayController.previewDisplay, False)
self.media_controller.setup_display(self.display_controller.previewDisplay, False)
def populateDisplayTypes(self):
"""
@ -226,11 +226,11 @@ class MediaMediaItem(MediaManagerItem):
self.displayTypeComboBox.blockSignals(True)
self.displayTypeComboBox.clear()
usedPlayers, overridePlayer = get_media_players()
mediaPlayers = self.media_controller.mediaPlayers
media_players = self.media_controller.media_players
currentIndex = 0
for player in usedPlayers:
# load the drop down selection
self.displayTypeComboBox.addItem(mediaPlayers[player].original_name)
self.displayTypeComboBox.addItem(media_players[player].original_name)
if overridePlayer == player:
currentIndex = len(self.displayTypeComboBox)
if self.displayTypeComboBox.count() > 1:

View File

@ -66,7 +66,7 @@ class MediaPlugin(Plugin):
'<br />The media plugin provides playback of audio and video.')
return about_text
def setPluginTextStrings(self):
def set_plugin_text_strings(self):
"""
Called to define all translatable texts of the plugin
"""

View File

@ -156,7 +156,7 @@ class PresentationPlugin(Plugin):
'available to the user in a drop down box.')
return about_text
def setPluginTextStrings(self):
def set_plugin_text_strings(self):
"""
Called to define all translatable texts of the plugin
"""

View File

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

View File

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

View File

@ -923,6 +923,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.song.verse_order)
except:
log.exception(u'Problem processing song Lyrics \n%s', sxml.dump_xml())
raise
def _get_plugin_manager(self):
"""

View File

@ -176,7 +176,7 @@ class SongsPlugin(Plugin):
return translate('SongsPlugin', '<strong>Songs Plugin</strong>'
'<br />The songs plugin provides the ability to display and manage songs.')
def usesTheme(self, theme):
def uses_theme(self, theme):
"""
Called to find out if the song plugin is currently using a theme.
@ -186,7 +186,7 @@ class SongsPlugin(Plugin):
return True
return False
def renameTheme(self, oldTheme, newTheme):
def rename_theme(self, oldTheme, newTheme):
"""
Renames a theme the song plugin is using making the plugin use the new
name.
@ -209,7 +209,7 @@ class SongsPlugin(Plugin):
importer.register(self.mediaItem.importWizard)
return importer
def setPluginTextStrings(self):
def set_plugin_text_strings(self):
"""
Called to define all translatable texts of the plugin
"""

View File

@ -219,7 +219,7 @@ class SongUsagePlugin(Plugin):
'</strong><br />This plugin tracks the usage of songs in services.')
return about_text
def setPluginTextStrings(self):
def set_plugin_text_strings(self):
"""
Called to define all translatable texts of the plugin
"""

View File

@ -7,7 +7,7 @@ from datetime import datetime, timedelta
from mock import MagicMock, patch
from openlp.core.lib import str_to_bool, translate, check_directory_exists, get_text_file_string, build_icon, \
image_to_byte, check_item_selected, validate_thumb, create_separated_list
image_to_byte, check_item_selected, validate_thumb, create_separated_list, expand_tags
class TestLib(TestCase):
@ -299,6 +299,45 @@ class TestLib(TestCase):
MockedQtGui.QMessageBox.information.assert_called_with(u'parent', u'mocked translate', 'message')
assert not result, u'The result should be False'
def expand_tags_test(self):
"""
Test the expand_tags() method.
"""
with patch(u'openlp.core.lib.FormattingTags.get_html_tags') as mocked_get_tags:
# GIVEN: Mocked get_html_tags() method.
mocked_get_tags.return_value = [
{
u'desc': u'Black',
u'start tag': u'{b}',
u'start html': u'<span style="-webkit-text-fill-color:black">',
u'end tag': u'{/b}', u'end html': u'</span>', u'protected': True,
u'temporary': False
},
{
u'desc': u'Yellow',
u'start tag': u'{y}',
u'start html': u'<span style="-webkit-text-fill-color:yellow">',
u'end tag': u'{/y}', u'end html': u'</span>', u'protected': True,
u'temporary': False
},
{
u'desc': u'Green',
u'start tag': u'{g}',
u'start html': u'<span style="-webkit-text-fill-color:green">',
u'end tag': u'{/g}', u'end html': u'</span>', u'protected': True,
u'temporary': False
}
]
string_to_pass = u'{b}black{/b}{y}yellow{/y}'
wanted_string = u'<span style="-webkit-text-fill-color:black">black</span>' + \
'<span style="-webkit-text-fill-color:yellow">yellow</span>'
# WHEN: Replace the tags.
result_string = expand_tags(string_to_pass)
# THEN: The strings should be identical.
assert result_string == wanted_string, u'The strings should be identical.'
def validate_thumb_file_does_not_exist_test(self):
"""
Test the validate_thumb() function when the thumbnail does not exist

View File

@ -216,12 +216,15 @@ class TestServiceItem(TestCase):
assert service_item.get_frame_path(0) == test_file, u'The frame path should match the full path to the image'
assert service_item.get_frame_title(0) == image_name, u'The frame title should match the image name'
assert service_item.get_display_title() == image_name, u'The display title should match the first image name'
assert service_item.is_image() is True, u'This service item is an Image'
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, u'This service item can be Maintained'
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, u'This service item can be Previewed'
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, u'This service item can be made to Loop'
assert service_item.is_image() is True, u'This service item should be of an "image" type'
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \
u'This service item should be able to be Maintained'
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \
u'This service item should be able to be be Previewed'
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \
u'This service item should be able to be run in a can be made to Loop'
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
u'This service item can have new items added'
u'This service item should be able to have new items added to it'
def serviceitem_load_image_from_local_service_test(self):
"""
@ -256,11 +259,14 @@ class TestServiceItem(TestCase):
assert service_item.get_display_title().lower() == service_item.name, \
u'The plugin name should match the display title, as there are > 1 Images'
assert service_item.is_image() is True, u'This service item should be of an "image" type'
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, u'This service item can be Maintained'
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, u'This service item can be Previewed'
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, u'This service item can be made to Loop'
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \
u'This service item should be able to be Maintained'
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \
u'This service item should be able to be be Previewed'
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \
u'This service item should be able to be run in a can be made to Loop'
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
u'This service item can have new items added'
u'This service item should be able to have new items added to it'
def convert_file_service_item(self, name):
service_file = os.path.join(TEST_PATH, name)