This commit is contained in:
Raoul Snyman 2010-09-03 07:30:26 +02:00
commit 7ebf4434a5
171 changed files with 17050 additions and 15846 deletions

View File

@ -32,12 +32,13 @@ from optparse import OptionParser
from PyQt4 import QtCore, QtGui
log = logging.getLogger()
from openlp.core.lib import Receiver
from openlp.core.resources import qInitResources
from openlp.core.ui import MainWindow, SplashScreen, ScreenList
from openlp.core.utils import AppLocation, LanguageManager
from openlp.core.ui.mainwindow import MainWindow
from openlp.core.ui import SplashScreen, ScreenList
from openlp.core.utils import AppLocation, LanguageManager, VersionThread
log = logging.getLogger()
application_stylesheet = u"""
QMainWindow::separator
@ -47,7 +48,6 @@ QMainWindow::separator
QDockWidget::title
{
/*background: palette(dark);*/
border: 1px solid palette(dark);
padding-left: 5px;
padding-top: 2px;
@ -122,7 +122,7 @@ class OpenLP(QtGui.QApplication):
show_splash = QtCore.QSettings().value(
u'general/show splash', QtCore.QVariant(True)).toBool()
if show_splash:
self.splash = SplashScreen(self.applicationVersion())
self.splash = SplashScreen()
self.splash.show()
# make sure Qt really display the splash screen
self.processEvents()
@ -141,7 +141,7 @@ class OpenLP(QtGui.QApplication):
# now kill the splashscreen
self.splash.finish(self.mainWindow)
self.mainWindow.repaint()
self.mainWindow.versionThread()
VersionThread(self.mainWindow, app_version).start()
return self.exec_()
def main():
@ -201,4 +201,4 @@ if __name__ == u'__main__':
"""
Instantiate and run the application.
"""
main()
main()

View File

@ -1 +1 @@
1.9.2
1.9.2-bzr987

View File

@ -25,4 +25,4 @@
###############################################################################
"""
The :mod:`openlp` module contains all the project produced OpenLP functionality
"""
"""

View File

@ -28,4 +28,4 @@ The :mod:`core` module provides all core application functions
All the core functions of the OpenLP application including the GUI, settings,
logging and a plugin framework are contained within the openlp.core module.
"""
"""

View File

@ -35,6 +35,67 @@ from PyQt4 import QtCore, QtGui
log = logging.getLogger(__name__)
# TODO make external and configurable in alpha 4 via a settings dialog
html_expands = []
html_expands.append({u'desc':u'Red', u'start tag':u'{r}', \
u'start html':u'<font color=red>', \
u'end tag':u'{/r}', u'end html':u'</font>', \
u'protected':False})
html_expands.append({u'desc':u'Black', u'start tag':u'{b}', \
u'start html':u'<font color=black>', \
u'end tag':u'{/b}', u'end html':u'</font>', \
u'protected':False})
html_expands.append({u'desc':u'Blue', u'start tag':u'{bl}', \
u'start html':u'<font color=blue>', \
u'end tag':u'{/bl}', u'end html':u'</font>', \
u'protected':False})
html_expands.append({u'desc':u'Yellow', u'start tag':u'{y}', \
u'start html':u'<font color=yellow>', \
u'end tag':u'{/y}', u'end html':u'</font>', \
u'protected':False})
html_expands.append({u'desc':u'Green', u'start tag':u'{g}', \
u'start html':u'<font color=green>', \
u'end tag':u'{/g}', u'end html':u'</font>', \
u'protected':False})
html_expands.append({u'desc':u'Pink', u'start tag':u'{pk}', \
u'start html':u'<font color=#CC33CC>', \
u'end tag':u'{/pk}', u'end html':u'</font>', \
u'protected':False})
html_expands.append({u'desc':u'Orange', u'start tag':u'{o}', \
u'start html':u'<font color=#CC0033>', \
u'end tag':u'{/o}', u'end html':u'</font>', \
u'protected':False})
html_expands.append({u'desc':u'Purple', u'start tag':u'{pp}', \
u'start html':u'<font color=#9900FF>', \
u'end tag':u'{/pp}', u'end html':u'</font>', \
u'protected':False})
html_expands.append({u'desc':u'White', u'start tag':u'{w}', \
u'start html':u'<font color=white>', \
u'end tag':u'{/w}', u'end html':u'</font>', \
u'protected':False})
html_expands.append({u'desc':u'Superscript', u'start tag':u'{su}', \
u'start html':u'<sup>', \
u'end tag':u'{/su}', u'end html':u'</sup>', \
u'protected':True})
html_expands.append({u'desc':u'Subscript', u'start tag':u'{sb}', \
u'start html':u'<sub>', \
u'end tag':u'{/sb}', u'end html':u'</sub>', \
u'protected':True})
html_expands.append({u'desc':u'Paragraph', u'start tag':u'{p}', \
u'start html':u'<p>', \
u'end tag':u'{/p}', u'end html':u'</p>', \
u'protected':True})
html_expands.append({u'desc':u'Bold', u'start tag':u'{st}', \
u'start html':u'<strong>', \
u'end tag':u'{/st}', \
u'end html':u'</strong>', \
u'protected':True})
html_expands.append({u'desc':u'Italics', u'start tag':u'{it}', \
u'start html':u'<em>', \
u'end tag':u'{/it}', u'end html':u'</em>', \
u'protected':True})
def translate(context, text, comment=None):
"""
A special shortcut method to wrap around the Qt4 translation functions.
@ -166,15 +227,46 @@ def context_menu_separator(base):
action.setSeparator(True)
return action
def resize_image(image, width, height):
def image_to_byte(image):
"""
Resize an image to fit on the current screen for the web and returns
it as a byte stream.
``image``
The image to converted.
"""
byte_array = QtCore.QByteArray()
# use buffer to store pixmap into byteArray
buffie = QtCore.QBuffer(byte_array)
buffie.open(QtCore.QIODevice.WriteOnly)
if isinstance(image, QtGui.QImage):
pixmap = QtGui.QPixmap.fromImage(image)
else:
pixmap = QtGui.QPixmap(image)
pixmap.save(buffie, "PNG")
# convert to base64 encoding so does not get missed!
return byte_array.toBase64()
def resize_image(image, width, height, background=QtCore.Qt.black):
"""
Resize an image to fit on the current screen.
``image``
The image to resize.
``width``
The new image width.
``height``
The new image height.
``background``
The background colour defaults to black.
"""
preview = QtGui.QImage(image)
if not preview.isNull():
# Only resize if different size
if preview.width() == width and preview.height == height:
return preview
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
@ -184,7 +276,7 @@ def resize_image(image, width, height):
# and move it to the centre of the preview space
new_image = QtGui.QImage(width, height,
QtGui.QImage.Format_ARGB32_Premultiplied)
new_image.fill(QtCore.Qt.black)
new_image.fill(background)
painter = QtGui.QPainter(new_image)
painter.drawImage((width - realw) / 2, (height - realh) / 2, preview)
return new_image
@ -205,6 +297,25 @@ def check_item_selected(list_widget, message):
return False
return True
def clean_tags(text):
"""
Remove Tags from text for display
"""
text = text.replace(u'<br>', u'\n')
for tag in html_expands:
text = text.replace(tag[u'start tag'], u'')
text = text.replace(tag[u'end tag'], u'')
return text
def expand_tags(text):
"""
Expand tags HTML for display
"""
for tag in html_expands:
text = text.replace(tag[u'start tag'], tag[u'start html'])
text = text.replace(tag[u'end tag'], tag[u'end html'])
return text
from eventreceiver import Receiver
from settingsmanager import SettingsManager
from plugin import PluginStatus, Plugin
@ -213,10 +324,11 @@ from settingstab import SettingsTab
from serviceitem import ServiceItem
from serviceitem import ServiceItemType
from serviceitem import ItemCapabilities
from htmlbuilder import build_html
from toolbar import OpenLPToolbar
from dockwidget import OpenLPDockWidget
from theme import ThemeLevel, ThemeXML
from renderer import Renderer
from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem
from baselistwithdnd import BaseListWithDnD
from baselistwithdnd import BaseListWithDnD

View File

@ -52,4 +52,4 @@ class BaseListWithDnD(QtGui.QListWidget):
mimeData = QtCore.QMimeData()
drag.setMimeData(mimeData)
mimeData.setText(self.PluginName)
drag.start(QtCore.Qt.CopyAction)
drag.start(QtCore.Qt.CopyAction)

View File

@ -199,7 +199,7 @@ class Manager(object):
Any parameters to order the returned objects by. Defaults to None.
"""
query = self.session.query(object_class)
if filter_clause:
if filter_clause is not None:
query = query.filter(filter_clause)
if order_by_ref is not None:
return query.order_by(order_by_ref).all()
@ -237,7 +237,7 @@ class Manager(object):
"""
try:
query = self.session.query(object_class)
if filter_clause:
if filter_clause is not None:
query = query.filter(filter_clause)
query.delete(synchronize_session=False)
self.session.commit()
@ -245,4 +245,4 @@ class Manager(object):
except InvalidRequestError:
self.session.rollback()
log.exception(u'Failed to delete %s records', object_class.__name__)
return False
return False

View File

@ -46,4 +46,4 @@ class OpenLPDockWidget(QtGui.QDockWidget):
if name:
self.setObjectName(name)
self.setFloating(False)
log.debug(u'Init done')
log.debug(u'Init done')

View File

@ -270,4 +270,4 @@ class Receiver(object):
"""
Get the global ``eventreceiver`` instance.
"""
return Receiver.eventreceiver
return Receiver.eventreceiver

View File

@ -0,0 +1,445 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from openlp.core.lib import image_to_byte
HTMLSRC = u"""
<html>
<head>
<title>OpenLP Display</title>
<style>
*{
margin: 0;
padding: 0;
border: 0;
}
body {
background-color: black;
}
.dim {
position: absolute;
left: 0px;
top: 0px;
width: %spx;
height: %spx;
}
#black {
z-index:8;
background-color: black;
display: none;
}
#video {
z-index:2;
}
#alert {
position: absolute;
left: 0px;
top: 0px;
z-index:10;
%s
}
#footer {
position: absolute;
z-index:5;
%s
}
/* lyric css */
%s
</style>
<script language="javascript">
var timer = null;
var transition = %s;
function show_video(state, path, volume, loop){
var vid = document.getElementById('video');
if(path != null)
vid.src = path;
if(loop != null){
if(loop)
vid.loop = 'loop';
else
vid.loop = '';
}
if(volume != null){
vid.volume = volume;
}
switch(state){
case 'play':
vid.play();
vid.style.display = 'block';
break;
case 'pause':
vid.pause();
vid.style.display = 'block';
break;
case 'stop':
vid.pause();
vid.style.display = 'none';
break;
case 'close':
vid.pause();
vid.style.display = 'none';
vid.src = '';
break;
}
}
function show_image(src){
var img = document.getElementById('image');
img.src = src;
if(src == '')
img.style.display = 'none';
else
img.style.display = 'block';
}
function show_blank(state){
var black = 'none';
var lyrics = '';
var pause = false;
switch(state){
case 'theme':
lyrics = 'hidden';
pause = true;
break;
case 'black':
black = 'block';
pause = true;
break;
case 'desktop':
pause = true;
break;
}
document.getElementById('black').style.display = black;
document.getElementById('lyricsmain').style.visibility = lyrics;
document.getElementById('lyricsoutline').style.visibility = lyrics;
document.getElementById('lyricsshadow').style.visibility = lyrics;
document.getElementById('footer').style.visibility = lyrics;
var vid = document.getElementById('video');
if(vid.src != ''){
if(pause)
vid.pause();
else
vid.play();
}
}
function show_alert(alerttext, position){
var text = document.getElementById('alert');
text.innerHTML = alerttext;
if(alerttext == '') {
text.style.visibility = 'hidden';
return 0;
}
if(position == ''){
position = window.getComputedStyle(text, '').verticalAlign;
}
switch(position)
{
case 'top':
text.style.top = '0px';
break;
case 'middle':
text.style.top = ((window.innerHeight - text.clientHeight) / 2)
+ 'px';
break;
case 'bottom':
text.style.top = (window.innerHeight - text.clientHeight)
+ 'px';
break;
}
text.style.visibility = 'visible';
return text.clientHeight;
}
function show_footer(footertext){
document.getElementById('footer').innerHTML = footertext;
}
function show_text(newtext){
var text1 = document.getElementById('lyricsmain');
var texto1 = document.getElementById('lyricsoutline');
var texts1 = document.getElementById('lyricsshadow');
if(!transition){
text1.innerHTML = newtext;
texto1.innerHTML = newtext;
texts1.innerHTML = newtext;
return;
}
var text2 = document.getElementById('lyricsmain2');
var texto2 = document.getElementById('lyricsoutline2');
var texts2 = document.getElementById('lyricsshadow2');
if((text2.style.opacity == '')||(parseFloat(text2.style.opacity) < 0.5))
{
text2.innerHTML = text1.innerHTML;
text2.style.opacity = text1.style.opacity;
texto2.innerHTML = text1.innerHTML;
texto2.style.opacity = text1.style.opacity;
texts2.innerHTML = text1.innerHTML;
texts2.style.opacity = text1.style.opacity;
}
text1.style.opacity = 0;
text1.innerHTML = newtext;
texto1.style.opacity = 0;
texto1.innerHTML = newtext;
texts1.style.opacity = 0;
texts1.innerHTML = newtext;
// For performance reasons, we'll not animate the shadow for now
texts2.style.opacity = 0;
if(timer != null)
clearTimeout(timer);
timer = setTimeout('text_fade()', 50);
}
function text_fade(){
var text1 = document.getElementById('lyricsmain');
var texto1 = document.getElementById('lyricsoutline');
var texts1 = document.getElementById('lyricsshadow');
var text2 = document.getElementById('lyricsmain2');
var texto2 = document.getElementById('lyricsoutline2');
var texts2 = document.getElementById('lyricsshadow2');
if(parseFloat(text1.style.opacity) < 1){
text1.style.opacity = parseFloat(text1.style.opacity) + 0.1;
texto1.style.opacity = parseFloat(texto1.style.opacity) + 0.1;
// Don't animate shadow (performance)
//texts1.style.opacity = parseFloat(texts1.style.opacity) + 0.1;
}
if(parseFloat(text2.style.opacity) > 0){
text2.style.opacity = parseFloat(text2.style.opacity) - 0.1;
texto2.style.opacity = parseFloat(texto2.style.opacity) - 0.1;
// Don't animate shadow (performance)
//texts2.style.opacity = parseFloat(texts2.style.opacity) - 0.1;
}
if((parseFloat(text1.style.opacity) < 1) ||
(parseFloat(text2.style.opacity) > 0)){
t = setTimeout('text_fade()', 50);
} else {
text1.style.opacity = 1;
texto1.style.opacity = 1;
texts1.style.opacity = 1;
text2.style.opacity = 0;
texto2.style.opacity = 0;
texts2.style.opacity = 0;
}
}
function show_text_complete(){
return (document.getElementById('lyricsmain').style.opacity == 1);
}
</script>
</head>
<body>
<!--
Using tables, rather than div's to make use of the vertical-align style that
doesn't work on div's. This avoids the need to do positioning manually which
could get messy when changing verses esp. with transitions
Would prefer to use a single table and make use of -webkit-text-fill-color
-webkit-text-stroke and text-shadow styles, but they have problems working/
co-operating in qwebkit. https://bugs.webkit.org/show_bug.cgi?id=43187
Therefore one table for text, one for outline and one for shadow.
-->
<table class="lyricstable lyricscommon">
<tr><td id="lyricsmain" class="lyrics"></td></tr>
</table>
<table class="lyricsoutlinetable lyricscommon">
<tr><td id="lyricsoutline" class="lyricsoutline lyrics"></td></tr>
</table>
<table class="lyricsshadowtable lyricscommon">
<tr><td id="lyricsshadow" class="lyricsshadow lyrics"></td></tr>
</table>
<table class="lyricstable lyricscommon">
<tr><td id="lyricsmain2" class="lyrics"></td></tr>
</table>
<table class="lyricsoutlinetable lyricscommon">
<tr><td id="lyricsoutline2" class="lyricsoutline lyrics"></td></tr>
</table>
<table class="lyricsshadowtable lyricscommon">
<tr><td id="lyricsshadow2" class="lyricsshadow lyrics"></td></tr>
</table>
<div id="alert" style="visibility:hidden;"></div>
<div id="footer" class="footer"></div>
<video class="dim" id="video"></video>
<div class="dim" id="black"></div>
<img class="dim" id="image" src="%s" />
</body>
</html>
"""
def build_html(item, screen, alert, islive):
"""
Build the full web paged structure for display
`item`
Service Item to be displayed
`screen`
Current display information
`alert`
Alert display display information
"""
width = screen[u'size'].width()
height = screen[u'size'].height()
theme = item.themedata
if item.bg_frame:
image = u'data:image/png;base64,%s' % image_to_byte(item.bg_frame)
else:
image = u''
html = HTMLSRC % (width, height,
build_alert(alert, width),
build_footer(item),
build_lyrics(item),
u'true' if theme and theme.display_slideTransition and islive \
else u'false',
image)
return html
def build_lyrics(item):
"""
Build the video display div
`item`
Service Item containing theme and location information
"""
style = """
.lyricscommon { position: absolute; %s }
.lyricstable { z-index:4; %s }
.lyricsoutlinetable { z-index:3; %s }
.lyricsshadowtable { z-index:2; %s }
.lyrics { %s }
.lyricsoutline { %s }
.lyricsshadow { %s }
"""
theme = item.themedata
lyricscommon = u''
lyricstable = u''
outlinetable = u''
shadowtable = u''
lyrics = u''
outline = u'display: none;'
shadow = u'display: none;'
if theme:
lyricscommon = u'width: %spx; height: %spx; word-wrap: break-word; ' \
u'font-family: %s; font-size: %spt; color: %s; line-height: %d%%;' \
% (item.main.width(), item.main.height(), theme.font_main_name,
theme.font_main_proportion, theme.font_main_color,
100 + int(theme.font_main_line_adjustment))
lyricstable = u'left: %spx; top: %spx;' % \
(item.main.x(), item.main.y())
outlinetable = u'left: %spx; top: %spx;' % \
(item.main.x(), item.main.y())
shadowtable = u'left: %spx; top: %spx;' % \
(item.main.x() + float(theme.display_shadow_size),
item.main.y() + float(theme.display_shadow_size))
align = u''
if theme.display_horizontalAlign == 2:
align = u'text-align:center;'
elif theme.display_horizontalAlign == 1:
align = u'text-align:right;'
else:
align = u'text-align:left;'
if theme.display_verticalAlign == 2:
valign = u'vertical-align:bottom;'
elif theme.display_verticalAlign == 1:
valign = u'vertical-align:middle;'
else:
valign = u'vertical-align:top;'
lyrics = u'%s %s' % (align, valign)
if theme.display_outline:
lyricscommon += u' letter-spacing: 1px;'
outline = u'-webkit-text-stroke: %sem %s; ' % \
(float(theme.display_outline_size) / 16,
theme.display_outline_color)
if theme.display_shadow:
shadow = u'-webkit-text-stroke: %sem %s; ' \
u'-webkit-text-fill-color: %s; ' % \
(float(theme.display_outline_size) / 16,
theme.display_shadow_color, theme.display_shadow_color)
else:
if theme.display_shadow:
shadow = u'color: %s;' % (theme.display_shadow_color)
lyrics_html = style % (lyricscommon, lyricstable, outlinetable,
shadowtable, lyrics, outline, shadow)
return lyrics_html
def build_footer(item):
"""
Build the display of the item footer
`item`
Service Item to be processed.
"""
style = """
left: %spx;
top: %spx;
width: %spx;
height: %spx;
font-family: %s;
font-size: %spt;
color: %s;
text-align: %s;
"""
theme = item.themedata
if not theme:
return u''
if theme.display_horizontalAlign == 2:
align = u'center'
elif theme.display_horizontalAlign == 1:
align = u'right'
else:
align = u'left'
lyrics_html = style % (item.footer.x(), item.footer.y(),
item.footer.width(), item.footer.height(), theme.font_footer_name,
theme.font_footer_proportion, theme.font_footer_color, align)
return lyrics_html
def build_alert(alertTab, width):
"""
Build the display of the footer
`alertTab`
Details from the Alert tab for fonts etc
"""
style = """
width: %s;
vertical-align: %s;
font-family: %s;
font-size: %spt;
color: %s;
background-color: %s;
"""
if not alertTab:
return u''
align = u''
if alertTab.location == 2:
align = u'bottom'
elif alertTab.location == 1:
align = u'middle'
else:
align = u'top'
alert = style % (width, align, alertTab.font_face, alertTab.font_size,
alertTab.font_color, alertTab.bg_color)
return alert

View File

@ -244,7 +244,8 @@ class MediaManagerItem(QtGui.QWidget):
self.addToolbarButton(
unicode(translate('OpenLP.MediaManagerItem', 'Delete %s')) %
self.PluginNameShort,
translate('OpenLP.MediaManagerItem', 'Delete the selected item'),
translate('OpenLP.MediaManagerItem',
'Delete the selected item'),
u':/general/general_delete.png', self.onDeleteClick)
## Separator Line ##
self.addToolbarSeparator()
@ -297,7 +298,8 @@ class MediaManagerItem(QtGui.QWidget):
self.listView.addAction(
context_menu_action(
self.listView, u':/general/general_delete.png',
unicode(translate('OpenLP.MediaManagerItem', '&Delete %s')) %
unicode(translate('OpenLP.MediaManagerItem',
'&Delete %s')) %
self.pluginNameVisible,
self.onDeleteClick))
self.listView.addAction(context_menu_separator(self.listView))
@ -509,7 +511,8 @@ class MediaManagerItem(QtGui.QWidget):
service_item = self.parent.serviceManager.getServiceItem()
if not service_item:
QtGui.QMessageBox.information(self,
translate('OpenLP.MediaManagerItem', 'No Service Item Selected'),
translate('OpenLP.MediaManagerItem',
'No Service Item Selected'),
translate('OpenLP.MediaManagerItem',
'You must select an existing service item to add to.'))
elif self.title.lower() == service_item.name.lower():
@ -519,7 +522,8 @@ class MediaManagerItem(QtGui.QWidget):
else:
#Turn off the remote edit update message indicator
QtGui.QMessageBox.information(self,
translate('OpenLP.MediaManagerItem', 'Invalid Service Item'),
translate('OpenLP.MediaManagerItem',
'Invalid Service Item'),
unicode(translate('OpenLP.MediaManagerItem',
'You must select a %s service item.')) % self.title)
@ -535,4 +539,4 @@ class MediaManagerItem(QtGui.QWidget):
if self.generateSlideData(service_item, item):
return service_item
else:
return None
return None

View File

@ -131,8 +131,8 @@ class Plugin(QtCore.QObject):
self.serviceManager = plugin_helpers[u'service']
self.settingsForm = plugin_helpers[u'settings form']
self.mediadock = plugin_helpers[u'toolbox']
self.displayManager = plugin_helpers[u'displaymanager']
self.pluginManager = plugin_helpers[u'pluginmanager']
self.formparent = plugin_helpers[u'formparent']
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_add_service_item' % self.name),
self.processAddServiceEvent)
@ -288,4 +288,4 @@ class Plugin(QtCore.QObject):
``newTheme``
The new name the plugin should now use.
"""
pass
pass

View File

@ -77,7 +77,6 @@ class PluginManager(object):
startdepth = len(os.path.abspath(plugin_dir).split(os.sep))
log.debug(u'finding plugins in %s at depth %d',
unicode(plugin_dir), startdepth)
for root, dirs, files in os.walk(plugin_dir):
for name in files:
if name.endswith(u'.py') and not name.startswith(u'__'):
@ -219,4 +218,4 @@ class PluginManager(object):
for plugin in self.plugins:
if plugin.isActive():
plugin.finalise()
log.info(u'Finalisation Complete for %s ' % plugin.name)
log.info(u'Finalisation Complete for %s ' % plugin.name)

View File

@ -31,7 +31,7 @@ import logging
from PyQt4 import QtGui, QtCore
from openlp.core.lib import resize_image
from openlp.core.lib import resize_image, expand_tags
log = logging.getLogger(__name__)
@ -80,7 +80,6 @@ class Renderer(object):
self.bg_image = None
self._bg_image_filename = None
self.theme_name = theme.theme_name
self._set_theme_font()
if theme.background_type == u'image':
if theme.background_filename:
self.set_bg_image(theme.background_filename)
@ -99,6 +98,20 @@ class Renderer(object):
self.frame.width(),
self.frame.height())
def set_text_rectangle(self, rect_main, rect_footer):
"""
Sets the rectangle within which text should be rendered.
``rect_main``
The main text block.
``rect_footer``
The footer text block.
"""
log.debug(u'set_text_rectangle %s , %s' % (rect_main, rect_footer))
self._rect = rect_main
self._rect_footer = rect_footer
def set_frame_dest(self, frame_width, frame_height, preview=False):
"""
Set the size of the slide.
@ -118,26 +131,24 @@ class Renderer(object):
frame_height)
self.frame = QtGui.QImage(frame_width, frame_height,
QtGui.QImage.Format_ARGB32_Premultiplied)
self.frame_opaque = QtGui.QImage(frame_width, frame_height,
QtGui.QImage.Format_ARGB32_Premultiplied)
if self._bg_image_filename and not self.bg_image:
self.bg_image = resize_image(self._bg_image_filename,
self.frame.width(), self.frame.height())
if self.bg_frame is None:
self._generate_background_frame()
def format_slide(self, words, footer):
def format_slide(self, words, line_break):
"""
Figure out how much text can appear on a slide, using the current
theme settings.
``words``
The words to be fitted on the slide.
``footer``
The footer of the slide.
"""
log.debug(u'format_slide - Start')
line_end = u''
if line_break:
line_end = u'<br>'
words = words.replace(u'\r\n', u'\n')
verses_text = words.split(u'\n')
text = []
@ -145,124 +156,43 @@ class Renderer(object):
lines = verse.split(u'\n')
for line in lines:
text.append(line)
split_text = self.pre_render_text(text)
log.debug(u'format_slide - End')
return split_text
def pre_render_text(self, text):
metrics = QtGui.QFontMetrics(self.main_font)
#work out line width
line_width = self._rect.width()
#number of lines on a page - adjust for rounding up.
line_height = metrics.height()
if self._theme.display_shadow:
line_height += int(self._theme.display_shadow_size)
if self._theme.display_outline:
# pixels top/bottom
line_height += 2 * int(self._theme.display_outline_size)
page_length = int(self._rect.height() / line_height )
#Average number of characters in line
ave_line_width = line_width / metrics.averageCharWidth()
#Maximum size of a character
max_char_width = metrics.maxWidth()
#Max characters pre line based on min size of a character
char_per_line = line_width / metrics.width(u'i')
log.debug(u'Page Length area height %s , metrics %s , lines %s' %
(int(self._rect.height()), metrics.height(), page_length ))
split_pages = []
page = []
split_lines = []
count = 0
for line in text:
#Must be a blank line so keep it.
if len(line) == 0:
line = u' '
while line:
pos = char_per_line
split_text = line[:pos]
#line needs splitting
if metrics.width(split_text, -1) > line_width:
#We have no spaces
if split_text.find(u' ') == -1:
#Move back 1 char at a time till it fits
while metrics.width(split_text, -1) > line_width:
split_text = split_text[:-1]
pos = len(split_text)
else:
#We have spaces so split at previous one
while metrics.width(split_text, -1) > line_width:
pos = split_text.rfind(u' ')
#no more spaces and we are still too long
if pos == -1:
while \
metrics.width(split_text, -1) > line_width:
split_text = split_text[:-1]
pos = len(split_text)
else:
split_text = line[:pos]
split_lines.append(split_text)
line = line[pos:].lstrip()
#if we have more text add up to 10 spaces on the front.
if line and self._theme.font_main_indentation > 0:
line = u'%s%s' % \
(u' '[:int(self._theme.font_main_indentation)],
line)
#Text fits in a line now
for count, line in enumerate(split_lines):
page.append(line)
#last but one line and only 2 lines to go or end of page
if (len(page) == page_length - 1 and
len(split_lines) - 3 == count) or \
len(page) == page_length:
split_pages.append(page)
page = []
if page and page != u' ':
split_pages.append(page)
return split_pages
def set_text_rectangle(self, rect_main, rect_footer):
"""
Sets the rectangle within which text should be rendered.
``rect_main``
The main text block.
``rect_footer``
The footer text block.
"""
log.debug(u'set_text_rectangle %s , %s' % (rect_main, rect_footer))
self._rect = rect_main
self._rect_footer = rect_footer
def generate_frame_from_lines(self, lines, footer_lines=None):
"""
Render a set of lines according to the theme, and return the block
dimensions.
``lines``
The lines to be rendered.
``footer_lines``
Defaults to *None*. The footer to render.
"""
log.debug(u'generate_frame_from_lines - Start')
bbox = self._render_lines_unaligned(lines, False)
if footer_lines:
bbox1 = self._render_lines_unaligned(footer_lines, True)
# reset the frame. first time do not worry about what you paint on.
self.frame = QtGui.QImage(self.bg_frame)
if self._theme.display_slideTransition:
self.frame_opaque = QtGui.QImage(self.bg_frame)
x, y = self._correct_alignment(self._rect, bbox)
bbox = self._render_lines_unaligned(lines, False, (x, y), True)
if footer_lines:
bbox = self._render_lines_unaligned(footer_lines, True,
(self._rect_footer.left(), self._rect_footer.top()), True)
log.debug(u'generate_frame_from_lines - Finish')
if self._theme.display_slideTransition:
return {u'main':self.frame, u'trans':self.frame_opaque}
doc = QtGui.QTextDocument()
doc.setPageSize(QtCore.QSizeF(self._rect.width(), self._rect.height()))
df = doc.defaultFont()
df.setPixelSize(self._theme.font_main_proportion)
df.setFamily(self._theme.font_main_name)
main_weight = 50
if self._theme.font_main_weight == u'Bold':
main_weight = 75
df.setWeight(main_weight)
doc.setDefaultFont(df)
layout = doc.documentLayout()
formatted = []
if self._theme.font_main_weight == u'Bold' and \
self._theme.font_main_italics:
shell = u'{p}{st}{it}%s{/it}{/st}{/p}'
elif self._theme.font_main_weight == u'Bold' and \
not self._theme.font_main_italics:
shell = u'{p}{st}%s{/st}{/p}'
elif self._theme.font_main_italics:
shell = u'{p}{it}%s{/it}{/p}'
else:
return {u'main':self.frame, u'trans':None}
shell = u'{p}%s{/p}'
temp_text = u''
old_html_text = u''
for line in text:
# mark line ends
temp_text = temp_text + line + line_end
html_text = shell % expand_tags(temp_text)
doc.setHtml(html_text)
# Text too long so gone to next mage
if layout.pageCount() != 1:
formatted.append(shell % old_html_text)
temp_text = line
old_html_text = temp_text
formatted.append(shell % old_html_text)
log.debug(u'format_slide - End')
return formatted
def _generate_background_frame(self):
"""
@ -270,327 +200,47 @@ class Renderer(object):
Results are cached for performance reasons.
"""
assert(self._theme)
if self._theme.background_mode == u'transparent':
self.bg_frame = \
QtGui.QPixmap(self.frame.width(), self.frame.height())
self.bg_frame.fill(QtCore.Qt.transparent)
else:
self.bg_frame = QtGui.QImage(self.frame.width(),
self.frame.height(), QtGui.QImage.Format_ARGB32_Premultiplied)
self.bg_frame = QtGui.QImage(self.frame.width(),
self.frame.height(), QtGui.QImage.Format_ARGB32_Premultiplied)
log.debug(u'render background %s start', self._theme.background_type)
painter = QtGui.QPainter()
painter.begin(self.bg_frame)
if self._theme.background_mode == u'transparent':
painter.fillRect(self.frame.rect(), QtCore.Qt.transparent)
else:
if self._theme.background_type == u'solid':
painter.fillRect(self.frame.rect(),
QtGui.QColor(self._theme.background_color))
elif self._theme.background_type == u'gradient':
# gradient
gradient = None
if self._theme.background_direction == u'horizontal':
w = int(self.frame.width()) / 2
# vertical
gradient = QtGui.QLinearGradient(w, 0, w,
self.frame.height())
elif self._theme.background_direction == u'vertical':
h = int(self.frame.height()) / 2
# Horizontal
gradient = QtGui.QLinearGradient(0, h, self.frame.width(),
h)
else:
w = int(self.frame.width()) / 2
h = int(self.frame.height()) / 2
# Circular
gradient = QtGui.QRadialGradient(w, h, w)
gradient.setColorAt(0,
QtGui.QColor(self._theme.background_startColor))
gradient.setColorAt(1,
QtGui.QColor(self._theme.background_endColor))
painter.setBrush(QtGui.QBrush(gradient))
rect_path = QtGui.QPainterPath()
max_x = self.frame.width()
max_y = self.frame.height()
rect_path.moveTo(0, 0)
rect_path.lineTo(0, max_y)
rect_path.lineTo(max_x, max_y)
rect_path.lineTo(max_x, 0)
rect_path.closeSubpath()
painter.drawPath(rect_path)
elif self._theme.background_type == u'image':
# image
painter.fillRect(self.frame.rect(), QtCore.Qt.black)
if self.bg_image:
painter.drawImage(0, 0, self.bg_image)
painter.end()
log.debug(u'render background End')
def _correct_alignment(self, rect, bbox):
"""
Corrects the vertical alignment of text.
``rect``
The block dimentions.
``bbox``
Footer dimensions?
"""
x = rect.left()
if self._theme.display_verticalAlign == 0:
# top align
y = rect.top()
elif self._theme.display_verticalAlign == 2:
# bottom align
y = rect.bottom() - bbox.height()
elif self._theme.display_verticalAlign == 1:
# centre align
y = rect.top() + (rect.height() - bbox.height()) / 2
else:
log.error(u'Invalid value for theme.VerticalAlign:%s',
self._theme.display_verticalAlign)
return x, y
def _render_lines_unaligned(self, lines, footer, tlcorner=(0, 0),
live=False):
"""
Given a list of lines to render, render each one in turn (using the
``_render_single_line`` fn - which may result in going off the bottom).
They are expected to be pre-arranged to less than a screenful (eg. by
using split_set_of_lines).
Returns the bounding box of the text as QRect.
``lines``
The lines of text to render.
``footer``
The slide footer.
``tlcorner``
Defaults to *``(0, 0)``*. Co-ordinates of the top left corner.
``live``
Defaults to *False*. Whether or not this is a live screen.
"""
x, y = tlcorner
brx = x
bry = y
for line in lines:
# render after current bottom, but at original left edge
# keep track of right edge to see which is biggest
(thisx, bry) = self._render_and_wrap_single_line(line, footer,
(x, bry), live)
if (thisx > brx):
brx = thisx
retval = QtCore.QRect(x, y, brx - x, bry - y)
if self._debug:
painter = QtGui.QPainter()
painter.begin(self.frame)
painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 255)))
painter.drawRect(retval)
painter.end()
return retval
def _render_and_wrap_single_line(self, line, footer, tlcorner=(0, 0),
live=False):
"""
Render a single line of words onto the DC, top left corner specified.
If the line is too wide for the context, it wraps, but right-aligns
the surplus words in the manner of song lyrics.
Returns the bottom-right corner (of what was rendered) as a tuple(x, y).
``line``
Line of text to be rendered.
``footer``
The footer of the slide.
``tlcorner``
Defaults to *``(0, 0)``*. The top left corner.
``live``
Defaults to *False*. Whether or not this is a live screen.
"""
x, y = tlcorner
maxx = self._rect.width()
maxy = self._rect.height()
lines = []
lines.append(line)
startx = x
starty = y
rightextent = None
self.painter = QtGui.QPainter()
self.painter.begin(self.frame)
self.painter.setRenderHint(QtGui.QPainter.Antialiasing)
if self._theme.display_slideTransition:
self.painter2 = QtGui.QPainter()
self.painter2.begin(self.frame_opaque)
self.painter2.setRenderHint(QtGui.QPainter.Antialiasing)
self.painter2.setOpacity(0.7)
# dont allow alignment messing with footers
if footer:
align = 0
display_shadow_size = self._display_shadow_size_footer
display_outline_size = self._display_outline_size_footer
else:
align = self._theme.display_horizontalAlign
display_shadow_size = int(self._theme.display_shadow_size)
display_outline_size = int(self._theme.display_outline_size)
for linenum in range(len(lines)):
line = lines[linenum]
#find out how wide line is
w, h = self._get_extent_and_render(line, footer, tlcorner=(x, y),
draw=False)
if self._theme.display_shadow:
w += display_shadow_size
h += display_shadow_size
if self._theme.display_outline:
# pixels either side
w += 2 * display_outline_size
# pixels top/bottom
h += 2 * display_outline_size
if align == 0: # left align
rightextent = x + w
# shift right from last line's rh edge
if self._theme.display_wrapStyle == 1 and linenum != 0:
rightextent = self._first_line_right_extent
if rightextent > maxx:
rightextent = maxx
x = rightextent - w
# right align
elif align == 1:
rightextent = maxx
x = maxx - w
# centre
elif align == 2:
x = (maxx - w) / 2
rightextent = x + w
if live:
# now draw the text, and any outlines/shadows
if self._theme.display_shadow:
self._get_extent_and_render(line, footer,
tlcorner=(x + display_shadow_size,
y + display_shadow_size),
draw=True, color=self._theme.display_shadow_color)
self._get_extent_and_render(line, footer, tlcorner=(x, y),
draw=True, outline_size=display_outline_size)
y += h
if linenum == 0:
self._first_line_right_extent = rightextent
# draw a box around the text - debug only
if self._debug:
self.painter.setPen(QtGui.QPen(QtGui.QColor(0, 255, 0)))
self.painter.drawRect(startx, starty, rightextent-startx, y-starty)
brcorner = (rightextent, y)
self.painter.end()
if self._theme.display_slideTransition:
self.painter2.end()
return brcorner
def _set_theme_font(self):
"""
Set the fonts from the current theme settings.
"""
footer_weight = 50
if self._theme.font_footer_weight == u'Bold':
footer_weight = 75
#TODO Add myfont.setPixelSize((screen_height / 100) * font_size)
self.footer_font = QtGui.QFont(self._theme.font_footer_name,
self._theme.font_footer_proportion, # size
footer_weight, # weight
self._theme.font_footer_italics) # italic
self.footer_font.setPixelSize(self._theme.font_footer_proportion)
main_weight = 50
if self._theme.font_main_weight == u'Bold':
main_weight = 75
self.main_font = QtGui.QFont(self._theme.font_main_name,
self._theme.font_main_proportion, # size
main_weight, # weight
self._theme.font_main_italics)# italic
self.main_font.setPixelSize(self._theme.font_main_proportion)
def _get_extent_and_render(self, line, footer, tlcorner=(0, 0), draw=False,
color=None, outline_size=0):
"""
Find bounding box of text - as render_single_line. If draw is set,
actually draw the text to the current DC as well return width and
height of text as a tuple (w, h).
``line``
The line of text to render.
``footer``
The footer text.
``tlcorner``
Defaults to *``(0, 0)``*. The top left corner co-ordinates.
``draw``
Defaults to *False*. Draw the text to the current surface.
``color``
Defaults to *None*. The colour to draw with.
"""
# setup defaults
if footer:
font = self.footer_font
else:
font = self.main_font
metrics = QtGui.QFontMetrics(font)
w = metrics.width(line)
if footer:
h = metrics.height()
else:
h = metrics.height() + int(self._theme.font_main_line_adjustment)
if draw:
self.painter.setFont(font)
if color is None:
if footer:
pen = QtGui.QColor(self._theme.font_footer_color)
else:
pen = QtGui.QColor(self._theme.font_main_color)
if self._theme.background_type == u'solid':
painter.fillRect(self.frame.rect(),
QtGui.QColor(self._theme.background_color))
elif self._theme.background_type == u'gradient':
# gradient
gradient = None
if self._theme.background_direction == u'horizontal':
w = int(self.frame.width()) / 2
# vertical
gradient = QtGui.QLinearGradient(w, 0, w, self.frame.height())
elif self._theme.background_direction == u'vertical':
h = int(self.frame.height()) / 2
# Horizontal
gradient = QtGui.QLinearGradient(0, h, self.frame.width(), h)
else:
pen = QtGui.QColor(color)
x, y = tlcorner
rowpos = y + metrics.ascent()
if self._theme.display_outline and outline_size != 0 and not footer:
path = QtGui.QPainterPath()
path.addText(QtCore.QPointF(x, rowpos), font, line)
self.painter.setBrush(self.painter.pen().brush())
self.painter.setPen(QtGui.QPen(QtGui.QColor(
self._theme.display_outline_color), outline_size))
self.painter.drawPath(path)
self.painter.setPen(pen)
self.painter.drawText(x, rowpos, line)
if self._theme.display_slideTransition:
# Print 2nd image with 70% weight
if self._theme.display_outline and outline_size != 0 and \
not footer:
path = QtGui.QPainterPath()
path.addText(QtCore.QPointF(x, rowpos), font, line)
self.painter2.setBrush(self.painter2.pen().brush())
self.painter2.setPen(QtGui.QPen(
QtGui.QColor(self._theme.display_outline_color),
outline_size))
self.painter2.drawPath(path)
self.painter2.setFont(font)
self.painter2.setPen(pen)
self.painter2.drawText(x, rowpos, line)
return (w, h)
def snoop_image(self, image, image2=None):
"""
Debugging method to allow images to be viewed.
``image``
An image to save to disk.
``image2``
Defaults to *None*. Another image to save to disk.
"""
image.save(u'renderer.png', u'png')
if image2:
image2.save(u'renderer2.png', u'png')
w = int(self.frame.width()) / 2
h = int(self.frame.height()) / 2
# Circular
gradient = QtGui.QRadialGradient(w, h, w)
gradient.setColorAt(0,
QtGui.QColor(self._theme.background_startColor))
gradient.setColorAt(1,
QtGui.QColor(self._theme.background_endColor))
painter.setBrush(QtGui.QBrush(gradient))
rect_path = QtGui.QPainterPath()
max_x = self.frame.width()
max_y = self.frame.height()
rect_path.moveTo(0, 0)
rect_path.lineTo(0, max_y)
rect_path.lineTo(max_x, max_y)
rect_path.lineTo(max_x, 0)
rect_path.closeSubpath()
painter.drawPath(rect_path)
elif self._theme.background_type == u'image':
# image
painter.fillRect(self.frame.rect(), QtCore.Qt.black)
if self.bg_image:
painter.drawImage(0, 0, self.bg_image)
painter.end()

View File

@ -28,7 +28,8 @@ import logging
from PyQt4 import QtCore
from openlp.core.lib import Renderer, ThemeLevel
from openlp.core.lib import Renderer, ThemeLevel, ServiceItem
from openlp.core.ui import MainDisplay
log = logging.getLogger(__name__)
@ -55,6 +56,8 @@ class RenderManager(object):
"""
log.debug(u'Initilisation started')
self.screens = screens
self.display = MainDisplay(self, screens, False)
self.display.setup()
self.theme_manager = theme_manager
self.renderer = Renderer()
self.calculate_default(self.screens.current[u'size'])
@ -63,6 +66,7 @@ class RenderManager(object):
self.theme_level = u''
self.override_background = None
self.themedata = None
self.alertTab = None
def update_display(self):
"""
@ -70,7 +74,10 @@ class RenderManager(object):
"""
log.debug(u'Update Display')
self.calculate_default(self.screens.current[u'size'])
self.display = MainDisplay(self, self.screens, False)
self.display.setup()
self.renderer.bg_frame = None
self.themedata = None
def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global):
"""
@ -96,17 +103,22 @@ class RenderManager(object):
"""
self.service_theme = service_theme
def set_override_theme(self, theme):
def set_override_theme(self, theme, overrideLevels=False):
"""
Set the appropriate theme depending on the theme level.
Called by the service item when building a display frame
``theme``
The name of the song-level theme.
The name of the song-level theme. None means the service
item wants to use the given value.
"""
log.debug(u'set override theme to %s', theme)
if self.theme_level == ThemeLevel.Global:
theme_level = self.theme_level
if overrideLevels:
theme_level = ThemeLevel.Song
if theme_level == ThemeLevel.Global:
self.theme = self.global_theme
elif self.theme_level == ThemeLevel.Service:
elif theme_level == ThemeLevel.Service:
if self.service_theme == u'':
self.theme = self.global_theme
else:
@ -114,20 +126,26 @@ class RenderManager(object):
else:
if theme:
self.theme = theme
elif self.theme_level == ThemeLevel.Song or \
self.theme_level == ThemeLevel.Service:
elif theme_level == ThemeLevel.Song or \
theme_level == ThemeLevel.Service:
if self.service_theme == u'':
self.theme = self.global_theme
else:
self.theme = self.service_theme
else:
self.theme = self.global_theme
if self.theme != self.renderer.theme_name or self.themedata is None:
if self.theme != self.renderer.theme_name or self.themedata is None \
or overrideLevels:
log.debug(u'theme is now %s', self.theme)
self.themedata = self.theme_manager.getThemeData(self.theme)
if overrideLevels:
self.themedata = theme
else:
self.themedata = self.theme_manager.getThemeData(self.theme)
self.calculate_default(self.screens.current[u'size'])
self.renderer.set_theme(self.themedata)
self.build_text_rectangle(self.themedata)
self.renderer.set_frame_dest(self.width, self.height)
return self.renderer._rect, self.renderer._rect_footer
def build_text_rectangle(self, theme):
"""
@ -163,13 +181,8 @@ class RenderManager(object):
The theme to generated a preview for.
"""
log.debug(u'generate preview')
#set the default image size for previews
# set the default image size for previews
self.calculate_default(self.screens.preview[u'size'])
self.renderer.set_theme(themedata)
self.build_text_rectangle(themedata)
self.renderer.set_frame_dest(self.width, self.height, True)
#Reset the real screen size for subsequent render requests
self.calculate_default(self.screens.current[u'size'])
verse = u'Amazing Grace!\n'\
'How sweet the sound\n'\
'To save a wretch like me;\n'\
@ -179,12 +192,21 @@ class RenderManager(object):
footer.append(u'Amazing Grace (John Newton)' )
footer.append(u'Public Domain')
footer.append(u'CCLI 123456')
formatted = self.renderer.format_slide(verse, False)
#Only Render the first slide page returned
return self.renderer.generate_frame_from_lines(formatted[0],
footer)[u'main']
# build a service item to generate preview
serviceItem = ServiceItem()
serviceItem.theme = themedata
serviceItem.add_from_text(u'', verse, footer)
serviceItem.render_manager = self
serviceItem.raw_footer = footer
serviceItem.render(True)
self.display.buildHtml(serviceItem)
raw_html = serviceItem.get_rendered_frame(0)[1]
preview = self.display.text(raw_html)
# Reset the real screen size for subsequent render requests
self.calculate_default(self.screens.current[u'size'])
return preview
def format_slide(self, words):
def format_slide(self, words, line_break):
"""
Calculate how much text can fit on a slide.
@ -193,22 +215,7 @@ class RenderManager(object):
"""
log.debug(u'format slide')
self.build_text_rectangle(self.themedata)
return self.renderer.format_slide(words, False)
def generate_slide(self, main_text, footer_text):
"""
Generate the actual slide image.
``main_text``
The text for the main area of the slide.
``footer_text``
The text for the slide footer.
"""
log.debug(u'generate slide')
self.build_text_rectangle(self.themedata)
self.renderer.set_frame_dest(self.width, self.height)
return self.renderer.generate_frame_from_lines(main_text, footer_text)
return self.renderer.format_slide(words, line_break)
def calculate_default(self, screen):
"""
@ -224,4 +231,4 @@ class RenderManager(object):
log.debug(u'calculate default %d, %d, %f',
self.width, self.height, self.screen_ratio )
# 90% is start of footer
self.footer_start = int(self.height * 0.90)
self.footer_start = int(self.height * 0.90)

View File

@ -35,7 +35,7 @@ import uuid
from PyQt4 import QtGui
from openlp.core.lib import build_icon, resize_image
from openlp.core.lib import build_icon, resize_image, clean_tags, expand_tags
log = logging.getLogger(__name__)
@ -57,6 +57,7 @@ class ItemCapabilities(object):
RequiresMedia = 4
AllowsLoop = 5
AllowsAdditions = 6
NoLineBreaks = 7
class ServiceItem(object):
"""
@ -82,17 +83,29 @@ class ServiceItem(object):
self.items = []
self.iconic_representation = None
self.raw_footer = None
self.foot_text = None
self.theme = None
self.service_item_type = None
self._raw_frames = []
self._display_frames = []
self._uuid = unicode(uuid.uuid1())
self._uuid = 0
self.notes = u''
self.from_plugin = False
self.capabilities = []
self.is_valid = True
self.cache = {}
self.icon = None
self.themedata = None
self.main = None
self.footer = None
self.bg_frame = None
def _new_item(self):
"""
Method to set the internal id of the item
This is used to compare service items to see if they are
the same
"""
self._uuid = unicode(uuid.uuid1())
def add_capability(self, capability):
"""
@ -123,34 +136,38 @@ class ServiceItem(object):
self.icon = icon
self.iconic_representation = build_icon(icon)
def render(self):
def render(self, useOverride=False):
"""
The render method is what generates the frames for the screen.
The render method is what generates the frames for the screen and
obtains the display information from the renderemanager.
At this point all the slides are build for the given
display size.
"""
log.debug(u'Render called')
self._display_frames = []
self.clear_cache()
self.bg_frame = None
line_break = True
if self.is_capable(ItemCapabilities.NoLineBreaks):
line_break = False
if self.service_item_type == ServiceItemType.Text:
log.debug(u'Formatting slides')
if self.theme is None:
self.render_manager.set_override_theme(None)
else:
self.render_manager.set_override_theme(self.theme)
theme = None
if self.theme:
theme = self.theme
self.main, self.footer = \
self.render_manager.set_override_theme(theme, useOverride)
self.bg_frame = self.render_manager.renderer.bg_frame
self.themedata = self.render_manager.renderer._theme
for slide in self._raw_frames:
before = time.time()
formated = self.render_manager.format_slide(slide[u'raw_slide'])
for format in formated:
lines = u''
title = u''
for line in format:
if title == u'':
title = line
lines += line + u'\n'
self._display_frames.append({u'title': title,
u'text': lines.rstrip(),
formated = self.render_manager \
.format_slide(slide[u'raw_slide'], line_break)
for page in formated:
self._display_frames.append(
{u'title': clean_tags(page),
u'text': clean_tags(page.rstrip()),
u'html': expand_tags(page.rstrip()),
u'verseTag': slide[u'verseTag'] })
if len(self._display_frames) in self.cache.keys():
del self.cache[len(self._display_frames)]
log.log(15, u'Formatting took %4s' % (time.time() - before))
elif self.service_item_type == ServiceItemType.Image:
for slide in self._raw_frames:
@ -160,29 +177,14 @@ class ServiceItem(object):
pass
else:
log.error(u'Invalid value renderer :%s' % self.service_item_type)
def render_individual(self, row):
"""
Takes an array of text and generates an Image from the
theme. It assumes the text will fit on the screen as it
has generated by the render method above.
"""
log.debug(u'render individual')
if self.theme is None:
self.render_manager.set_override_theme(None)
else:
self.render_manager.set_override_theme(self.theme)
format = self._display_frames[row][u'text'].split(u'\n')
if self.cache.get(row):
frame = self.cache[row]
else:
if format[0]:
frame = self.render_manager.generate_slide(format,
self.raw_footer)
else:
frame = self.render_manager.generate_slide(format, u'')
self.cache[row] = frame
return frame
self.title = clean_tags(self.title)
self.foot_text = None
if self.raw_footer:
for foot in self.raw_footer:
if not self.foot_text:
self.foot_text = foot
else:
self.foot_text = u'%s<br>%s' % (self.foot_text, foot)
def add_from_image(self, path, title, image):
"""
@ -200,6 +202,7 @@ class ServiceItem(object):
self.service_item_type = ServiceItemType.Image
self._raw_frames.append(
{u'title': title, u'image': image, u'path': path})
self._new_item()
def add_from_text(self, title, raw_slide, verse_tag=None):
"""
@ -215,6 +218,7 @@ class ServiceItem(object):
title = title.split(u'\n')[0]
self._raw_frames.append(
{u'title': title, u'raw_slide': raw_slide, u'verseTag':verse_tag})
self._new_item()
def add_from_command(self, path, file_name, image):
"""
@ -232,6 +236,7 @@ class ServiceItem(object):
self.service_item_type = ServiceItemType.Command
self._raw_frames.append(
{u'title': file_name, u'image': image, u'path': path})
self._new_item()
def get_service_repr(self):
"""
@ -369,9 +374,9 @@ class ServiceItem(object):
renders it if required.
"""
if self.service_item_type == ServiceItemType.Text:
return self.render_individual(row)
return None, self._display_frames[row][u'html'].split(u'\n')[0]
else:
return {u'main':self._raw_frames[row][u'image'], u'trans':None}
return self._raw_frames[row][u'image'], u''
def get_frame_title(self, row=0):
"""
@ -384,9 +389,3 @@ class ServiceItem(object):
Returns the title of the raw frame
"""
return self._raw_frames[row][u'path']
def clear_cache(self):
"""
Clear's the service item's cache.
"""
self.cache = {}

View File

@ -58,34 +58,6 @@ class SettingsManager(object):
self.mainwindow_left + self.mainwindow_right) - 100 ) / 2
self.slidecontroller_image = self.slidecontroller - 50
def get_preview_visibility(self):
"""
Return the preview panel's visibility.
"""
return QtCore.QSettings().value(u'user interface/preview panel',
QtCore.QVariant(True)).toBool()
def set_preview_visibility(self, visible):
"""
Set the preview panel's visibility.
"""
QtCore.QSettings().setValue(u'user interface/preview panel',
QtCore.QVariant(visible))
def get_live_visibility(self):
"""
Return the live panel's visibility.
"""
return QtCore.QSettings().value(u'user interface/live panel',
QtCore.QVariant(True)).toBool()
def set_live_visibility(self, visible):
"""
Set the live panel's visibility.
"""
QtCore.QSettings().setValue(u'user interface/live panel',
QtCore.QVariant(visible))
@staticmethod
def get_last_dir(section, num=None):
"""
@ -206,4 +178,4 @@ class SettingsManager(object):
if extension == os.path.splitext(filename)[1]]
else:
# no filtering required
return files
return files

View File

@ -88,4 +88,4 @@ class SettingsTab(QtGui.QWidget):
"""
Changes which need to be made after setup of application
"""
pass
pass

View File

@ -55,7 +55,6 @@ BLANK_THEME_XML = \
<proportion>30</proportion>
<weight>Normal</weight>
<italics>False</italics>
<indentation>0</indentation>
<line_adjustment>0</line_adjustment>
<location override="False" x="10" y="10" width="1004" height="730"/>
</font>
@ -65,7 +64,6 @@ BLANK_THEME_XML = \
<proportion>12</proportion>
<weight>Normal</weight>
<italics>False</italics>
<indentation>0</indentation>
<line_adjustment>0</line_adjustment>
<location override="False" x="10" y="730" width="1004" height="38"/>
</font>
@ -184,7 +182,7 @@ class ThemeXML(object):
self.child_element(background, u'filename', filename)
def add_font(self, name, color, proportion, override, fonttype=u'main',
weight=u'Normal', italics=u'False', indentation=0, line_adjustment=0,
weight=u'Normal', italics=u'False', line_adjustment=0,
xpos=0, ypos=0, width=0, height=0):
"""
Add a Font.
@ -210,9 +208,6 @@ class ThemeXML(object):
``italics``
Does the font render to italics Defaults to 0 Normal
``indentation``
Number of characters the wrap line is indented
``xpos``
The X position of the text block.
@ -239,8 +234,6 @@ class ThemeXML(object):
#Create italics name element
self.child_element(background, u'italics', italics)
#Create indentation name element
self.child_element(background, u'indentation', unicode(indentation))
#Create indentation name element
self.child_element(
background, u'line_adjustment', unicode(line_adjustment))
@ -415,4 +408,4 @@ class ThemeXML(object):
for key in dir(self):
if key[0:1] != u'_':
theme_strings.append(u'%30s: %s' % (key, getattr(self, key)))
return u'\n'.join(theme_strings)
return u'\n'.join(theme_strings)

View File

@ -154,4 +154,4 @@ class OpenLPToolbar(QtGui.QToolBar):
push_button.setCheckable(True)
push_button.setFlat(True)
self.addWidget(push_button)
return push_button
return push_button

View File

@ -24,4 +24,4 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from openlp.core.theme.theme import Theme
from openlp.core.theme.theme import Theme

View File

@ -204,7 +204,7 @@ class Theme(object):
val = element_text
if (element.tag.find(u'Color') > 0 or
(element.tag.find(u'BackgroundParameter') == 0 and
isinstance(int, val))):
isinstance(val, int))):
# convert to a wx.Colour
if not delphi_color_change:
val = QtGui.QColor(
@ -222,4 +222,4 @@ class Theme(object):
for key in dir(self):
if key[0:1] != u'_':
theme_strings.append(u'%30s : %s' % (key, getattr(self, key)))
return u'\n'.join(theme_strings)
return u'\n'.join(theme_strings)

View File

@ -27,6 +27,141 @@
The :mod:`ui` module provides the core user interface for OpenLP
"""
# http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/
import re
import sys
try:
import enchant
enchant_available = True
except ImportError:
enchant_available = False
from PyQt4 import QtCore, QtGui
from openlp.core.lib import html_expands, translate, context_menu_action
class SpellTextEdit(QtGui.QPlainTextEdit):
def __init__(self, *args):
QtGui.QPlainTextEdit.__init__(self, *args)
# Default dictionary based on the current locale.
if enchant_available:
self.dict = enchant.Dict()
self.highlighter = Highlighter(self.document())
self.highlighter.setDict(self.dict)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.RightButton:
# Rewrite the mouse event to a left button event so the cursor is
# moved to the location of the pointer.
event = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress,
event.pos(), QtCore.Qt.LeftButton, QtCore.Qt.LeftButton,
QtCore.Qt.NoModifier)
QtGui.QPlainTextEdit.mousePressEvent(self, event)
def contextMenuEvent(self, event):
popup_menu = self.createStandardContextMenu()
# Select the word under the cursor.
cursor = self.textCursor()
cursor.select(QtGui.QTextCursor.WordUnderCursor)
self.setTextCursor(cursor)
# Check if the selected word is misspelled and offer spelling
# suggestions if it is.
if enchant_available and self.textCursor().hasSelection():
text = unicode(self.textCursor().selectedText())
if not self.dict.check(text):
spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
'Spelling Suggestions'))
for word in self.dict.suggest(text):
action = SpellAction(word, spell_menu)
action.correct.connect(self.correctWord)
spell_menu.addAction(action)
# Only add the spelling suggests to the menu if there are
# suggestions.
if len(spell_menu.actions()) != 0:
popup_menu.insertSeparator(popup_menu.actions()[0])
popup_menu.insertMenu(popup_menu.actions()[0], spell_menu)
tag_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
'Formatting Tags'))
for html in html_expands:
action = SpellAction( html[u'desc'], tag_menu)
action.correct.connect(self.htmlTag)
tag_menu.addAction(action)
popup_menu.insertSeparator(popup_menu.actions()[0])
popup_menu.insertMenu(popup_menu.actions()[0], tag_menu)
popup_menu.exec_(event.globalPos())
def correctWord(self, word):
"""
Replaces the selected text with word.
"""
cursor = self.textCursor()
cursor.beginEditBlock()
cursor.removeSelectedText()
cursor.insertText(word)
cursor.endEditBlock()
def htmlTag(self, tag):
"""
Replaces the selected text with word.
"""
for html in html_expands:
if tag == html[u'desc']:
cursor = self.textCursor()
if self.textCursor().hasSelection():
text = cursor.selectedText()
cursor.beginEditBlock()
cursor.removeSelectedText()
cursor.insertText(html[u'start tag'])
cursor.insertText(text)
cursor.insertText(html[u'end tag'])
cursor.endEditBlock()
else:
cursor = self.textCursor()
cursor.insertText(html[u'start tag'])
cursor.insertText(html[u'end tag'])
class Highlighter(QtGui.QSyntaxHighlighter):
WORDS = u'(?iu)[\w\']+'
def __init__(self, *args):
QtGui.QSyntaxHighlighter.__init__(self, *args)
self.dict = None
def setDict(self, dict):
self.dict = dict
def highlightBlock(self, text):
if not self.dict:
return
text = unicode(text)
format = QtGui.QTextCharFormat()
format.setUnderlineColor(QtCore.Qt.red)
format.setUnderlineStyle(QtGui.QTextCharFormat.SpellCheckUnderline)
for word_object in re.finditer(self.WORDS, text):
if not self.dict.check(word_object.group()):
self.setFormat(word_object.start(),
word_object.end() - word_object.start(), format)
class SpellAction(QtGui.QAction):
"""
A special QAction that returns the text in a signal.
"""
correct = QtCore.pyqtSignal(unicode)
def __init__(self, *args):
QtGui.QAction.__init__(self, *args)
self.triggered.connect(lambda x: self.correct.emit(
unicode(self.text())))
class HideMode(object):
"""
This is basically an enumeration class which specifies the mode of a Bible.
@ -37,13 +172,11 @@ class HideMode(object):
Theme = 2
Screen = 3
from maindisplay import MainDisplay
from slidecontroller import HideMode
from servicenoteform import ServiceNoteForm
from serviceitemeditform import ServiceItemEditForm
from screen import ScreenList
from maindisplay import MainDisplay
from maindisplay import VideoDisplay
from maindisplay import DisplayManager
from amendthemeform import AmendThemeForm
from slidecontroller import SlideController
from splashscreen import SplashScreen
@ -56,8 +189,7 @@ from settingsform import SettingsForm
from mediadockmanager import MediaDockManager
from servicemanager import ServiceManager
from thememanager import ThemeManager
from mainwindow import MainWindow
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainWindow',
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm',
'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeManager',
'AmendThemeForm', 'MediaDockManager', 'ServiceItemEditForm']
'AmendThemeForm', 'MediaDockManager', 'ServiceItemEditForm']

View File

@ -562,5 +562,6 @@ class Ui_AboutDialog(object):
self.aboutNotebook.setTabText(
self.aboutNotebook.indexOf(self.licenseTab),
translate('OpenLP.AboutForm', 'License'))
self.contributeButton.setText(translate('OpenLP.AboutForm', 'Contribute'))
self.contributeButton.setText(translate('OpenLP.AboutForm',
'Contribute'))
self.closeButton.setText(translate('OpenLP.AboutForm', 'Close'))

View File

@ -61,4 +61,4 @@ class AboutForm(QtGui.QDialog, Ui_AboutDialog):
import webbrowser
url = u'http://www.openlp.org/en/documentation/introduction/' \
+ u'contributing.html'
webbrowser.open_new(url)
webbrowser.open_new(url)

View File

@ -134,7 +134,8 @@ class AdvancedTab(SettingsTab):
"""
self.uiGroupBox.setTitle(translate('OpenLP.AdvancedTab', 'UI Settings'))
self.recentLabel.setText(
translate('OpenLP.AdvancedTab', 'Number of recent files to display:'))
translate('OpenLP.AdvancedTab',
'Number of recent files to display:'))
self.mediaPluginCheckBox.setText(translate('OpenLP.AdvancedTab',
'Remember active media manager tab on startup'))
self.doubleClickLiveCheckBox.setText(translate('OpenLP.AdvancedTab',
@ -188,4 +189,4 @@ class AdvancedTab(SettingsTab):
"""
self.sharedLabel.setEnabled(checked)
self.sharedTextEdit.setEnabled(checked)
self.sharedPushButton.setEnabled(checked)
self.sharedPushButton.setEnabled(checked)

File diff suppressed because it is too large Load Diff

View File

@ -50,131 +50,121 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.path = None
self.theme = ThemeXML()
self.setupUi(self)
# define signals
# Buttons
QtCore.QObject.connect(self.Color1PushButton,
QtCore.QObject.connect(self.color1PushButton,
QtCore.SIGNAL(u'pressed()'), self.onColor1PushButtonClicked)
QtCore.QObject.connect(self.Color2PushButton,
QtCore.QObject.connect(self.color2PushButton,
QtCore.SIGNAL(u'pressed()'), self.onColor2PushButtonClicked)
QtCore.QObject.connect(self.FontMainColorPushButton,
QtCore.QObject.connect(self.fontMainColorPushButton,
QtCore.SIGNAL(u'pressed()'), self.onFontMainColorPushButtonClicked)
QtCore.QObject.connect(self.FontFooterColorPushButton,
QtCore.QObject.connect(self.fontFooterColorPushButton,
QtCore.SIGNAL(u'pressed()'),
self.onFontFooterColorPushButtonClicked)
QtCore.QObject.connect(self.OutlineColorPushButton,
QtCore.QObject.connect(self.outlineColorPushButton,
QtCore.SIGNAL(u'pressed()'), self.onOutlineColorPushButtonClicked)
QtCore.QObject.connect(self.ShadowColorPushButton,
QtCore.QObject.connect(self.shadowColorPushButton,
QtCore.SIGNAL(u'pressed()'), self.onShadowColorPushButtonClicked)
QtCore.QObject.connect(self.ImageToolButton,
QtCore.QObject.connect(self.imageToolButton,
QtCore.SIGNAL(u'clicked()'), self.onImageToolButtonClicked)
# Combo boxes
QtCore.QObject.connect(self.BackgroundComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onBackgroundComboBoxSelected)
QtCore.QObject.connect(self.BackgroundTypeComboBox,
QtCore.QObject.connect(self.backgroundTypeComboBox,
QtCore.SIGNAL(u'activated(int)'),
self.onBackgroundTypeComboBoxSelected)
QtCore.QObject.connect(self.GradientComboBox,
QtCore.QObject.connect(self.gradientComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onGradientComboBoxSelected)
QtCore.QObject.connect(self.FontMainComboBox,
QtCore.QObject.connect(self.fontMainComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontMainComboBoxSelected)
QtCore.QObject.connect(self.FontMainWeightComboBox,
QtCore.QObject.connect(self.fontMainWeightComboBox,
QtCore.SIGNAL(u'activated(int)'),
self.onFontMainWeightComboBoxSelected)
QtCore.QObject.connect(self.FontFooterComboBox,
QtCore.QObject.connect(self.fontFooterComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontFooterComboBoxSelected)
QtCore.QObject.connect(self.FontFooterWeightComboBox,
QtCore.QObject.connect(self.fontFooterWeightComboBox,
QtCore.SIGNAL(u'activated(int)'),
self.onFontFooterWeightComboBoxSelected)
QtCore.QObject.connect(self.HorizontalComboBox,
QtCore.QObject.connect(self.horizontalComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onHorizontalComboBoxSelected)
QtCore.QObject.connect(self.VerticalComboBox,
QtCore.QObject.connect(self.verticalComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onVerticalComboBoxSelected)
# Spin boxes
QtCore.QObject.connect(self.FontMainSizeSpinBox,
QtCore.QObject.connect(self.fontMainSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainSizeSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterSizeSpinBox,
QtCore.QObject.connect(self.fontFooterSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterSizeSpinBoxChanged)
QtCore.QObject.connect(self.FontMainXSpinBox,
QtCore.QObject.connect(self.fontMainXSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontMainXSpinBoxChanged)
QtCore.QObject.connect(self.FontMainYSpinBox,
QtCore.QObject.connect(self.fontMainYSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontMainYSpinBoxChanged)
QtCore.QObject.connect(self.FontMainWidthSpinBox,
QtCore.QObject.connect(self.fontMainWidthSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainWidthSpinBoxChanged)
QtCore.QObject.connect(self.FontMainHeightSpinBox,
QtCore.QObject.connect(self.fontMainHeightSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainHeightSpinBoxChanged)
QtCore.QObject.connect(self.FontMainLineAdjustmentSpinBox,
QtCore.QObject.connect(self.fontMainLineAdjustmentSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainLineAdjustmentSpinBoxChanged)
QtCore.QObject.connect(self.FontMainLineSpacingSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainLineSpacingSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterXSpinBox,
QtCore.QObject.connect(self.fontFooterXSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterXSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterYSpinBox,
QtCore.QObject.connect(self.fontFooterYSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterYSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterWidthSpinBox,
QtCore.QObject.connect(self.fontFooterWidthSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterWidthSpinBoxChanged)
QtCore.QObject.connect(self.FontFooterHeightSpinBox,
QtCore.QObject.connect(self.fontFooterHeightSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterHeightSpinBoxChanged)
QtCore.QObject.connect(self.ShadowSpinBox,
QtCore.QObject.connect(self.shadowSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onShadowSpinBoxChanged)
QtCore.QObject.connect(self.OutlineSpinBox,
QtCore.QObject.connect(self.outlineSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onOutlineSpinBoxChanged)
# CheckBoxes
QtCore.QObject.connect(self.FontMainDefaultCheckBox,
QtCore.QObject.connect(self.fontMainDefaultCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onFontMainDefaultCheckBoxChanged)
QtCore.QObject.connect(self.FontFooterDefaultCheckBox,
QtCore.QObject.connect(self.fontFooterDefaultCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onFontFooterDefaultCheckBoxChanged)
QtCore.QObject.connect(self.OutlineCheckBox,
QtCore.QObject.connect(self.outlineCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onOutlineCheckBoxChanged)
QtCore.QObject.connect(self.ShadowCheckBox,
QtCore.QObject.connect(self.shadowCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onShadowCheckBoxChanged)
QtCore.QObject.connect(self.SlideTransitionCheckBox,
QtCore.QObject.connect(self.slideTransitionCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onSlideTransitionCheckBoxChanged)
def accept(self):
new_theme = ThemeXML()
theme_name = unicode(self.ThemeNameEdit.text())
theme_name = unicode(self.themeNameEdit.text())
new_theme.new_document(theme_name)
save_from = None
save_to = None
if self.theme.background_mode == u'transparent':
new_theme.add_background_transparent()
if self.theme.background_type == u'solid':
new_theme.add_background_solid(
unicode(self.theme.background_color))
elif self.theme.background_type == u'gradient':
new_theme.add_background_gradient(
unicode(self.theme.background_startColor),
unicode(self.theme.background_endColor),
self.theme.background_direction)
else:
if self.theme.background_type == u'solid':
new_theme.add_background_solid(
unicode(self.theme.background_color))
elif self.theme.background_type == u'gradient':
new_theme.add_background_gradient(
unicode(self.theme.background_startColor),
unicode(self.theme.background_endColor),
self.theme.background_direction)
else:
filename = \
os.path.split(unicode(self.theme.background_filename))[1]
new_theme.add_background_image(filename)
save_to = os.path.join(self.path, theme_name, filename)
save_from = self.theme.background_filename
filename = \
os.path.split(unicode(self.theme.background_filename))[1]
new_theme.add_background_image(filename)
save_to = os.path.join(self.path, theme_name, filename)
save_from = self.theme.background_filename
new_theme.add_font(unicode(self.theme.font_main_name),
unicode(self.theme.font_main_color),
unicode(self.theme.font_main_proportion),
unicode(self.theme.font_main_override), u'main',
unicode(self.theme.font_main_weight),
unicode(self.theme.font_main_italics),
unicode(self.theme.font_main_indentation),
unicode(self.theme.font_main_line_adjustment),
unicode(self.theme.font_main_x),
unicode(self.theme.font_main_y),
@ -186,7 +176,6 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
unicode(self.theme.font_footer_override), u'footer',
unicode(self.theme.font_footer_weight),
unicode(self.theme.font_footer_italics),
0, # indentation
0, # line adjustment
unicode(self.theme.font_footer_x),
unicode(self.theme.font_footer_y),
@ -222,17 +211,18 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
images_filter = '%s;;%s (*.*) (*)' % (images_filter,
translate('OpenLP.AmendThemeForm', 'All Files'))
filename = QtGui.QFileDialog.getOpenFileName(self,
translate('OpenLP.AmendThemeForm', 'Select Image'), u'', images_filter)
translate('OpenLP.AmendThemeForm', 'Select Image'), u'',
images_filter)
if filename:
self.ImageLineEdit.setText(filename)
self.imageLineEdit.setText(filename)
self.theme.background_filename = filename
self.previewTheme()
#
#Main Font Tab
# Main Font Tab
#
def onFontMainComboBoxSelected(self):
self.theme.font_main_name = self.FontMainComboBox.currentFont().family()
self.theme.font_main_name = self.fontMainComboBox.currentFont().family()
self.previewTheme()
def onFontMainWeightComboBoxSelected(self, value):
@ -255,13 +245,13 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtGui.QColor(self.theme.font_main_color), self)
if new_color.isValid():
self.theme.font_main_color = new_color.name()
self.FontMainColorPushButton.setStyleSheet(
self.fontMainColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(self.theme.font_main_color))
self.previewTheme()
def onFontMainSizeSpinBoxChanged(self):
if self.theme.font_main_proportion != self.FontMainSizeSpinBox.value():
self.theme.font_main_proportion = self.FontMainSizeSpinBox.value()
if self.theme.font_main_proportion != self.fontMainSizeSpinBox.value():
self.theme.font_main_proportion = self.fontMainSizeSpinBox.value()
self.previewTheme()
def onFontMainDefaultCheckBoxChanged(self, value):
@ -276,57 +266,48 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.theme.font_main_y = u'10'
self.theme.font_main_width = u'1024'
self.theme.font_main_height = u'730'
self.FontMainXSpinBox.setValue(self.theme.font_main_x)
self.FontMainYSpinBox.setValue(self.theme.font_main_y)
self.FontMainWidthSpinBox.setValue(self.theme.font_main_width)
self.FontMainHeightSpinBox.setValue(self.theme.font_main_height)
self.FontMainLineAdjustmentSpinBox.setValue(
self.fontMainXSpinBox.setValue(self.theme.font_main_x)
self.fontMainYSpinBox.setValue(self.theme.font_main_y)
self.fontMainWidthSpinBox.setValue(self.theme.font_main_width)
self.fontMainHeightSpinBox.setValue(self.theme.font_main_height)
self.fontMainLineAdjustmentSpinBox.setValue(
self.theme.font_main_line_adjustment)
self.FontMainLineSpacingSpinBox.setValue(
self.theme.font_main_indentation)
self.stateChanging(self.theme)
self.previewTheme()
def onFontMainXSpinBoxChanged(self):
if self.theme.font_main_x != self.FontMainXSpinBox.value():
self.theme.font_main_x = self.FontMainXSpinBox.value()
if self.theme.font_main_x != self.fontMainXSpinBox.value():
self.theme.font_main_x = self.fontMainXSpinBox.value()
self.previewTheme()
def onFontMainYSpinBoxChanged(self):
if self.theme.font_main_y != self.FontMainYSpinBox.value():
self.theme.font_main_y = self.FontMainYSpinBox.value()
if self.theme.font_main_y != self.fontMainYSpinBox.value():
self.theme.font_main_y = self.fontMainYSpinBox.value()
self.previewTheme()
def onFontMainWidthSpinBoxChanged(self):
if self.theme.font_main_width != self.FontMainWidthSpinBox.value():
self.theme.font_main_width = self.FontMainWidthSpinBox.value()
if self.theme.font_main_width != self.fontMainWidthSpinBox.value():
self.theme.font_main_width = self.fontMainWidthSpinBox.value()
self.previewTheme()
def onFontMainLineAdjustmentSpinBoxChanged(self):
if self.theme.font_main_line_adjustment != \
self.FontMainLineAdjustmentSpinBox.value():
self.fontMainLineAdjustmentSpinBox.value():
self.theme.font_main_line_adjustment = \
self.FontMainLineAdjustmentSpinBox.value()
self.previewTheme()
def onFontMainLineSpacingSpinBoxChanged(self):
if self.theme.font_main_indentation != \
self.FontMainLineSpacingSpinBox.value():
self.theme.font_main_indentation = \
self.FontMainLineSpacingSpinBox.value()
self.fontMainLineAdjustmentSpinBox.value()
self.previewTheme()
def onFontMainHeightSpinBoxChanged(self):
if self.theme.font_main_height != self.FontMainHeightSpinBox.value():
self.theme.font_main_height = self.FontMainHeightSpinBox.value()
if self.theme.font_main_height != self.fontMainHeightSpinBox.value():
self.theme.font_main_height = self.fontMainHeightSpinBox.value()
self.previewTheme()
#
#Footer Font Tab
# Footer Font Tab
#
def onFontFooterComboBoxSelected(self):
self.theme.font_footer_name = \
self.FontFooterComboBox.currentFont().family()
self.fontFooterComboBox.currentFont().family()
self.previewTheme()
def onFontFooterWeightComboBoxSelected(self, value):
@ -349,15 +330,15 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtGui.QColor(self.theme.font_footer_color), self)
if new_color.isValid():
self.theme.font_footer_color = new_color.name()
self.FontFooterColorPushButton.setStyleSheet(
self.fontFooterColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(self.theme.font_footer_color))
self.previewTheme()
def onFontFooterSizeSpinBoxChanged(self):
if self.theme.font_footer_proportion != \
self.FontFooterSizeSpinBox.value():
self.fontFooterSizeSpinBox.value():
self.theme.font_footer_proportion = \
self.FontFooterSizeSpinBox.value()
self.fontFooterSizeSpinBox.value()
self.previewTheme()
def onFontFooterDefaultCheckBoxChanged(self, value):
@ -372,60 +353,52 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.theme.font_footer_y = u'730'
self.theme.font_footer_width = u'1024'
self.theme.font_footer_height = u'38'
self.FontFooterXSpinBox.setValue(self.theme.font_footer_x)
self.FontFooterYSpinBox.setValue(self.theme.font_footer_y)
self.FontFooterWidthSpinBox.setValue(self.theme.font_footer_width)
self.FontFooterHeightSpinBox.setValue(
self.fontFooterXSpinBox.setValue(self.theme.font_footer_x)
self.fontFooterYSpinBox.setValue(self.theme.font_footer_y)
self.fontFooterWidthSpinBox.setValue(self.theme.font_footer_width)
self.fontFooterHeightSpinBox.setValue(
self.theme.font_footer_height)
self.stateChanging(self.theme)
self.previewTheme()
def onFontFooterXSpinBoxChanged(self):
if self.theme.font_footer_x != self.FontFooterXSpinBox.value():
self.theme.font_footer_x = self.FontFooterXSpinBox.value()
if self.theme.font_footer_x != self.fontFooterXSpinBox.value():
self.theme.font_footer_x = self.fontFooterXSpinBox.value()
self.previewTheme()
def onFontFooterYSpinBoxChanged(self):
if self.theme.font_footer_y != self.FontFooterYSpinBox.value():
self.theme.font_footer_y = self.FontFooterYSpinBox.value()
if self.theme.font_footer_y != self.fontFooterYSpinBox.value():
self.theme.font_footer_y = self.fontFooterYSpinBox.value()
self.previewTheme()
def onFontFooterWidthSpinBoxChanged(self):
if self.theme.font_footer_width != self.FontFooterWidthSpinBox.value():
self.theme.font_footer_width = self.FontFooterWidthSpinBox.value()
if self.theme.font_footer_width != self.fontFooterWidthSpinBox.value():
self.theme.font_footer_width = self.fontFooterWidthSpinBox.value()
self.previewTheme()
def onFontFooterHeightSpinBoxChanged(self):
if self.theme.font_footer_height != \
self.FontFooterHeightSpinBox.value():
self.fontFooterHeightSpinBox.value():
self.theme.font_footer_height = \
self.FontFooterHeightSpinBox.value()
self.fontFooterHeightSpinBox.value()
self.previewTheme()
#
#Background Tab
# Background Tab
#
def onGradientComboBoxSelected(self, currentIndex):
self.setBackground(self.BackgroundTypeComboBox.currentIndex(),
self.setBackground(self.backgroundTypeComboBox.currentIndex(),
currentIndex)
def onBackgroundComboBoxSelected(self, currentIndex):
if currentIndex == 0: # Opaque
self.theme.background_mode = u'opaque'
else:
self.theme.background_mode = u'transparent'
self.stateChanging(self.theme)
self.previewTheme()
def onBackgroundTypeComboBoxSelected(self, currentIndex):
self.setBackground(currentIndex, self.GradientComboBox.currentIndex())
self.setBackground(currentIndex, self.gradientComboBox.currentIndex())
def setBackground(self, background, gradient):
if background == 0: # Solid
self.theme.background_type = u'solid'
if self.theme.background_color is None:
self.theme.background_color = u'#000000'
self.ImageLineEdit.setText(u'')
self.imageLineEdit.setText(u'')
elif background == 1: # Gradient
self.theme.background_type = u'gradient'
if gradient == 0: # Horizontal
@ -438,7 +411,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.theme.background_startColor = u'#000000'
if self.theme.background_endColor is None:
self.theme.background_endColor = u'#ff0000'
self.ImageLineEdit.setText(u'')
self.imageLineEdit.setText(u'')
else:
self.theme.background_type = u'image'
self.stateChanging(self.theme)
@ -450,14 +423,14 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtGui.QColor(self.theme.background_color), self)
if new_color.isValid():
self.theme.background_color = new_color.name()
self.Color1PushButton.setStyleSheet(u'background-color: %s' %
self.color1PushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.background_color))
else:
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.background_startColor), self)
if new_color.isValid():
self.theme.background_startColor = new_color.name()
self.Color1PushButton.setStyleSheet(u'background-color: %s' %
self.color1PushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.background_startColor))
self.previewTheme()
@ -466,12 +439,12 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtGui.QColor(self.theme.background_endColor), self)
if new_color.isValid():
self.theme.background_endColor = new_color.name()
self.Color2PushButton.setStyleSheet(u'background-color: %s' %
self.color2PushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.background_endColor))
self.previewTheme()
#
#Other Tab
# Other Tab
#
def onOutlineCheckBoxChanged(self, value):
if value == 2: # checked
@ -482,13 +455,13 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.previewTheme()
def onOutlineSpinBoxChanged(self):
if self.theme.display_outline_size != self.OutlineSpinBox.value():
self.theme.display_outline_size = self.OutlineSpinBox.value()
if self.theme.display_outline_size != self.outlineSpinBox.value():
self.theme.display_outline_size = self.outlineSpinBox.value()
self.previewTheme()
def onShadowSpinBoxChanged(self):
if self.theme.display_shadow_size != self.ShadowSpinBox.value():
self.theme.display_shadow_size = self.ShadowSpinBox.value()
if self.theme.display_shadow_size != self.shadowSpinBox.value():
self.theme.display_shadow_size = self.shadowSpinBox.value()
self.previewTheme()
def onOutlineColorPushButtonClicked(self):
@ -496,7 +469,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtGui.QColor(self.theme.display_outline_color), self)
if new_color.isValid():
self.theme.display_outline_color = new_color.name()
self.OutlineColorPushButton.setStyleSheet(u'background-color: %s' %
self.outlineColorPushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.display_outline_color))
self.previewTheme()
@ -521,7 +494,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtGui.QColor(self.theme.display_shadow_color), self)
if new_color.isValid():
self.theme.display_shadow_color = new_color.name()
self.ShadowColorPushButton.setStyleSheet(u'background-color: %s' %
self.shadowColorPushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.display_shadow_color))
self.previewTheme()
@ -536,198 +509,179 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.previewTheme()
#
#Local Methods
# Local Methods
#
def paintUi(self, theme):
self.stateChanging(theme)
self.ThemeNameEdit.setText(self.theme.theme_name)
self.themeNameEdit.setText(self.theme.theme_name)
# Background Tab
if self.theme.background_mode == u'opaque':
self.BackgroundComboBox.setCurrentIndex(0)
else:
self.BackgroundComboBox.setCurrentIndex(1)
self.ImageLineEdit.setText(u'')
self.imageLineEdit.setText(u'')
if theme.background_type == u'solid':
self.BackgroundTypeComboBox.setCurrentIndex(0)
self.backgroundTypeComboBox.setCurrentIndex(0)
elif theme.background_type == u'gradient':
self.BackgroundTypeComboBox.setCurrentIndex(1)
self.backgroundTypeComboBox.setCurrentIndex(1)
else:
self.BackgroundTypeComboBox.setCurrentIndex(2)
self.ImageLineEdit.setText(self.theme.background_filename)
self.backgroundTypeComboBox.setCurrentIndex(2)
self.imageLineEdit.setText(self.theme.background_filename)
if self.theme.background_direction == u'horizontal':
self.GradientComboBox.setCurrentIndex(0)
self.gradientComboBox.setCurrentIndex(0)
elif self.theme.background_direction == u'vertical':
self.GradientComboBox.setCurrentIndex(1)
self.gradientComboBox.setCurrentIndex(1)
else:
self.GradientComboBox.setCurrentIndex(2)
self.gradientComboBox.setCurrentIndex(2)
# Font Main Tab
self.FontMainComboBox.setCurrentFont(
self.fontMainComboBox.setCurrentFont(
QtGui.QFont(self.theme.font_main_name))
self.FontMainSizeSpinBox.setValue(self.theme.font_main_proportion)
self.fontMainSizeSpinBox.setValue(self.theme.font_main_proportion)
if not self.theme.font_main_italics and \
self.theme.font_main_weight == u'Normal':
self.FontMainWeightComboBox.setCurrentIndex(0)
self.fontMainWeightComboBox.setCurrentIndex(0)
elif not self.theme.font_main_italics and \
self.theme.font_main_weight == u'Bold':
self.FontMainWeightComboBox.setCurrentIndex(1)
self.fontMainWeightComboBox.setCurrentIndex(1)
elif self.theme.font_main_italics and \
self.theme.font_main_weight == u'Normal':
self.FontMainWeightComboBox.setCurrentIndex(2)
self.fontMainWeightComboBox.setCurrentIndex(2)
else:
self.FontMainWeightComboBox.setCurrentIndex(3)
self.FontMainLineSpacingSpinBox.setValue(
self.theme.font_main_indentation)
self.FontMainXSpinBox.setValue(self.theme.font_main_x)
self.FontMainYSpinBox.setValue(self.theme.font_main_y)
self.FontMainWidthSpinBox.setValue(self.theme.font_main_width)
self.FontMainHeightSpinBox.setValue(self.theme.font_main_height)
self.fontMainWeightComboBox.setCurrentIndex(3)
self.fontMainXSpinBox.setValue(self.theme.font_main_x)
self.fontMainYSpinBox.setValue(self.theme.font_main_y)
self.fontMainWidthSpinBox.setValue(self.theme.font_main_width)
self.fontMainHeightSpinBox.setValue(self.theme.font_main_height)
# Font Footer Tab
self.FontFooterComboBox.setCurrentFont(
self.fontFooterComboBox.setCurrentFont(
QtGui.QFont(self.theme.font_footer_name))
self.FontFooterSizeSpinBox.setValue(
self.fontFooterSizeSpinBox.setValue(
self.theme.font_footer_proportion)
if not self.theme.font_footer_italics and \
self.theme.font_footer_weight == u'Normal':
self.FontFooterWeightComboBox.setCurrentIndex(0)
self.fontFooterWeightComboBox.setCurrentIndex(0)
elif not self.theme.font_footer_italics and \
self.theme.font_footer_weight == u'Bold':
self.FontFooterWeightComboBox.setCurrentIndex(1)
self.fontFooterWeightComboBox.setCurrentIndex(1)
elif self.theme.font_footer_italics and \
self.theme.font_footer_weight == u'Normal':
self.FontFooterWeightComboBox.setCurrentIndex(2)
self.fontFooterWeightComboBox.setCurrentIndex(2)
else:
self.FontFooterWeightComboBox.setCurrentIndex(3)
self.FontFooterXSpinBox.setValue(self.theme.font_footer_x)
self.FontFooterYSpinBox.setValue(self.theme.font_footer_y)
self.FontFooterWidthSpinBox.setValue(self.theme.font_footer_width)
self.FontFooterHeightSpinBox.setValue(self.theme.font_footer_height)
self.FontMainColorPushButton.setStyleSheet(
self.fontFooterWeightComboBox.setCurrentIndex(3)
self.fontFooterXSpinBox.setValue(self.theme.font_footer_x)
self.fontFooterYSpinBox.setValue(self.theme.font_footer_y)
self.fontFooterWidthSpinBox.setValue(self.theme.font_footer_width)
self.fontFooterHeightSpinBox.setValue(self.theme.font_footer_height)
self.fontMainColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.font_main_color))
self.FontFooterColorPushButton.setStyleSheet(
self.fontFooterColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.font_footer_color))
if not self.theme.font_main_override:
self.FontMainDefaultCheckBox.setChecked(True)
self.fontMainDefaultCheckBox.setChecked(True)
else:
self.FontMainDefaultCheckBox.setChecked(False)
self.fontMainDefaultCheckBox.setChecked(False)
if not self.theme.font_footer_override:
self.FontFooterDefaultCheckBox.setChecked(True)
self.fontFooterDefaultCheckBox.setChecked(True)
else:
self.FontFooterDefaultCheckBox.setChecked(False)
self.OutlineColorPushButton.setStyleSheet(
self.fontFooterDefaultCheckBox.setChecked(False)
self.outlineColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.display_outline_color))
self.ShadowColorPushButton.setStyleSheet(
self.shadowColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.display_shadow_color))
if self.theme.display_outline:
self.OutlineCheckBox.setChecked(True)
self.OutlineColorPushButton.setEnabled(True)
self.outlineCheckBox.setChecked(True)
self.outlineColorPushButton.setEnabled(True)
else:
self.OutlineCheckBox.setChecked(False)
self.OutlineColorPushButton.setEnabled(False)
self.OutlineSpinBox.setValue(int(self.theme.display_outline_size))
self.outlineCheckBox.setChecked(False)
self.outlineColorPushButton.setEnabled(False)
self.outlineSpinBox.setValue(int(self.theme.display_outline_size))
if self.theme.display_shadow:
self.ShadowCheckBox.setChecked(True)
self.ShadowColorPushButton.setEnabled(True)
self.shadowCheckBox.setChecked(True)
self.shadowColorPushButton.setEnabled(True)
else:
self.ShadowCheckBox.setChecked(False)
self.ShadowColorPushButton.setEnabled(False)
self.ShadowSpinBox.setValue(int(self.theme.display_shadow_size))
self.shadowCheckBox.setChecked(False)
self.shadowColorPushButton.setEnabled(False)
self.shadowSpinBox.setValue(int(self.theme.display_shadow_size))
if self.theme.display_slideTransition:
self.SlideTransitionCheckBox.setCheckState(QtCore.Qt.Checked)
self.slideTransitionCheckBox.setCheckState(QtCore.Qt.Checked)
else:
self.SlideTransitionCheckBox.setCheckState(QtCore.Qt.Unchecked)
self.HorizontalComboBox.setCurrentIndex(
self.slideTransitionCheckBox.setCheckState(QtCore.Qt.Unchecked)
self.horizontalComboBox.setCurrentIndex(
self.theme.display_horizontalAlign)
self.VerticalComboBox.setCurrentIndex(self.theme.display_verticalAlign)
self.verticalComboBox.setCurrentIndex(self.theme.display_verticalAlign)
def stateChanging(self, theme):
if theme.background_mode == u'transparent':
self.Color1Label.setVisible(False)
self.Color1PushButton.setVisible(False)
self.Color2Label.setVisible(False)
self.Color2PushButton.setVisible(False)
self.ImageLabel.setVisible(False)
self.ImageLineEdit.setVisible(False)
self.ImageFilenameWidget.setVisible(False)
self.GradientLabel.setVisible(False)
self.GradientComboBox.setVisible(False)
self.BackgroundTypeComboBox.setVisible(False)
self.BackgroundTypeLabel.setVisible(False)
else:
self.BackgroundTypeComboBox.setVisible(True)
self.BackgroundTypeLabel.setVisible(True)
if theme.background_type == u'solid':
self.Color1PushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.background_color))
self.Color1Label.setText(
translate('OpenLP.AmendThemeForm', 'Color:'))
self.Color1Label.setVisible(True)
self.Color1PushButton.setVisible(True)
self.Color2Label.setVisible(False)
self.Color2PushButton.setVisible(False)
self.ImageLabel.setVisible(False)
self.ImageLineEdit.setVisible(False)
self.ImageFilenameWidget.setVisible(False)
self.GradientLabel.setVisible(False)
self.GradientComboBox.setVisible(False)
elif theme.background_type == u'gradient':
self.Color1PushButton.setStyleSheet(u'background-color: %s' \
% unicode(theme.background_startColor))
self.Color2PushButton.setStyleSheet(u'background-color: %s' \
% unicode(theme.background_endColor))
self.Color1Label.setText(
translate('OpenLP.AmendThemeForm', 'First color:'))
self.Color2Label.setText(
translate('OpenLP.AmendThemeForm', 'Second color:'))
self.Color1Label.setVisible(True)
self.Color1PushButton.setVisible(True)
self.Color2Label.setVisible(True)
self.Color2PushButton.setVisible(True)
self.ImageLabel.setVisible(False)
self.ImageLineEdit.setVisible(False)
self.ImageFilenameWidget.setVisible(False)
self.GradientLabel.setVisible(True)
self.GradientComboBox.setVisible(True)
else: # must be image
self.Color1Label.setVisible(False)
self.Color1PushButton.setVisible(False)
self.Color2Label.setVisible(False)
self.Color2PushButton.setVisible(False)
self.ImageLabel.setVisible(True)
self.ImageLineEdit.setVisible(True)
self.ImageFilenameWidget.setVisible(True)
self.GradientLabel.setVisible(False)
self.GradientComboBox.setVisible(False)
self.backgroundTypeComboBox.setVisible(True)
self.backgroundTypeLabel.setVisible(True)
if theme.background_type == u'solid':
self.color1PushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.background_color))
self.color1Label.setText(
translate('OpenLP.AmendThemeForm', 'Color:'))
self.color1Label.setVisible(True)
self.color1PushButton.setVisible(True)
self.color2Label.setVisible(False)
self.color2PushButton.setVisible(False)
self.imageLabel.setVisible(False)
self.imageLineEdit.setVisible(False)
self.imageFilenameWidget.setVisible(False)
self.gradientLabel.setVisible(False)
self.gradientComboBox.setVisible(False)
elif theme.background_type == u'gradient':
self.color1PushButton.setStyleSheet(u'background-color: %s' \
% unicode(theme.background_startColor))
self.color2PushButton.setStyleSheet(u'background-color: %s' \
% unicode(theme.background_endColor))
self.color1Label.setText(
translate('OpenLP.AmendThemeForm', 'First color:'))
self.color2Label.setText(
translate('OpenLP.AmendThemeForm', 'Second color:'))
self.color1Label.setVisible(True)
self.color1PushButton.setVisible(True)
self.color2Label.setVisible(True)
self.color2PushButton.setVisible(True)
self.imageLabel.setVisible(False)
self.imageLineEdit.setVisible(False)
self.imageFilenameWidget.setVisible(False)
self.gradientLabel.setVisible(True)
self.gradientComboBox.setVisible(True)
else: # must be image
self.color1Label.setVisible(False)
self.color1PushButton.setVisible(False)
self.color2Label.setVisible(False)
self.color2PushButton.setVisible(False)
self.imageLabel.setVisible(True)
self.imageLineEdit.setVisible(True)
self.imageFilenameWidget.setVisible(True)
self.gradientLabel.setVisible(False)
self.gradientComboBox.setVisible(False)
if not theme.font_main_override:
self.FontMainXSpinBox.setEnabled(False)
self.FontMainYSpinBox.setEnabled(False)
self.FontMainWidthSpinBox.setEnabled(False)
self.FontMainHeightSpinBox.setEnabled(False)
self.fontMainXSpinBox.setEnabled(False)
self.fontMainYSpinBox.setEnabled(False)
self.fontMainWidthSpinBox.setEnabled(False)
self.fontMainHeightSpinBox.setEnabled(False)
else:
self.FontMainXSpinBox.setEnabled(True)
self.FontMainYSpinBox.setEnabled(True)
self.FontMainWidthSpinBox.setEnabled(True)
self.FontMainHeightSpinBox.setEnabled(True)
self.fontMainXSpinBox.setEnabled(True)
self.fontMainYSpinBox.setEnabled(True)
self.fontMainWidthSpinBox.setEnabled(True)
self.fontMainHeightSpinBox.setEnabled(True)
if not theme.font_footer_override:
self.FontFooterXSpinBox.setEnabled(False)
self.FontFooterYSpinBox.setEnabled(False)
self.FontFooterWidthSpinBox.setEnabled(False)
self.FontFooterHeightSpinBox.setEnabled(False)
self.fontFooterXSpinBox.setEnabled(False)
self.fontFooterYSpinBox.setEnabled(False)
self.fontFooterWidthSpinBox.setEnabled(False)
self.fontFooterHeightSpinBox.setEnabled(False)
else:
self.FontFooterXSpinBox.setEnabled(True)
self.FontFooterYSpinBox.setEnabled(True)
self.FontFooterWidthSpinBox.setEnabled(True)
self.FontFooterHeightSpinBox.setEnabled(True)
self.fontFooterXSpinBox.setEnabled(True)
self.fontFooterYSpinBox.setEnabled(True)
self.fontFooterWidthSpinBox.setEnabled(True)
self.fontFooterHeightSpinBox.setEnabled(True)
if self.theme.display_outline:
self.OutlineColorPushButton.setEnabled(True)
self.outlineColorPushButton.setEnabled(True)
else:
self.OutlineColorPushButton.setEnabled(False)
self.outlineColorPushButton.setEnabled(False)
if self.theme.display_shadow:
self.ShadowColorPushButton.setEnabled(True)
self.shadowColorPushButton.setEnabled(True)
else:
self.ShadowColorPushButton.setEnabled(False)
self.shadowColorPushButton.setEnabled(False)
def previewTheme(self):
if self.allowPreview:
@ -741,15 +695,15 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
# pixels top/bottom
line_height += 2 * int(self.theme.display_outline_size)
page_length = \
((self.FontMainHeightSpinBox.value()) / line_height )
((self.fontMainHeightSpinBox.value()) / line_height )
log.debug(u'Page Length area height %s, metrics %s, lines %s' %
(self.FontMainHeightSpinBox.value(), metrics.height(),
(self.fontMainHeightSpinBox.value(), metrics.height(),
page_length))
page_length_text = unicode(
translate('OpenLP.AmendThemeForm', 'Slide height is %s rows.'))
self.FontMainLinesPageLabel.setText(page_length_text % page_length)
self.fontMainLinesPageLabel.setText(page_length_text % page_length)
frame = self.thememanager.generateImage(self.theme)
self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
self.themePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
def _getThemeMetrics(self):
main_weight = 50
@ -764,5 +718,5 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
# Validate that the screen width is big enough to display the text
if self.theme.font_main_width < metrics.maxWidth() * 2 + 64:
self.theme.font_main_width = metrics.maxWidth() * 2 + 64
self.FontMainWidthSpinBox.setValue(self.theme.font_main_width)
return metrics
self.fontMainWidthSpinBox.setValue(self.theme.font_main_width)
return metrics

View File

@ -38,6 +38,8 @@ class GeneralTab(SettingsTab):
"""
self.screens = screens
self.monitorNumber = 0
# Set to True to allow PostSetup to work on application start up
self.overrideChanged = True
SettingsTab.__init__(self, u'General')
def preLoad(self):
@ -61,96 +63,101 @@ class GeneralTab(SettingsTab):
"""
self.setObjectName(u'GeneralTab')
self.tabTitleVisible = translate('OpenLP.GeneralTab', 'General')
self.GeneralLayout = QtGui.QHBoxLayout(self)
self.GeneralLayout.setSpacing(8)
self.GeneralLayout.setMargin(8)
self.GeneralLayout.setObjectName(u'GeneralLayout')
self.GeneralLeftLayout = QtGui.QVBoxLayout()
self.GeneralLeftLayout.setObjectName(u'GeneralLeftLayout')
self.GeneralLeftLayout.setSpacing(8)
self.GeneralLeftLayout.setMargin(0)
self.GeneralLayout.addLayout(self.GeneralLeftLayout)
self.MonitorGroupBox = QtGui.QGroupBox(self)
self.MonitorGroupBox.setObjectName(u'MonitorGroupBox')
self.MonitorLayout = QtGui.QVBoxLayout(self.MonitorGroupBox)
self.MonitorLayout.setSpacing(8)
self.MonitorLayout.setMargin(8)
self.MonitorLayout.setObjectName(u'MonitorLayout')
self.MonitorLabel = QtGui.QLabel(self.MonitorGroupBox)
self.MonitorLabel.setObjectName(u'MonitorLabel')
self.MonitorLayout.addWidget(self.MonitorLabel)
self.MonitorComboBox = QtGui.QComboBox(self.MonitorGroupBox)
self.MonitorComboBox.setObjectName(u'MonitorComboBox')
self.MonitorLayout.addWidget(self.MonitorComboBox)
self.MonitorLayout.addWidget(self.MonitorComboBox)
self.DisplayOnMonitorCheck = QtGui.QCheckBox(self.MonitorGroupBox)
self.DisplayOnMonitorCheck.setObjectName(u'MonitorComboBox')
self.MonitorLayout.addWidget(self.DisplayOnMonitorCheck)
self.GeneralLeftLayout.addWidget(self.MonitorGroupBox)
self.StartupGroupBox = QtGui.QGroupBox(self)
self.StartupGroupBox.setObjectName(u'StartupGroupBox')
self.StartupLayout = QtGui.QVBoxLayout(self.StartupGroupBox)
self.StartupLayout.setSpacing(8)
self.StartupLayout.setMargin(8)
self.StartupLayout.setObjectName(u'StartupLayout')
self.WarningCheckBox = QtGui.QCheckBox(self.StartupGroupBox)
self.WarningCheckBox.setObjectName(u'WarningCheckBox')
self.StartupLayout.addWidget(self.WarningCheckBox)
self.AutoOpenCheckBox = QtGui.QCheckBox(self.StartupGroupBox)
self.AutoOpenCheckBox.setObjectName(u'AutoOpenCheckBox')
self.StartupLayout.addWidget(self.AutoOpenCheckBox)
self.ShowSplashCheckBox = QtGui.QCheckBox(self.StartupGroupBox)
self.ShowSplashCheckBox.setObjectName(u'ShowSplashCheckBox')
self.StartupLayout.addWidget(self.ShowSplashCheckBox)
self.GeneralLeftLayout.addWidget(self.StartupGroupBox)
self.SettingsGroupBox = QtGui.QGroupBox(self)
self.SettingsGroupBox.setObjectName(u'SettingsGroupBox')
self.SettingsLayout = QtGui.QVBoxLayout(self.SettingsGroupBox)
self.SettingsLayout.setSpacing(8)
self.SettingsLayout.setMargin(8)
self.SettingsLayout.setObjectName(u'SettingsLayout')
self.SaveCheckServiceCheckBox = QtGui.QCheckBox(self.SettingsGroupBox)
self.SaveCheckServiceCheckBox.setObjectName(u'SaveCheckServiceCheckBox')
self.SettingsLayout.addWidget(self.SaveCheckServiceCheckBox)
self.GeneralLeftLayout.addWidget(self.SettingsGroupBox)
self.AutoPreviewCheckBox = QtGui.QCheckBox(self.SettingsGroupBox)
self.AutoPreviewCheckBox.setObjectName(u'AutoPreviewCheckBox')
self.SettingsLayout.addWidget(self.AutoPreviewCheckBox)
self.GeneralLeftLayout.addWidget(self.SettingsGroupBox)
self.GeneralLeftSpacer = QtGui.QSpacerItem(20, 40,
self.generalLayout = QtGui.QHBoxLayout(self)
self.generalLayout.setSpacing(8)
self.generalLayout.setMargin(8)
self.generalLayout.setObjectName(u'generalLayout')
self.generalLeftLayout = QtGui.QVBoxLayout()
self.generalLeftLayout.setObjectName(u'generalLeftLayout')
self.generalLeftLayout.setSpacing(8)
self.generalLeftLayout.setMargin(0)
self.generalLayout.addLayout(self.generalLeftLayout)
self.monitorGroupBox = QtGui.QGroupBox(self)
self.monitorGroupBox.setObjectName(u'monitorGroupBox')
self.monitorLayout = QtGui.QVBoxLayout(self.monitorGroupBox)
self.monitorLayout.setSpacing(8)
self.monitorLayout.setMargin(8)
self.monitorLayout.setObjectName(u'monitorLayout')
self.monitorLabel = QtGui.QLabel(self.monitorGroupBox)
self.monitorLabel.setObjectName(u'monitorLabel')
self.monitorLayout.addWidget(self.monitorLabel)
self.monitorComboBox = QtGui.QComboBox(self.monitorGroupBox)
self.monitorComboBox.setObjectName(u'monitorComboBox')
self.monitorLayout.addWidget(self.monitorComboBox)
self.displayOnMonitorCheck = QtGui.QCheckBox(self.monitorGroupBox)
self.displayOnMonitorCheck.setObjectName(u'monitorComboBox')
self.monitorLayout.addWidget(self.displayOnMonitorCheck)
self.generalLeftLayout.addWidget(self.monitorGroupBox)
self.startupGroupBox = QtGui.QGroupBox(self)
self.startupGroupBox.setObjectName(u'startupGroupBox')
self.startupLayout = QtGui.QVBoxLayout(self.startupGroupBox)
self.startupLayout.setSpacing(8)
self.startupLayout.setMargin(8)
self.startupLayout.setObjectName(u'startupLayout')
self.warningCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.warningCheckBox.setObjectName(u'warningCheckBox')
self.startupLayout.addWidget(self.warningCheckBox)
self.autoOpenCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.autoOpenCheckBox.setObjectName(u'autoOpenCheckBox')
self.startupLayout.addWidget(self.autoOpenCheckBox)
self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.showSplashCheckBox.setObjectName(u'showSplashCheckBox')
self.startupLayout.addWidget(self.showSplashCheckBox)
self.generalLeftLayout.addWidget(self.startupGroupBox)
self.settingsGroupBox = QtGui.QGroupBox(self)
self.settingsGroupBox.setObjectName(u'settingsGroupBox')
self.settingsLayout = QtGui.QGridLayout(self.settingsGroupBox)
self.settingsLayout.setSpacing(8)
self.settingsLayout.setMargin(8)
self.settingsLayout.setObjectName(u'settingsLayout')
self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.saveCheckServiceCheckBox.setObjectName(u'saveCheckServiceCheckBox')
self.settingsLayout.addWidget(self.saveCheckServiceCheckBox, 0, 0, 1, 2)
self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox')
self.settingsLayout.addWidget(self.autoPreviewCheckBox, 1, 0, 1, 2)
# Moved here from image tab
self.timeoutLabel = QtGui.QLabel(self.settingsGroupBox)
self.timeoutLabel.setObjectName("timeoutLabel")
self.settingsLayout.addWidget(self.timeoutLabel, 2, 0, 1, 1)
self.timeoutSpinBox = QtGui.QSpinBox(self.settingsGroupBox)
self.timeoutSpinBox.setObjectName("timeoutSpinBox")
self.settingsLayout.addWidget(self.timeoutSpinBox, 2, 1, 1, 1)
self.generalLeftLayout.addWidget(self.settingsGroupBox)
self.generalLeftSpacer = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.GeneralLeftLayout.addItem(self.GeneralLeftSpacer)
self.GeneralRightLayout = QtGui.QVBoxLayout()
self.GeneralRightLayout.setSpacing(8)
self.GeneralRightLayout.setMargin(0)
self.GeneralRightLayout.setObjectName(u'GeneralRightLayout')
self.GeneralLayout.addLayout(self.GeneralRightLayout)
self.CCLIGroupBox = QtGui.QGroupBox(self)
self.CCLIGroupBox.setObjectName(u'CCLIGroupBox')
self.CCLILayout = QtGui.QGridLayout(self.CCLIGroupBox)
self.CCLILayout.setMargin(8)
self.CCLILayout.setSpacing(8)
self.CCLILayout.setObjectName(u'CCLILayout')
self.NumberLabel = QtGui.QLabel(self.CCLIGroupBox)
self.NumberLabel.setObjectName(u'NumberLabel')
self.CCLILayout.addWidget(self.NumberLabel, 0, 0, 1, 1)
self.NumberEdit = QtGui.QLineEdit(self.CCLIGroupBox)
self.NumberEdit.setObjectName(u'NumberEdit')
self.CCLILayout.addWidget(self.NumberEdit, 0, 1, 1, 1)
self.UsernameLabel = QtGui.QLabel(self.CCLIGroupBox)
self.UsernameLabel.setObjectName(u'UsernameLabel')
self.CCLILayout.addWidget(self.UsernameLabel, 1, 0, 1, 1)
self.UsernameEdit = QtGui.QLineEdit(self.CCLIGroupBox)
self.UsernameEdit.setObjectName(u'UsernameEdit')
self.CCLILayout.addWidget(self.UsernameEdit, 1, 1, 1, 1)
self.PasswordLabel = QtGui.QLabel(self.CCLIGroupBox)
self.PasswordLabel.setObjectName(u'PasswordLabel')
self.CCLILayout.addWidget(self.PasswordLabel, 2, 0, 1, 1)
self.PasswordEdit = QtGui.QLineEdit(self.CCLIGroupBox)
self.PasswordEdit.setEchoMode(QtGui.QLineEdit.Password)
self.PasswordEdit.setObjectName(u'PasswordEdit')
self.CCLILayout.addWidget(self.PasswordEdit, 2, 1, 1, 1)
self.GeneralRightLayout.addWidget(self.CCLIGroupBox)
self.generalLeftLayout.addItem(self.generalLeftSpacer)
self.generalRightLayout = QtGui.QVBoxLayout()
self.generalRightLayout.setSpacing(8)
self.generalRightLayout.setMargin(0)
self.generalRightLayout.setObjectName(u'generalRightLayout')
self.generalLayout.addLayout(self.generalRightLayout)
self.ccliGroupBox = QtGui.QGroupBox(self)
self.ccliGroupBox.setObjectName(u'ccliGroupBox')
self.ccliLayout = QtGui.QGridLayout(self.ccliGroupBox)
self.ccliLayout.setMargin(8)
self.ccliLayout.setSpacing(8)
self.ccliLayout.setObjectName(u'ccliLayout')
self.numberLabel = QtGui.QLabel(self.ccliGroupBox)
self.numberLabel.setObjectName(u'numberLabel')
self.ccliLayout.addWidget(self.numberLabel, 0, 0, 1, 1)
self.numberEdit = QtGui.QLineEdit(self.ccliGroupBox)
self.numberEdit.setObjectName(u'numberEdit')
self.ccliLayout.addWidget(self.numberEdit, 0, 1, 1, 1)
self.usernameLabel = QtGui.QLabel(self.ccliGroupBox)
self.usernameLabel.setObjectName(u'usernameLabel')
self.ccliLayout.addWidget(self.usernameLabel, 1, 0, 1, 1)
self.usernameEdit = QtGui.QLineEdit(self.ccliGroupBox)
self.usernameEdit.setObjectName(u'usernameEdit')
self.ccliLayout.addWidget(self.usernameEdit, 1, 1, 1, 1)
self.passwordLabel = QtGui.QLabel(self.ccliGroupBox)
self.passwordLabel.setObjectName(u'passwordLabel')
self.ccliLayout.addWidget(self.passwordLabel, 2, 0, 1, 1)
self.passwordEdit = QtGui.QLineEdit(self.ccliGroupBox)
self.passwordEdit.setEchoMode(QtGui.QLineEdit.Password)
self.passwordEdit.setObjectName(u'passwordEdit')
self.ccliLayout.addWidget(self.passwordEdit, 2, 1, 1, 1)
self.generalRightLayout.addWidget(self.ccliGroupBox)
# Moved here from display tab
self.displayGroupBox = QtGui.QGroupBox(self)
self.displayGroupBox.setObjectName(u'displayGroupBox')
@ -219,7 +226,7 @@ class GeneralTab(SettingsTab):
self.overrideCheckBox = QtGui.QCheckBox(self.displayGroupBox)
self.overrideCheckBox.setObjectName(u'overrideCheckBox')
self.displayLayout.addWidget(self.overrideCheckBox)
self.GeneralRightLayout.addWidget(self.displayGroupBox)
self.generalRightLayout.addWidget(self.displayGroupBox)
# Custom position
self.customLayout = QtGui.QHBoxLayout()
self.customLayout.setSpacing(8)
@ -276,9 +283,9 @@ class GeneralTab(SettingsTab):
self.customLayout.addLayout(self.customWidthLayout)
self.displayLayout.addLayout(self.customLayout)
# Bottom spacer
self.GeneralRightSpacer = QtGui.QSpacerItem(20, 40,
self.generalRightSpacer = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.GeneralRightLayout.addItem(self.GeneralRightSpacer)
self.generalRightLayout.addItem(self.generalRightSpacer)
# Signals and slots
QtCore.QObject.connect(self.overrideCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideCheckBoxToggled)
@ -287,32 +294,37 @@ class GeneralTab(SettingsTab):
"""
Translate the general settings tab to the currently selected language
"""
self.MonitorGroupBox.setTitle(translate('OpenLP.GeneralTab', 'Monitors'))
self.MonitorLabel.setText(translate('OpenLP.GeneralTab',
self.monitorGroupBox.setTitle(translate('OpenLP.GeneralTab',
'Monitors'))
self.monitorLabel.setText(translate('OpenLP.GeneralTab',
'Select monitor for output display:'))
self.DisplayOnMonitorCheck.setText(
self.displayOnMonitorCheck.setText(
translate('OpenLP.GeneralTab', 'Display if a single screen'))
self.StartupGroupBox.setTitle(
self.startupGroupBox.setTitle(
translate('OpenLP.GeneralTab', 'Application Startup'))
self.WarningCheckBox.setText(
self.warningCheckBox.setText(
translate('OpenLP.GeneralTab', 'Show blank screen warning'))
self.AutoOpenCheckBox.setText(translate('OpenLP.GeneralTab',
self.autoOpenCheckBox.setText(translate('OpenLP.GeneralTab',
'Automatically open the last service'))
self.ShowSplashCheckBox.setText(
self.showSplashCheckBox.setText(
translate('OpenLP.GeneralTab', 'Show the splash screen'))
self.SettingsGroupBox.setTitle(
self.settingsGroupBox.setTitle(
translate('OpenLP.GeneralTab', 'Application Settings'))
self.SaveCheckServiceCheckBox.setText(translate('OpenLP.GeneralTab',
self.saveCheckServiceCheckBox.setText(translate('OpenLP.GeneralTab',
'Prompt to save before starting a new service'))
self.AutoPreviewCheckBox.setText(translate('OpenLP.GeneralTab',
self.autoPreviewCheckBox.setText(translate('OpenLP.GeneralTab',
'Automatically preview next item in service'))
self.CCLIGroupBox.setTitle(
self.timeoutLabel.setText(translate('OpenLP.GeneralTab',
'Slide loop delay:'))
self.timeoutSpinBox.setSuffix(
translate('OpenLP.GeneralTab', ' sec'))
self.ccliGroupBox.setTitle(
translate('OpenLP.GeneralTab', 'CCLI Details'))
self.NumberLabel.setText(
self.numberLabel.setText(
translate('OpenLP.GeneralTab', 'CCLI number:'))
self.UsernameLabel.setText(
self.usernameLabel.setText(
translate('OpenLP.GeneralTab', 'SongSelect username:'))
self.PasswordLabel.setText(
self.passwordLabel.setText(
translate('OpenLP.GeneralTab', 'SongSelect password:'))
# Moved from display tab
self.displayGroupBox.setTitle(
@ -347,25 +359,27 @@ class GeneralTab(SettingsTab):
if screen[u'primary']:
screen_name = u'%s (%s)' % (screen_name,
translate('OpenLP.GeneralTab', 'primary'))
self.MonitorComboBox.addItem(screen_name)
self.NumberEdit.setText(unicode(settings.value(
self.monitorComboBox.addItem(screen_name)
self.numberEdit.setText(unicode(settings.value(
u'ccli number', QtCore.QVariant(u'')).toString()))
self.UsernameEdit.setText(unicode(settings.value(
self.usernameEdit.setText(unicode(settings.value(
u'songselect username', QtCore.QVariant(u'')).toString()))
self.PasswordEdit.setText(unicode(settings.value(
self.passwordEdit.setText(unicode(settings.value(
u'songselect password', QtCore.QVariant(u'')).toString()))
self.SaveCheckServiceCheckBox.setChecked(settings.value(u'save prompt',
self.saveCheckServiceCheckBox.setChecked(settings.value(u'save prompt',
QtCore.QVariant(False)).toBool())
self.MonitorComboBox.setCurrentIndex(self.monitorNumber)
self.DisplayOnMonitorCheck.setChecked(self.screens.display)
self.WarningCheckBox.setChecked(settings.value(u'blank warning',
self.monitorComboBox.setCurrentIndex(self.monitorNumber)
self.displayOnMonitorCheck.setChecked(self.screens.display)
self.warningCheckBox.setChecked(settings.value(u'blank warning',
QtCore.QVariant(False)).toBool())
self.AutoOpenCheckBox.setChecked(settings.value(u'auto open',
self.autoOpenCheckBox.setChecked(settings.value(u'auto open',
QtCore.QVariant(False)).toBool())
self.ShowSplashCheckBox.setChecked(settings.value(u'show splash',
self.showSplashCheckBox.setChecked(settings.value(u'show splash',
QtCore.QVariant(True)).toBool())
self.AutoPreviewCheckBox.setChecked(settings.value(u'auto preview',
self.autoPreviewCheckBox.setChecked(settings.value(u'auto preview',
QtCore.QVariant(False)).toBool())
self.timeoutSpinBox.setValue(settings.value(u'loop delay',
QtCore.QVariant(5)).toInt()[0])
self.currentXValueLabel.setText(
unicode(self.screens.current[u'size'].x()))
self.currentYValueLabel.setText(
@ -376,59 +390,50 @@ class GeneralTab(SettingsTab):
unicode(self.screens.current[u'size'].width()))
self.overrideCheckBox.setChecked(settings.value(u'override position',
QtCore.QVariant(False)).toBool())
if self.overrideCheckBox.isChecked():
self.customXValueEdit.setText(settings.value(u'x position',
QtCore.QVariant(self.screens.current[u'size'].x())).toString())
self.customYValueEdit.setText(settings.value(u'y position',
QtCore.QVariant(self.screens.current[u'size'].y())).toString())
self.customHeightValueEdit.setText(
settings.value(u'height', QtCore.QVariant(
self.screens.current[u'size'].height())).toString())
self.customWidthValueEdit.setText(
settings.value(u'width', QtCore.QVariant(
self.screens.current[u'size'].width())).toString())
else:
self.customXValueEdit.setText(
unicode(self.screens.current[u'size'].x()))
self.customYValueEdit.setText(
unicode(self.screens.current[u'size'].y()))
self.customHeightValueEdit.setText(
unicode(self.screens.current[u'size'].height()))
self.customWidthValueEdit.setText(
unicode(self.screens.current[u'size'].width()))
self.customXValueEdit.setText(settings.value(u'x position',
QtCore.QVariant(self.screens.current[u'size'].x())).toString())
self.customYValueEdit.setText(settings.value(u'y position',
QtCore.QVariant(self.screens.current[u'size'].y())).toString())
self.customHeightValueEdit.setText(
settings.value(u'height', QtCore.QVariant(
self.screens.current[u'size'].height())).toString())
self.customWidthValueEdit.setText(
settings.value(u'width', QtCore.QVariant(
self.screens.current[u'size'].width())).toString())
settings.endGroup()
self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customHeightValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customWidthValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.override_changed = False
def save(self):
"""
Save the settings from the form
"""
self.monitorNumber = self.MonitorComboBox.currentIndex()
self.monitorNumber = self.monitorComboBox.currentIndex()
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
settings.setValue(u'monitor', QtCore.QVariant(self.monitorNumber))
settings.setValue(u'display on monitor',
QtCore.QVariant(self.DisplayOnMonitorCheck.isChecked()))
QtCore.QVariant(self.displayOnMonitorCheck.isChecked()))
settings.setValue(u'blank warning',
QtCore.QVariant(self.WarningCheckBox.isChecked()))
QtCore.QVariant(self.warningCheckBox.isChecked()))
settings.setValue(u'auto open',
QtCore.QVariant(self.AutoOpenCheckBox.isChecked()))
QtCore.QVariant(self.autoOpenCheckBox.isChecked()))
settings.setValue(u'show splash',
QtCore.QVariant(self.ShowSplashCheckBox.isChecked()))
QtCore.QVariant(self.showSplashCheckBox.isChecked()))
settings.setValue(u'save prompt',
QtCore.QVariant(self.SaveCheckServiceCheckBox.isChecked()))
QtCore.QVariant(self.saveCheckServiceCheckBox.isChecked()))
settings.setValue(u'auto preview',
QtCore.QVariant(self.AutoPreviewCheckBox.isChecked()))
QtCore.QVariant(self.autoPreviewCheckBox.isChecked()))
settings.setValue(u'loop delay',
QtCore.QVariant(self.timeoutSpinBox.value()))
settings.setValue(u'ccli number',
QtCore.QVariant(self.NumberEdit.displayText()))
QtCore.QVariant(self.numberEdit.displayText()))
settings.setValue(u'songselect username',
QtCore.QVariant(self.UsernameEdit.displayText()))
QtCore.QVariant(self.usernameEdit.displayText()))
settings.setValue(u'songselect password',
QtCore.QVariant(self.PasswordEdit.displayText()))
QtCore.QVariant(self.passwordEdit.displayText()))
settings.setValue(u'x position',
QtCore.QVariant(self.customXValueEdit.text()))
settings.setValue(u'y position',
@ -440,30 +445,39 @@ class GeneralTab(SettingsTab):
settings.setValue(u'override position',
QtCore.QVariant(self.overrideCheckBox.isChecked()))
settings.endGroup()
self.screens.display = self.DisplayOnMonitorCheck.isChecked()
#Monitor Number has changed.
self.screens.display = self.displayOnMonitorCheck.isChecked()
# Monitor Number has changed.
postUpdate = False
if self.screens.monitor_number != self.monitorNumber:
self.screens.monitor_number = self.monitorNumber
self.screens.set_current_display(self.monitorNumber)
Receiver.send_message(u'config_screen_changed')
Receiver.send_message(u'config_updated')
postUpdate = True
# On save update the screens as well
self.postSetUp()
self.postSetUp(postUpdate)
def postSetUp(self):
def postSetUp(self, postUpdate=False):
"""
Reset screens after initial definition
Apply settings after settings tab has loaded and most of the
system so must be delayed
"""
self.screens.override[u'size'] = QtCore.QRect(
int(self.customXValueEdit.text()),
int(self.customYValueEdit.text()),
int(self.customWidthValueEdit.text()),
int(self.customHeightValueEdit.text()))
Receiver.send_message(u'slidecontroller_live_spin_delay',
self.timeoutSpinBox.value())
# Reset screens after initial definition
if self.overrideChanged:
self.screens.override[u'size'] = QtCore.QRect(
int(self.customXValueEdit.text()),
int(self.customYValueEdit.text()),
int(self.customWidthValueEdit.text()),
int(self.customHeightValueEdit.text()))
if self.overrideCheckBox.isChecked():
self.screens.set_override_display()
Receiver.send_message(u'config_screen_changed')
else:
self.screens.reset_current_display()
# Order is important so be careful if you change
if self.overrideChanged or postUpdate:
Receiver.send_message(u'config_screen_changed')
Receiver.send_message(u'config_updated')
self.overrideChanged = False
def onOverrideCheckBoxToggled(self, checked):
"""
@ -473,4 +487,4 @@ class GeneralTab(SettingsTab):
self.customYValueEdit.setEnabled(checked)
self.customHeightValueEdit.setEnabled(checked)
self.customWidthValueEdit.setEnabled(checked)
self.override_changed = True
self.overrideChanged = True

View File

@ -26,149 +26,46 @@
import logging
import os
import time
from PyQt4 import QtCore, QtGui, QtWebKit
from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, resize_image
from openlp.core.lib import Receiver, resize_image, build_html, ServiceItem, \
image_to_byte
from openlp.core.ui import HideMode
log = logging.getLogger(__name__)
#http://www.steveheffernan.com/html5-video-player/demo-video-player.html
HTMLVIDEO = u"""<html>
<head>
<style>
*{
margin: 0;
padding:0
}
</style>
<script type="text/javascript" charset="utf-8">
var video;
var bodyLoaded = function(){
video = document.getElementById("video");
video.volume = 0;
}
</script>
</head>
<body id="body" onload="bodyLoaded();">
<video id="video" src="%s" autoplay="autoplay" loop="loop"
width="%s" height="%s" autobuffer="autobuffer" preload="preload" />
</body></html>
"""
class DisplayManager(QtGui.QWidget):
"""
Wrapper class to hold the display widgets.
I will provide API's in future to access the screens allow for
extra displays to be added.
RenderManager is poked in by MainWindow
"""
def __init__(self, screens):
QtGui.QWidget.__init__(self)
self.screens = screens
self.videoDisplay = VideoDisplay(self, screens)
self.audioPlayer = AudioPlayer(self)
self.mainDisplay = MainDisplay(self, screens)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_show'), self.showDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_start'), self.onStartVideo)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_stop'), self.onStopVideo)
def setup(self):
self.videoDisplay.setup()
self.mainDisplay.setup()
def hideDisplay(self, message):
"""
Hide the output displays
"""
self.videoDisplay.mediaHide(message)
self.mainDisplay.hideDisplay(message)
def showDisplay(self, message):
"""
Hide the output displays
"""
self.videoDisplay.mediaShow(message)
self.mainDisplay.showDisplay(message)
def addAlert(self, alertMessage, location):
"""
Handles the addition of an Alert Message to the Displays
"""
self.mainDisplay.addAlert(alertMessage, location)
def displayImageWithText(self, frame):
"""
Handles the addition of a background Image to the displays
"""
self.mainDisplay.addImageWithText(frame)
def displayImage(self, frame):
"""
Handles the addition of a background Image to the displays
"""
self.mainDisplay.displayImage(frame)
def displayVideo(self, path):
"""
Handles the addition of a background Video to the displays
"""
self.mainDisplay.displayVideo(path)
def onStartVideo(self, item):
"""
Handles the Starting of a Video and Display Management
"""
self.videoDisplay.setVisible(True)
self.mainDisplay.setVisible(False)
self.videoDisplay.onMediaQueue(item)
def onStopVideo(self):
"""
Handles the Stopping of a Video and Display Management
"""
self.mainDisplay.setVisible(True)
self.videoDisplay.setVisible(False)
self.videoDisplay.onMediaStop()
def close(self):
"""
Handles the closure of the displays
"""
self.videoDisplay.close()
self.audioPlayer.close()
self.mainDisplay.close()
class DisplayWidget(QtGui.QGraphicsView):
"""
Customised version of QTableWidget which can respond to keyboard
events.
"""
log.info(u'MainDisplay loaded')
log.info(u'Display Widget loaded')
def __init__(self, parent=None, name=None, primary=False):
QtGui.QWidget.__init__(self, None)
def __init__(self, live, parent=None):
QtGui.QGraphicsView.__init__(self)
self.parent = parent
self.primary = primary
self.live = live
self.hotkey_map = {
QtCore.Qt.Key_Return: 'servicemanager_next_item',
QtCore.Qt.Key_Space: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_Enter: 'slidecontroller_live_next_noloop',
QtCore.Qt.Key_0: 'servicemanager_next_item',
QtCore.Qt.Key_Backspace: 'slidecontroller_live_previous_noloop'}
self.setStyleSheet(u'border: none;')
def keyPressEvent(self, event):
"""
Handle key events from display screen
"""
# Key events only needed for live
if not self.live:
return
if isinstance(event, QtGui.QKeyEvent):
#here accept the event and do something
# Here accept the event and do something
if event.key() == QtCore.Qt.Key_Up:
Receiver.send_message(u'slidecontroller_live_previous')
event.accept()
@ -185,157 +82,271 @@ class DisplayWidget(QtGui.QGraphicsView):
Receiver.send_message(self.hotkey_map[event.key()])
event.accept()
elif event.key() == QtCore.Qt.Key_Escape:
self.resetDisplay()
self.setVisible(False)
self.videoStop()
event.accept()
event.ignore()
else:
event.ignore()
def resetDisplay(self):
log.debug(u'resetDisplay')
Receiver.send_message(u'slidecontroller_live_stop_loop')
if self.primary:
self.setVisible(False)
else:
self.setVisible(True)
class MainDisplay(DisplayWidget):
"""
This is the form that is used to display things on the projector.
"""
log.info(u'MainDisplay Loaded')
def __init__(self, parent, screens):
"""
The constructor for the display form.
``parent``
The parent widget.
``screens``
The list of screens.
"""
log.debug(u'Initialisation started')
DisplayWidget.__init__(self, parent, primary=True)
self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
# WA_TranslucentBackground is not available in QT4.4
try:
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
except AttributeError:
pass
def __init__(self, parent, screens, live):
DisplayWidget.__init__(self, live, parent=None)
self.parent = parent
self.screens = screens
self.setupScene()
self.setupVideo()
self.setupImage()
self.setupText()
self.setupAlert()
self.setupBlank()
self.blankFrame = None
self.frame = None
#Hide desktop for now until we know where to put it
#and what size it should be.
self.setVisible(False)
self.isLive = live
self.alertTab = None
self.setWindowTitle(u'OpenLP Display')
self.setWindowFlags(QtCore.Qt.FramelessWindowHint |
QtCore.Qt.WindowStaysOnTopHint)
if self.isLive:
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_show'), self.showDisplay)
def setup(self):
"""
Sets up the screen on a particular screen.
Set up and build the output screen
"""
log.debug(u'Setup %s for %s ' % (
self.screens, self.screens.monitor_number))
self.setVisible(False)
log.debug(u'Setup live = %s for %s ' % (self.isLive,
self.screens.monitor_number))
self.screen = self.screens.current
#Sort out screen locations and sizes
self.setVisible(False)
self.setGeometry(self.screen[u'size'])
self.scene.setSceneRect(0, 0, self.size().width(),
self.size().height())
self.webView.setGeometry(0, 0, self.size().width(),
self.size().height())
#Build a custom splash screen
self.initialFrame = QtGui.QImage(
self.screen[u'size'].width(),
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
splash_image = QtGui.QImage(u':/graphics/openlp-splash-screen.png')
painter_image = QtGui.QPainter()
painter_image.begin(self.initialFrame)
painter_image.fillRect(self.initialFrame.rect(), QtCore.Qt.white)
painter_image.drawImage(
(self.screen[u'size'].width() - splash_image.width()) / 2,
(self.screen[u'size'].height() - splash_image.height()) / 2,
splash_image)
#build a blank transparent image
self.transparent = QtGui.QPixmap(
self.screen[u'size'].width(), self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent)
self.displayImage(self.initialFrame)
self.repaint()
#Build a Black screen
painter = QtGui.QPainter()
self.blankFrame = QtGui.QImage(
self.screen[u'size'].width(),
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
painter.begin(self.blankFrame)
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black)
# To display or not to display?
if not self.screen[u'primary']:
self.setVisible(True)
self.primary = False
else:
self.setVisible(False)
self.primary = True
def setupScene(self):
self.scene = QtGui.QGraphicsScene(self)
self.scene.setSceneRect(0, 0, self.size().width(), self.size().height())
self.setScene(self.scene)
def setupVideo(self):
self.webView = QtWebKit.QWebView()
self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0, self.screen[u'size'].width(), \
self.screen[u'size'].height())
self.page = self.webView.page()
self.videoDisplay = self.page.mainFrame()
self.videoDisplay.setScrollBarPolicy(QtCore.Qt.Vertical,
self.frame = self.page.mainFrame()
QtCore.QObject.connect(self.webView,
QtCore.SIGNAL(u'loadFinished(bool)'), self.isLoaded)
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical,
QtCore.Qt.ScrollBarAlwaysOff)
self.videoDisplay.setScrollBarPolicy(QtCore.Qt.Horizontal,
self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal,
QtCore.Qt.ScrollBarAlwaysOff)
self.proxy = QtGui.QGraphicsProxyWidget()
self.proxy.setWidget(self.webView)
self.proxy.setWindowFlags(QtCore.Qt.Window |
QtCore.Qt.FramelessWindowHint)
self.proxy.setZValue(1)
self.scene.addItem(self.proxy)
if self.isLive:
# Build the initial frame.
self.black = QtGui.QImage(
self.screens.current[u'size'].width(),
self.screens.current[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
painter_image = QtGui.QPainter()
painter_image.begin(self.black)
painter_image.fillRect(self.black.rect(), QtCore.Qt.black)
#Build the initial frame.
initialFrame = QtGui.QImage(
self.screens.current[u'size'].width(),
self.screens.current[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
splash_image = QtGui.QImage(u':/graphics/openlp-splash-screen.png')
painter_image = QtGui.QPainter()
painter_image.begin(initialFrame)
painter_image.fillRect(initialFrame.rect(), QtCore.Qt.white)
painter_image.drawImage(
(self.screens.current[u'size'].width() \
- splash_image.width()) / 2,
(self.screens.current[u'size'].height() \
- splash_image.height()) / 2,
splash_image)
serviceItem = ServiceItem()
serviceItem.bg_frame = initialFrame
self.webView.setHtml(build_html(serviceItem, self.screen,
self.parent.alertTab, self.isLive))
self.initialFrame = True
# To display or not to display?
if not self.screen[u'primary']:
self.show()
self.primary = False
else:
self.primary = True
def setupImage(self):
self.imageDisplay = QtGui.QGraphicsPixmapItem()
self.imageDisplay.setZValue(2)
self.scene.addItem(self.imageDisplay)
def text(self, slide):
"""
Add the slide text from slideController
def setupText(self):
#self.displayText = QtGui.QGraphicsTextItem()
self.displayText = QtGui.QGraphicsPixmapItem()
#self.displayText.setPos(0,0)
#self.displayText.setTextWidth(self.size().width())
self.displayText.setZValue(4)
self.scene.addItem(self.displayText)
`slide`
The slide text to be displayed
"""
log.debug(u'text')
self.frame.evaluateJavaScript(u'show_text("%s")' % \
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
return self.preview()
def setupAlert(self):
self.alertText = QtGui.QGraphicsTextItem()
self.alertText.setTextWidth(self.size().width())
self.alertText.setZValue(8)
self.scene.addItem(self.alertText)
def alert(self, text):
"""
Add the alert text
def setupBlank(self):
self.displayBlank = QtGui.QGraphicsPixmapItem()
self.displayBlank.setZValue(10)
self.scene.addItem(self.displayBlank)
`slide`
The slide text to be displayed
"""
log.debug(u'alert')
if self.height() != self.screen[u'size'].height() \
or not self.isVisible():
shrink = True
else:
shrink = False
js = u'show_alert("%s", "%s")' % (
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'),
u'top' if shrink else u'')
height = self.frame.evaluateJavaScript(js)
if shrink:
if text:
self.resize(self.width(), int(height.toString()))
self.setVisible(True)
else:
self.setGeometry(self.screen[u'size'])
self.setVisible(False)
# def hideDisplayForVideo(self):
# """
# Hides the main display if for the video to be played
# """
# self.hideDisplay(HideMode.Screen)
def image(self, image):
"""
Add an image as the background. The image is converted to a
bytestream on route.
`Image`
The Image to be displayed can be QImage or QPixmap
"""
log.debug(u'image')
image = resize_image(image, self.screen[u'size'].width(),
self.screen[u'size'].height())
self.resetVideo()
self.displayImage(image)
# show screen
if self.isLive:
self.setVisible(True)
def displayImage(self, image):
"""
Display an image, as is.
"""
if image:
js = u'show_image("data:image/png;base64,%s");' % \
image_to_byte(image)
else:
js = u'show_image("");'
self.frame.evaluateJavaScript(js)
def resetImage(self):
"""
Reset the backgound image to the service item image.
Used after Image plugin has changed the background
"""
log.debug(u'resetImage')
self.displayImage(self.serviceItem.bg_frame)
def resetVideo(self):
"""
Used after Video plugin has changed the background
"""
log.debug(u'resetVideo')
self.frame.evaluateJavaScript(u'show_video("close");')
def videoPlay(self):
"""
Responds to the request to play a loaded video
"""
log.debug(u'videoPlay')
self.frame.evaluateJavaScript(u'show_video("play");')
# show screen
if self.isLive:
self.setVisible(True)
def videoPause(self):
"""
Responds to the request to pause a loaded video
"""
log.debug(u'videoPause')
self.frame.evaluateJavaScript(u'show_video("pause");')
def videoStop(self):
"""
Responds to the request to stop a loaded video
"""
log.debug(u'videoStop')
self.frame.evaluateJavaScript(u'show_video("stop");')
def videoVolume(self, volume):
"""
Changes the volume of a running video
"""
log.debug(u'videoVolume %d' % volume)
self.frame.evaluateJavaScript(u'show_video(null, null, %s);' %
str(float(volume)/float(10)))
def video(self, videoPath, volume):
"""
Loads and starts a video to run with the option of sound
"""
log.debug(u'video')
self.loaded = True
js = u'show_video("play", "%s", %s, true);' % \
(videoPath.replace(u'\\', u'\\\\'), str(float(volume)/float(10)))
self.frame.evaluateJavaScript(js)
return self.preview()
def isLoaded(self):
"""
Called by webView event to show display is fully loaded
"""
log.debug(u'loaded')
self.loaded = True
def preview(self):
"""
Generates a preview of the image displayed.
"""
log.debug(u'preview for %s', self.isLive)
if self.isLive:
# 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_slideTransition:
while self.frame.evaluateJavaScript(u'show_text_complete()') \
.toString() == u'false':
Receiver.send_message(u'openlp_process_events')
# Wait for the webview to update before geting the preview.
# Important otherwise first preview will miss the background !
while not self.loaded:
Receiver.send_message(u'openlp_process_events')
preview = QtGui.QImage(self.screen[u'size'].width(),
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
painter = QtGui.QPainter(preview)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
self.frame.render(painter)
painter.end()
# Make display show up if in single screen mode
if self.isLive:
self.setVisible(True)
# save preview for debugging
if log.isEnabledFor(logging.DEBUG):
preview.save(u'temp.png', u'png')
return preview
def buildHtml(self, serviceItem):
"""
Store the serviceItem and build the new HTML from it. Add the
HTML to the display
"""
log.debug(u'buildHtml')
self.loaded = False
self.initialFrame = False
self.serviceItem = serviceItem
html = build_html(self.serviceItem, self.screen, self.parent.alertTab,\
self.isLive)
self.webView.setHtml(html)
if serviceItem.foot_text and serviceItem.foot_text:
self.footer(serviceItem.foot_text)
def footer(self, text):
"""
Display the Footer
"""
log.debug(u'footer')
js = "show_footer('" + \
text.replace("\\", "\\\\").replace("\'", "\\\'") + "')"
self.frame.evaluateJavaScript(js)
def hideDisplay(self, mode=HideMode.Screen):
"""
@ -343,20 +354,13 @@ class MainDisplay(DisplayWidget):
Store the images so they can be replaced when required
"""
log.debug(u'hideDisplay mode = %d', mode)
#self.displayText.setPixmap(self.transparent)
if mode == HideMode.Screen:
#self.display_image.setPixmap(self.transparent)
self.frame.evaluateJavaScript(u'show_blank("desktop");')
self.setVisible(False)
elif mode == HideMode.Blank:
self.displayBlank.setPixmap(
QtGui.QPixmap.fromImage(self.blankFrame))
elif mode == HideMode.Blank or self.initialFrame:
self.frame.evaluateJavaScript(u'show_blank("black");')
else:
if self.parent.renderManager.renderer.bg_frame:
self.displayBlank.setPixmap(QtGui.QPixmap.fromImage(
self.parent.renderManager.renderer.bg_frame))
else:
self.displayBlank.setPixmap(
QtGui.QPixmap.fromImage(self.blankFrame))
self.frame.evaluateJavaScript(u'show_blank("theme");')
if mode != HideMode.Screen and self.isHidden():
self.setVisible(True)
@ -367,275 +371,16 @@ class MainDisplay(DisplayWidget):
Make the stored images None to release memory.
"""
log.debug(u'showDisplay')
self.displayBlank.setPixmap(self.transparent)
self.frame.evaluateJavaScript('show_blank("show");')
if self.isHidden():
self.setVisible(True)
#Trigger actions when display is active again
# Trigger actions when display is active again
Receiver.send_message(u'maindisplay_active')
def addImageWithText(self, frame):
log.debug(u'addImageWithText')
frame = resize_image(
frame, self.screen[u'size'].width(), self.screen[u'size'].height())
self.imageDisplay.setPixmap(QtGui.QPixmap.fromImage(frame))
self.videoDisplay.setHtml(u'<html></html>')
def addAlert(self, message, location):
"""
Places the Alert text on the display at the correct location
``message``
Text to be displayed
``location``
Where on the screen the text should be. From the AlertTab
Combo box.
"""
log.debug(u'addAlertImage')
if location == 0:
self.alertText.setPos(0, 0)
elif location == 1:
self.alertText.setPos(0, self.size().height() / 2)
else:
self.alertText.setPos(0, self.size().height() - 76)
self.alertText.setHtml(message)
def displayImage(self, frame):
"""
Places the Image passed on the display screen
``frame``
The image to be displayed
"""
log.debug(u'adddisplayImage')
if isinstance(frame, QtGui.QImage):
self.imageDisplay.setPixmap(QtGui.QPixmap.fromImage(frame))
else:
self.imageDisplay.setPixmap(frame)
self.frameView(self.transparent)
self.videoDisplay.setHtml(u'<html></html>')
def displayVideo(self, path):
"""
Places the Video passed on the display screen
``path``
The path to the image to be displayed
"""
log.debug(u'adddisplayVideo')
self.displayImage(self.transparent)
self.videoDisplay.setHtml(HTMLVIDEO %
(path, self.screen[u'size'].width(),
self.screen[u'size'].height()))
def frameView(self, frame, transition=False):
"""
Called from a slide controller to display a frame
if the alert is in progress the alert is added on top
``frame``
Image frame to be rendered
``transition``
Are transitions required.
"""
log.debug(u'frameView')
if transition:
if self.frame is not None:
self.displayText.setPixmap(
QtGui.QPixmap.fromImage(self.frame))
self.repaint()
Receiver.send_message(u'openlp_process_events')
time.sleep(0.1)
self.frame = None
if frame[u'trans'] is not None:
self.displayText.setPixmap(
QtGui.QPixmap.fromImage(frame[u'trans']))
self.repaint()
Receiver.send_message(u'openlp_process_events')
time.sleep(0.1)
self.frame = frame[u'trans']
self.displayText.setPixmap(
QtGui.QPixmap.fromImage(frame[u'main']))
else:
if isinstance(frame, QtGui.QPixmap):
self.displayText.setPixmap(frame)
else:
self.displayText.setPixmap(QtGui.QPixmap.fromImage(frame))
if not self.isVisible() and self.screens.display:
self.setVisible(True)
class VideoDisplay(Phonon.VideoWidget):
"""
This is the form that is used to display videos on the projector.
"""
log.info(u'VideoDisplay Loaded')
def __init__(self, parent, screens,
aspect=Phonon.VideoWidget.AspectRatioWidget):
"""
The constructor for the display form.
``parent``
The parent widget.
``screens``
The list of screens.
"""
log.debug(u'VideoDisplay Initialisation started')
Phonon.VideoWidget.__init__(self)
self.setWindowTitle(u'OpenLP Video Display')
self.parent = parent
self.screens = screens
self.hidden = False
self.message = None
self.mediaActive = False
self.mediaObject = Phonon.MediaObject()
self.setAspectRatio(aspect)
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self)
Phonon.createPath(self.mediaObject, self.audioObject)
flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Dialog
## # WindowsStaysOnBottomHint is not available in QT4.4
# try:
# flags = flags | QtCore.Qt.WindowStaysOnBottomHint
# except AttributeError:
# pass
self.setWindowFlags(flags)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'videodisplay_pause'), self.onMediaPause)
# QtCore.QObject.connect(Receiver.get_receiver(),
# QtCore.SIGNAL(u'videodisplay_background'), self.onMediaBackground)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.setup)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'), self.onMediaStop)
self.setVisible(False)
def keyPressEvent(self, event):
if isinstance(event, QtGui.QKeyEvent):
#here accept the event and do something
if event.key() == QtCore.Qt.Key_Escape:
self.onMediaStop()
event.accept()
event.ignore()
else:
event.ignore()
def setup(self):
"""
Sets up the screen on a particular screen.
"""
log.debug(u'VideoDisplay Setup %s for %s ' % (self.screens,
self.screens.monitor_number))
self.screen = self.screens.current
#Sort out screen locations and sizes
self.setGeometry(self.screen[u'size'])
# To display or not to display?
if not self.screen[u'primary']: # and self.isVisible():
#self.showFullScreen()
self.setVisible(False)
self.primary = False
else:
self.setVisible(False)
self.primary = True
def closeEvent(self, event):
"""
Shutting down so clean up connections
"""
self.onMediaStop()
for path in self.outputPaths():
path.disconnect()
# def onMediaBackground(self, message=None):
# """
# Play a video triggered from the video plugin with the
# file name passed in on the event.
# Also triggered from the Finish event so the video will loop
# if it is triggered from the plugin
# """
# log.debug(u'VideoDisplay Queue new media message %s' % message)
# #If not file take the stored one
# if not message:
# message = self.message
# # still no file name then stop as it was a normal video stopping
# if message:
# self.mediaObject.setCurrentSource(Phonon.MediaSource(message))
# self.message = message
# self._play()
def onMediaQueue(self, message):
"""
Set up a video to play from the serviceitem.
"""
log.debug(u'VideoDisplay Queue new media message %s' % message)
file = os.path.join(message.get_frame_path(),
message.get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.mediaActive = True
self._play()
def onMediaPlay(self):
"""
Respond to the Play button on the slide controller unless the display
has been hidden by the slidecontroller
"""
if not self.hidden:
log.debug(u'VideoDisplay Play the new media, Live ')
self._play()
def _play(self):
"""
We want to play the video so start it and display the screen
"""
log.debug(u'VideoDisplay _play called')
self.mediaObject.play()
self.setVisible(True)
def onMediaPause(self):
"""
Pause the video and refresh the screen
"""
log.debug(u'VideoDisplay Media paused by user')
self.mediaObject.pause()
self.show()
def onMediaStop(self):
"""
Stop the video and clean up
"""
log.debug(u'VideoDisplay Media stopped by user')
self.message = None
self.mediaActive = False
self.mediaObject.stop()
self.onMediaFinish()
def onMediaFinish(self):
"""
Clean up the Object queue
"""
log.debug(u'VideoDisplay Reached end of media playlist')
self.mediaObject.clearQueue()
self.setVisible(False)
def mediaHide(self, message=u''):
"""
Hide the video display
"""
self.mediaObject.pause()
self.hidden = True
self.setVisible(False)
def mediaShow(self, message=''):
"""
Show the video display if it was already hidden
"""
if self.hidden:
self.hidden = False
if self.mediaActive:
self._play()
class AudioPlayer(QtCore.QObject):
"""
This Class will play audio only allowing components to work with a
soundtrack which does not take over the user interface.
soundtrack independent of the user interface.
"""
log.info(u'AudioPlayer Loaded')
@ -675,9 +420,9 @@ class AudioPlayer(QtCore.QObject):
Set up a video to play from the serviceitem.
"""
log.debug(u'AudioPlayer Queue new media message %s' % message)
file = os.path.join(message[0].get_frame_path(),
mfile = os.path.join(message[0].get_frame_path(),
message[0].get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.mediaObject.setCurrentSource(Phonon.MediaSource(mfile))
self.onMediaPlay()
def onMediaPlay(self):
@ -708,4 +453,4 @@ class AudioPlayer(QtCore.QObject):
Clean up the Object queue
"""
log.debug(u'AudioPlayer Reached end of media playlist')
self.mediaObject.clearQueue()
self.mediaObject.clearQueue()

View File

@ -25,17 +25,14 @@
###############################################################################
import logging
import time
import re
from PyQt4 import QtCore, QtGui
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ThemeManager, SlideController, PluginForm, MediaDockManager, DisplayManager
ThemeManager, SlideController, PluginForm, MediaDockManager
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate
from openlp.core.utils import check_latest_version, AppLocation, add_actions, \
LanguageManager
from openlp.core.utils import AppLocation, add_actions, LanguageManager
log = logging.getLogger(__name__)
@ -58,49 +55,6 @@ MEDIA_MANAGER_STYLE = """
font-weight: bold;
}
"""
class VersionThread(QtCore.QThread):
"""
A special Qt thread class to fetch the version of OpenLP from the website.
This is threaded so that it doesn't affect the loading time of OpenLP.
"""
def __init__(self, parent, app_version):
QtCore.QThread.__init__(self, parent)
self.parent = parent
self.app_version = app_version
self.version_splitter = re.compile(
r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))?')
def run(self):
"""
Run the thread.
"""
time.sleep(1)
Receiver.send_message(u'maindisplay_blank_check')
version = check_latest_version(self.app_version)
remote_version = {}
local_version = {}
match = self.version_splitter.match(version)
if match:
remote_version[u'major'] = int(match.group(1))
remote_version[u'minor'] = int(match.group(2))
remote_version[u'release'] = int(match.group(3))
if len(match.groups()) > 3 and match.group(4):
remote_version[u'revision'] = int(match.group(4))
match = self.version_splitter.match(self.app_version[u'full'])
if match:
local_version[u'major'] = int(match.group(1))
local_version[u'minor'] = int(match.group(2))
local_version[u'release'] = int(match.group(3))
if len(match.groups()) > 3 and match.group(4):
local_version[u'revision'] = int(match.group(4))
if remote_version[u'major'] > local_version[u'major'] or \
remote_version[u'minor'] > local_version[u'minor'] or \
remote_version[u'release'] > local_version[u'release']:
Receiver.send_message(u'openlp_version_check', u'%s' % version)
elif remote_version.get(u'revision') and \
local_version.get(u'revision') and \
remote_version[u'revision'] > local_version[u'revision']:
Receiver.send_message(u'openlp_version_check', u'%s' % version)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
@ -140,8 +94,10 @@ class Ui_MainWindow(object):
self.ControlSplitter.setObjectName(u'ControlSplitter')
self.MainContentLayout.addWidget(self.ControlSplitter)
# Create slide controllers
self.PreviewController = SlideController(self, self.settingsmanager)
self.LiveController = SlideController(self, self.settingsmanager, True)
self.PreviewController = SlideController(self, self.settingsmanager,
self.screens)
self.LiveController = SlideController(self, self.settingsmanager,
self.screens, True)
# Create menu
self.MenuBar = QtGui.QMenuBar(MainWindow)
self.MenuBar.setGeometry(QtCore.QRect(0, 0, 1087, 27))
@ -220,17 +176,17 @@ class Ui_MainWindow(object):
# Create the menu items
self.FileNewItem = QtGui.QAction(MainWindow)
self.FileNewItem.setIcon(
self.ServiceManagerContents.Toolbar.getIconFromTitle(
self.ServiceManagerContents.toolbar.getIconFromTitle(
u'New Service'))
self.FileNewItem.setObjectName(u'FileNewItem')
self.FileOpenItem = QtGui.QAction(MainWindow)
self.FileOpenItem.setIcon(
self.ServiceManagerContents.Toolbar.getIconFromTitle(
self.ServiceManagerContents.toolbar.getIconFromTitle(
u'Open Service'))
self.FileOpenItem.setObjectName(u'FileOpenItem')
self.FileSaveItem = QtGui.QAction(MainWindow)
self.FileSaveItem.setIcon(
self.ServiceManagerContents.Toolbar.getIconFromTitle(
self.ServiceManagerContents.toolbar.getIconFromTitle(
u'Save Service'))
self.FileSaveItem.setObjectName(u'FileSaveItem')
self.FileSaveAsItem = QtGui.QAction(MainWindow)
@ -308,18 +264,18 @@ class Ui_MainWindow(object):
self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem')
self.ViewPreviewPanel = QtGui.QAction(MainWindow)
self.ViewPreviewPanel.setCheckable(True)
self.ViewPreviewPanel.setChecked(
self.settingsmanager.get_preview_visibility())
previewVisible = QtCore.QSettings().value(
u'user interface/preview panel', QtCore.QVariant(True)).toBool()
self.ViewPreviewPanel.setChecked(previewVisible)
self.ViewPreviewPanel.setObjectName(u'ViewPreviewPanel')
self.PreviewController.Panel.setVisible(
self.settingsmanager.get_preview_visibility())
self.PreviewController.Panel.setVisible(previewVisible)
self.ViewLivePanel = QtGui.QAction(MainWindow)
self.ViewLivePanel.setCheckable(True)
self.ViewLivePanel.setChecked(
self.settingsmanager.get_live_visibility())
liveVisible = QtCore.QSettings().value(u'user interface/live panel',
QtCore.QVariant(True)).toBool()
self.ViewLivePanel.setChecked(liveVisible)
self.ViewLivePanel.setObjectName(u'ViewLivePanel')
self.LiveController.Panel.setVisible(
self.settingsmanager.get_live_visibility())
self.LiveController.Panel.setVisible(liveVisible)
self.ModeDefaultItem = QtGui.QAction(MainWindow)
self.ModeDefaultItem.setCheckable(True)
self.ModeDefaultItem.setObjectName(u'ModeDefaultItem')
@ -498,7 +454,8 @@ class Ui_MainWindow(object):
self.HelpAboutItem.setText(translate('OpenLP.MainWindow', '&About'))
self.HelpAboutItem.setStatusTip(
translate('OpenLP.MainWindow', 'More information about OpenLP'))
self.HelpAboutItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+F1'))
self.HelpAboutItem.setShortcut(translate('OpenLP.MainWindow',
'Ctrl+F1'))
self.HelpOnlineHelpItem.setText(
translate('OpenLP.MainWindow', '&Online Help'))
self.HelpWebSiteItem.setText(
@ -554,7 +511,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.songsSettingsSection = u'songs'
self.serviceNotSaved = False
self.settingsmanager = SettingsManager(screens)
self.displayManager = DisplayManager(screens)
self.aboutForm = AboutForm(self, applicationVersion)
self.settingsForm = SettingsForm(self.screens, self, self)
self.recentFiles = QtCore.QStringList()
@ -577,20 +533,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'triggered()'),
self.ThemeManagerContents.onExportTheme)
QtCore.QObject.connect(self.ViewMediaManagerItem,
QtCore.SIGNAL(u'triggered(bool)'),
self.toggleMediaManager)
QtCore.SIGNAL(u'triggered(bool)'), self.toggleMediaManager)
QtCore.QObject.connect(self.ViewServiceManagerItem,
QtCore.SIGNAL(u'triggered(bool)'),
self.toggleServiceManager)
QtCore.SIGNAL(u'triggered(bool)'), self.toggleServiceManager)
QtCore.QObject.connect(self.ViewThemeManagerItem,
QtCore.SIGNAL(u'triggered(bool)'),
self.toggleThemeManager)
QtCore.SIGNAL(u'triggered(bool)'), self.toggleThemeManager)
QtCore.QObject.connect(self.ViewPreviewPanel,
QtCore.SIGNAL(u'toggled(bool)'),
self.setPreviewPanelVisibility)
QtCore.SIGNAL(u'toggled(bool)'), self.setPreviewPanelVisibility)
QtCore.QObject.connect(self.ViewLivePanel,
QtCore.SIGNAL(u'toggled(bool)'),
self.setLivePanelVisibility)
QtCore.SIGNAL(u'toggled(bool)'), self.setLivePanelVisibility)
QtCore.QObject.connect(self.MediaManagerDock,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.ViewMediaManagerItem.setChecked)
@ -608,8 +559,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked)
QtCore.QObject.connect(self.SettingsConfigureItem,
QtCore.SIGNAL(u'triggered()'), self.onOptionsSettingsItemClicked)
QtCore.QObject.connect(self.FileNewItem,
QtCore.SIGNAL(u'triggered()'),
QtCore.QObject.connect(self.FileNewItem, QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onNewService)
QtCore.QObject.connect(self.FileOpenItem,
QtCore.SIGNAL(u'triggered()'),
@ -622,22 +572,18 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.ServiceManagerContents.onSaveService)
#i18n set signals for languages
QtCore.QObject.connect(self.AutoLanguageItem,
QtCore.SIGNAL(u'toggled(bool)'),
self.setAutoLanguage)
QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage)
self.LanguageGroup.triggered.connect(LanguageManager.set_language)
QtCore.QObject.connect(self.ModeDefaultItem,
QtCore.SIGNAL(u'triggered()'),
self.onModeDefaultItemClicked)
QtCore.SIGNAL(u'triggered()'), self.setViewMode)
QtCore.QObject.connect(self.ModeSetupItem,
QtCore.SIGNAL(u'triggered()'),
self.onModeSetupItemClicked)
QtCore.SIGNAL(u'triggered()'), self.onModeSetupItemClicked)
QtCore.QObject.connect(self.ModeLiveItem,
QtCore.SIGNAL(u'triggered()'),
self.onModeLiveItemClicked)
QtCore.SIGNAL(u'triggered()'), self.onModeLiveItemClicked)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_global'), self.defaultThemeChanged)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_version_check'), self.versionCheck)
QtCore.SIGNAL(u'openlp_version_check'), self.versionNotice)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_blank_check'), self.blankCheck)
QtCore.QObject.connect(Receiver.get_receiver(),
@ -649,7 +595,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
#ThemeManager needs to call RenderManager
self.RenderManager = RenderManager(
self.ThemeManagerContents, self.screens)
self.displayManager.renderManager = self.RenderManager
#Define the media Dock Manager
self.mediaDockManager = MediaDockManager(self.MediaToolBox)
log.info(u'Load Plugins')
@ -660,8 +605,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.plugin_helpers[u'service'] = self.ServiceManagerContents
self.plugin_helpers[u'settings form'] = self.settingsForm
self.plugin_helpers[u'toolbox'] = self.mediaDockManager
self.plugin_helpers[u'displaymanager'] = self.displayManager
self.plugin_helpers[u'pluginmanager'] = self.plugin_manager
self.plugin_helpers[u'formparent'] = self
self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers)
# hook methods have to happen after find_plugins. Find plugins needs
# the controllers hence the hooks have moved from setupUI() to here
@ -698,31 +643,28 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
LanguageManager.AutoLanguage = value
LanguageManager.set_language(self.LanguageGroup.checkedAction())
def versionCheck(self, version):
def versionNotice(self, version):
"""
Checks the version of the Application called from openlp.pyw
Notifies the user that a newer version of OpenLP is available.
Triggered by delay thread.
"""
app_version = self.applicationVersion[u'full']
version_text = unicode(translate('OpenLP.MainWindow',
'Version %s of OpenLP is now available for download (you are '
'currently running version %s). \n\nYou can download the latest '
'version from <a href="http://openlp.org/">http://openlp.org/</a>.'))
'version from http://openlp.org/.'))
QtGui.QMessageBox.question(self,
translate('OpenLP.MainWindow', 'OpenLP Version Updated'),
version_text % (version, app_version),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
version_text % (version, self.applicationVersion[u'full']))
def show(self):
"""
Show the main form, as well as the display form
"""
QtGui.QWidget.show(self)
#screen_number = self.getMonitorNumber()
self.displayManager.setup()
if self.displayManager.mainDisplay.isVisible():
self.displayManager.mainDisplay.setFocus()
self.LiveController.display.setup()
self.PreviewController.display.setup()
if self.LiveController.display.isVisible():
self.LiveController.display.setFocus()
self.activateWindow()
if QtCore.QSettings().value(
self.generalSettingsSection + u'/auto open',
@ -747,13 +689,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
'The Main Display has been blanked out'))
settings.endGroup()
def versionThread(self):
"""
Start an initial setup thread to delay notifications
"""
vT = VersionThread(self, self.applicationVersion)
vT.start()
def onHelpWebSiteClicked(self):
"""
Load the OpenLP website
@ -781,43 +716,36 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
self.settingsForm.exec_()
def onModeDefaultItemClicked(self):
"""
Put OpenLP into "Default" view mode.
"""
self.MediaManagerDock.setVisible(True)
self.ServiceManagerDock.setVisible(True)
self.ThemeManagerDock.setVisible(True)
self.setPreviewPanelVisibility(True)
self.setLivePanelVisibility(True)
def onModeSetupItemClicked(self):
"""
Put OpenLP into "Setup" view mode.
"""
self.MediaManagerDock.setVisible(True)
self.ServiceManagerDock.setVisible(True)
self.ThemeManagerDock.setVisible(False)
self.setPreviewPanelVisibility(True)
self.setLivePanelVisibility(False)
self.setViewMode(True, True, False, True, False)
def onModeLiveItemClicked(self):
"""
Put OpenLP into "Live" view mode.
"""
self.MediaManagerDock.setVisible(False)
self.ServiceManagerDock.setVisible(True)
self.ThemeManagerDock.setVisible(False)
self.setPreviewPanelVisibility(False)
self.setLivePanelVisibility(True)
self.setViewMode(False, True, False, False, True)
def setViewMode(self, media=True, service=True, theme=True, preview=True,
live=True):
"""
Set OpenLP to a different view mode.
"""
self.MediaManagerDock.setVisible(media)
self.ServiceManagerDock.setVisible(service)
self.ThemeManagerDock.setVisible(theme)
self.setPreviewPanelVisibility(preview)
self.setLivePanelVisibility(live)
def screenChanged(self):
"""
The screen has changed to so tell the displays to update_display
their locations
"""
log.debug(u'screenChanged')
self.RenderManager.update_display()
self.displayManager.setup()
self.setFocus()
self.activateWindow()
@ -863,8 +791,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.plugin_manager.finalise_plugins()
# Save settings
self.saveSettings()
#Close down the displays
self.displayManager.close()
#Close down the display
self.LiveController.display.close()
def serviceChanged(self, reset=False, serviceName=None):
"""
@ -893,7 +821,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def defaultThemeChanged(self, theme):
self.DefaultThemeLabel.setText(
unicode(translate('OpenLP.MainWindow', 'Default Theme: %s')) % theme)
unicode(translate('OpenLP.MainWindow', 'Default Theme: %s')) %
theme)
def toggleMediaManager(self, visible):
if self.MediaManagerDock.isVisible() != visible:
@ -918,7 +847,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
False - Hidden
"""
self.PreviewController.Panel.setVisible(visible)
self.settingsmanager.set_preview_visibility(visible)
QtCore.QSettings().setValue(u'user interface/preview panel',
QtCore.QVariant(visible))
self.ViewPreviewPanel.setChecked(visible)
def setLivePanelVisibility(self, visible):
@ -932,7 +862,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
False - Hidden
"""
self.LiveController.Panel.setVisible(visible)
self.settingsmanager.set_live_visibility(visible)
QtCore.QSettings().setValue(u'user interface/live panel',
QtCore.QVariant(visible))
self.ViewLivePanel.setChecked(visible)
def loadSettings(self):
@ -1014,4 +945,4 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.recentFiles.insert(0, QtCore.QString(filename))
while self.recentFiles.count() > maxRecentFiles:
# Don't care what API says takeLast works, removeLast doesn't!
self.recentFiles.takeLast()
self.recentFiles.takeLast()

View File

@ -80,4 +80,4 @@ class MediaDockManager(object):
if self.media_dock.widget(dock_index).settingsSection == \
name.lower():
self.media_dock.widget(dock_index).hide()
self.media_dock.removeItem(dock_index)
self.media_dock.removeItem(dock_index)

View File

@ -28,91 +28,91 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_PluginViewDialog(object):
def setupUi(self, PluginViewDialog):
PluginViewDialog.setObjectName(u'PluginViewDialog')
PluginViewDialog.setWindowModality(QtCore.Qt.ApplicationModal)
PluginViewDialog.resize(554, 344)
self.PluginLayout = QtGui.QVBoxLayout(PluginViewDialog)
self.PluginLayout.setSpacing(8)
self.PluginLayout.setMargin(8)
self.PluginLayout.setObjectName(u'PluginLayout')
self.ListLayout = QtGui.QHBoxLayout()
self.ListLayout.setSpacing(8)
self.ListLayout.setObjectName(u'ListLayout')
self.PluginListWidget = QtGui.QListWidget(PluginViewDialog)
def setupUi(self, pluginViewDialog):
pluginViewDialog.setObjectName(u'pluginViewDialog')
pluginViewDialog.setWindowModality(QtCore.Qt.ApplicationModal)
pluginViewDialog.resize(554, 344)
self.pluginLayout = QtGui.QVBoxLayout(pluginViewDialog)
self.pluginLayout.setSpacing(8)
self.pluginLayout.setMargin(8)
self.pluginLayout.setObjectName(u'pluginLayout')
self.listLayout = QtGui.QHBoxLayout()
self.listLayout.setSpacing(8)
self.listLayout.setObjectName(u'listLayout')
self.pluginListWidget = QtGui.QListWidget(pluginViewDialog)
sizePolicy = QtGui.QSizePolicy(
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(
self.PluginListWidget.sizePolicy().hasHeightForWidth())
self.PluginListWidget.setSizePolicy(sizePolicy)
self.PluginListWidget.setMaximumSize(QtCore.QSize(192, 16777215))
self.PluginListWidget.setObjectName(u'PluginListWidget')
self.ListLayout.addWidget(self.PluginListWidget)
self.PluginInfoGroupBox = QtGui.QGroupBox(PluginViewDialog)
self.PluginInfoGroupBox.setAlignment(
self.pluginListWidget.sizePolicy().hasHeightForWidth())
self.pluginListWidget.setSizePolicy(sizePolicy)
self.pluginListWidget.setMaximumSize(QtCore.QSize(192, 16777215))
self.pluginListWidget.setObjectName(u'pluginListWidget')
self.listLayout.addWidget(self.pluginListWidget)
self.pluginInfoGroupBox = QtGui.QGroupBox(pluginViewDialog)
self.pluginInfoGroupBox.setAlignment(
QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.PluginInfoGroupBox.setFlat(False)
self.PluginInfoGroupBox.setObjectName(u'PluginInfoGroupBox')
self.PluginInfoLayout = QtGui.QFormLayout(self.PluginInfoGroupBox)
self.PluginInfoLayout.setMargin(8)
self.PluginInfoLayout.setSpacing(8)
self.PluginInfoLayout.setObjectName(u'PluginInfoLayout')
self.VersionLabel = QtGui.QLabel(self.PluginInfoGroupBox)
self.VersionLabel.setObjectName(u'VersionLabel')
self.PluginInfoLayout.setWidget(
1, QtGui.QFormLayout.LabelRole, self.VersionLabel)
self.VersionNumberLabel = QtGui.QLabel(self.PluginInfoGroupBox)
self.VersionNumberLabel.setObjectName(u'VersionNumberLabel')
self.PluginInfoLayout.setWidget(
1, QtGui.QFormLayout.FieldRole, self.VersionNumberLabel)
self.AboutLabel = QtGui.QLabel(self.PluginInfoGroupBox)
self.AboutLabel.setObjectName(u'AboutLabel')
self.PluginInfoLayout.setWidget(
2, QtGui.QFormLayout.LabelRole, self.AboutLabel)
self.StatusLabel = QtGui.QLabel(self.PluginInfoGroupBox)
self.StatusLabel.setObjectName(u'StatusLabel')
self.PluginInfoLayout.setWidget(
0, QtGui.QFormLayout.LabelRole, self.StatusLabel)
self.StatusComboBox = QtGui.QComboBox(self.PluginInfoGroupBox)
self.StatusComboBox.setObjectName(u'StatusComboBox')
self.StatusComboBox.addItem(QtCore.QString())
self.StatusComboBox.addItem(QtCore.QString())
self.PluginInfoLayout.setWidget(
0, QtGui.QFormLayout.FieldRole, self.StatusComboBox)
self.AboutTextBrowser = QtGui.QTextBrowser(self.PluginInfoGroupBox)
self.AboutTextBrowser.setTextInteractionFlags(
self.pluginInfoGroupBox.setFlat(False)
self.pluginInfoGroupBox.setObjectName(u'pluginInfoGroupBox')
self.pluginInfoLayout = QtGui.QFormLayout(self.pluginInfoGroupBox)
self.pluginInfoLayout.setMargin(8)
self.pluginInfoLayout.setSpacing(8)
self.pluginInfoLayout.setObjectName(u'pluginInfoLayout')
self.versionLabel = QtGui.QLabel(self.pluginInfoGroupBox)
self.versionLabel.setObjectName(u'versionLabel')
self.pluginInfoLayout.setWidget(
1, QtGui.QFormLayout.LabelRole, self.versionLabel)
self.versionNumberLabel = QtGui.QLabel(self.pluginInfoGroupBox)
self.versionNumberLabel.setObjectName(u'versionNumberLabel')
self.pluginInfoLayout.setWidget(
1, QtGui.QFormLayout.FieldRole, self.versionNumberLabel)
self.aboutLabel = QtGui.QLabel(self.pluginInfoGroupBox)
self.aboutLabel.setObjectName(u'aboutLabel')
self.pluginInfoLayout.setWidget(
2, QtGui.QFormLayout.LabelRole, self.aboutLabel)
self.statusLabel = QtGui.QLabel(self.pluginInfoGroupBox)
self.statusLabel.setObjectName(u'statusLabel')
self.pluginInfoLayout.setWidget(
0, QtGui.QFormLayout.LabelRole, self.statusLabel)
self.statusComboBox = QtGui.QComboBox(self.pluginInfoGroupBox)
self.statusComboBox.setObjectName(u'statusComboBox')
self.statusComboBox.addItem(QtCore.QString())
self.statusComboBox.addItem(QtCore.QString())
self.pluginInfoLayout.setWidget(
0, QtGui.QFormLayout.FieldRole, self.statusComboBox)
self.aboutTextBrowser = QtGui.QTextBrowser(self.pluginInfoGroupBox)
self.aboutTextBrowser.setTextInteractionFlags(
QtCore.Qt.LinksAccessibleByMouse)
self.AboutTextBrowser.setObjectName(u'AboutTextBrowser')
self.PluginInfoLayout.setWidget(
2, QtGui.QFormLayout.FieldRole, self.AboutTextBrowser)
self.ListLayout.addWidget(self.PluginInfoGroupBox)
self.PluginLayout.addLayout(self.ListLayout)
self.PluginListButtonBox = QtGui.QDialogButtonBox(PluginViewDialog)
self.PluginListButtonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
self.PluginListButtonBox.setObjectName(u'PluginListButtonBox')
self.PluginLayout.addWidget(self.PluginListButtonBox)
self.aboutTextBrowser.setObjectName(u'aboutTextBrowser')
self.pluginInfoLayout.setWidget(
2, QtGui.QFormLayout.FieldRole, self.aboutTextBrowser)
self.listLayout.addWidget(self.pluginInfoGroupBox)
self.pluginLayout.addLayout(self.listLayout)
self.pluginListButtonBox = QtGui.QDialogButtonBox(pluginViewDialog)
self.pluginListButtonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
self.pluginListButtonBox.setObjectName(u'pluginListButtonBox')
self.pluginLayout.addWidget(self.pluginListButtonBox)
self.retranslateUi(PluginViewDialog)
QtCore.QObject.connect(self.PluginListButtonBox,
QtCore.SIGNAL(u'accepted()'), PluginViewDialog.close)
QtCore.QMetaObject.connectSlotsByName(PluginViewDialog)
self.retranslateUi(pluginViewDialog)
QtCore.QObject.connect(self.pluginListButtonBox,
QtCore.SIGNAL(u'accepted()'), pluginViewDialog.close)
QtCore.QMetaObject.connectSlotsByName(pluginViewDialog)
def retranslateUi(self, PluginViewDialog):
PluginViewDialog.setWindowTitle(
def retranslateUi(self, pluginViewDialog):
pluginViewDialog.setWindowTitle(
translate('OpenLP.PluginForm', 'Plugin List'))
self.PluginInfoGroupBox.setTitle(
self.pluginInfoGroupBox.setTitle(
translate('OpenLP.PluginForm', 'Plugin Details'))
self.VersionLabel.setText(
self.versionLabel.setText(
translate('OpenLP.PluginForm', 'Version:'))
self.VersionNumberLabel.setText(
self.versionNumberLabel.setText(
translate('OpenLP.PluginForm', 'TextLabel'))
self.AboutLabel.setText(
self.aboutLabel.setText(
translate('OpenLP.PluginForm', 'About:'))
self.StatusLabel.setText(
self.statusLabel.setText(
translate('OpenLP.PluginForm', 'Status:'))
self.StatusComboBox.setItemText(0,
self.statusComboBox.setItemText(0,
translate('OpenLP.PluginForm', 'Active'))
self.StatusComboBox.setItemText(1,
translate('OpenLP.PluginForm', 'Inactive'))
self.statusComboBox.setItemText(1,
translate('OpenLP.PluginForm', 'Inactive'))

View File

@ -45,11 +45,11 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
self._clearDetails()
# Right, now let's put some signals and slots together!
QtCore.QObject.connect(
self.PluginListWidget,
self.pluginListWidget,
QtCore.SIGNAL(u'itemSelectionChanged()'),
self.onPluginListWidgetSelectionChanged)
QtCore.QObject.connect(
self.StatusComboBox,
self.statusComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onStatusComboBoxChanged)
@ -57,9 +57,9 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
"""
Load the plugin details into the screen
"""
self.PluginListWidget.clear()
self.pluginListWidget.clear()
for plugin in self.parent.plugin_manager.plugins:
item = QtGui.QListWidgetItem(self.PluginListWidget)
item = QtGui.QListWidgetItem(self.pluginListWidget)
# We do this just to make 100% sure the status is an integer as
# sometimes when it's loaded from the config, it isn't cast to int.
plugin.status = int(plugin.status)
@ -79,31 +79,31 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
# If the plugin has an icon, set it!
if plugin.icon:
item.setIcon(plugin.icon)
self.PluginListWidget.addItem(item)
self.pluginListWidget.addItem(item)
def _clearDetails(self):
self.StatusComboBox.setCurrentIndex(-1)
self.VersionNumberLabel.setText(u'')
self.AboutTextBrowser.setHtml(u'')
self.StatusComboBox.setEnabled(False)
self.statusComboBox.setCurrentIndex(-1)
self.versionNumberLabel.setText(u'')
self.aboutTextBrowser.setHtml(u'')
self.statusComboBox.setEnabled(False)
def _setDetails(self):
log.debug('PluginStatus: %s', str(self.activePlugin.status))
self.VersionNumberLabel.setText(self.activePlugin.version)
self.AboutTextBrowser.setHtml(self.activePlugin.about())
self.versionNumberLabel.setText(self.activePlugin.version)
self.aboutTextBrowser.setHtml(self.activePlugin.about())
self.programaticChange = True
status = 1
if self.activePlugin.status == PluginStatus.Active:
status = 0
self.StatusComboBox.setCurrentIndex(status)
self.StatusComboBox.setEnabled(True)
self.statusComboBox.setCurrentIndex(status)
self.statusComboBox.setEnabled(True)
self.programaticChange = False
def onPluginListWidgetSelectionChanged(self):
if self.PluginListWidget.currentItem() is None:
if self.pluginListWidget.currentItem() is None:
self._clearDetails()
return
plugin_name = self.PluginListWidget.currentItem().text().split(u' ')[0]
plugin_name = self.pluginListWidget.currentItem().text().split(u' ')[0]
self.activePlugin = None
for plugin in self.parent.plugin_manager.plugins:
if plugin.name == plugin_name:
@ -134,5 +134,5 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
elif self.activePlugin.status == PluginStatus.Disabled:
status_text = unicode(
translate('OpenLP.PluginForm', '%s (Disabled)'))
self.PluginListWidget.currentItem().setText(
status_text % self.activePlugin.name)
self.pluginListWidget.currentItem().setText(
status_text % self.activePlugin.name)

View File

@ -44,9 +44,9 @@ class ScreenList(object):
self.override = None
self.screen_list = []
self.display_count = 0
#actual display number
# actual display number
self.current_display = 0
#save config display number
# save config display number
self.monitor_number = 0
def add_screen(self, screen):
@ -99,4 +99,4 @@ class ScreenList(object):
user wants to use the correct screen attributes
"""
log.debug(u'reset_current_display')
self.set_current_display(self.current_display)
self.set_current_display(self.current_display)

View File

@ -28,10 +28,10 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_ServiceItemEditDialog(object):
def setupUi(self, ServiceItemEditDialog):
ServiceItemEditDialog.setObjectName(u'ServiceItemEditDialog')
ServiceItemEditDialog.resize(386, 272)
self.layoutWidget = QtGui.QWidget(ServiceItemEditDialog)
def setupUi(self, serviceItemEditDialog):
serviceItemEditDialog.setObjectName(u'serviceItemEditDialog')
serviceItemEditDialog.resize(386, 272)
self.layoutWidget = QtGui.QWidget(serviceItemEditDialog)
self.layoutWidget.setGeometry(QtCore.QRect(20, 20, 351, 241))
self.layoutWidget.setObjectName(u'layoutWidget')
self.outerLayout = QtGui.QVBoxLayout(self.layoutWidget)
@ -47,8 +47,8 @@ class Ui_ServiceItemEditDialog(object):
self.upButton = QtGui.QPushButton(self.layoutWidget)
self.upButton.setObjectName(u'upButton')
self.buttonLayout.addWidget(self.upButton)
spacerItem = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.buttonLayout.addItem(spacerItem)
self.deleteButton = QtGui.QPushButton(self.layoutWidget)
self.deleteButton.setObjectName(u'deleteButton')
@ -59,17 +59,18 @@ class Ui_ServiceItemEditDialog(object):
self.topLayout.addLayout(self.buttonLayout)
self.outerLayout.addLayout(self.topLayout)
self.buttonBox = QtGui.QDialogButtonBox(self.layoutWidget)
self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.outerLayout.addWidget(self.buttonBox)
self.retranslateUi(ServiceItemEditDialog)
QtCore.QMetaObject.connectSlotsByName(ServiceItemEditDialog)
self.retranslateUi(serviceItemEditDialog)
QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog)
def retranslateUi(self, ServiceItemEditDialog):
ServiceItemEditDialog.setWindowTitle(
def retranslateUi(self, serviceItemEditDialog):
serviceItemEditDialog.setWindowTitle(
translate('OpenLP.ServiceItemEditForm', 'Reorder Service Item'))
self.upButton.setText(translate('OpenLP.ServiceItemEditForm', 'Up'))
self.deleteButton.setText(translate('OpenLP.ServiceItemEditForm', 'Delete'))
self.deleteButton.setText(translate('OpenLP.ServiceItemEditForm',
'Delete'))
self.downButton.setText(translate('OpenLP.ServiceItemEditForm', 'Down'))

View File

@ -123,4 +123,4 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
self.itemList.remove(self.itemList[row])
self.itemList.insert(row + 1, temp)
self.loadData()
self.listWidget.setCurrentRow(row + 1)
self.listWidget.setCurrentRow(row + 1)

View File

@ -112,102 +112,102 @@ class ServiceManager(QtGui.QWidget):
self.serviceNoteForm = ServiceNoteForm(self.parent)
self.serviceItemEditForm = ServiceItemEditForm(self.parent)
#start with the layout
self.Layout = QtGui.QVBoxLayout(self)
self.Layout.setSpacing(0)
self.Layout.setMargin(0)
self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0)
self.layout.setMargin(0)
# Create the top toolbar
self.Toolbar = OpenLPToolbar(self)
self.Toolbar.addToolbarButton(
self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'New Service'),
u':/general/general_new.png',
translate('OpenLP.ServiceManager', 'Create a new service'),
self.onNewService)
self.Toolbar.addToolbarButton(
self.toolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Open Service'),
u':/general/general_open.png',
translate('OpenLP.ServiceManager', 'Load an existing service'),
self.onLoadService)
self.Toolbar.addToolbarButton(
self.toolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Save Service'),
u':/general/general_save.png',
translate('OpenLP.ServiceManager', 'Save this service'),
self.onQuickSaveService)
self.Toolbar.addSeparator()
self.ThemeLabel = QtGui.QLabel(translate('OpenLP.ServiceManager', 'Theme:'),
self)
self.ThemeLabel.setMargin(3)
self.Toolbar.addToolbarWidget(u'ThemeLabel', self.ThemeLabel)
self.ThemeComboBox = QtGui.QComboBox(self.Toolbar)
self.ThemeComboBox.setToolTip(translate('OpenLP.ServiceManager',
self.toolbar.addSeparator()
self.themeLabel = QtGui.QLabel(translate('OpenLP.ServiceManager',
'Theme:'), self)
self.themeLabel.setMargin(3)
self.toolbar.addToolbarWidget(u'ThemeLabel', self.themeLabel)
self.themeComboBox = QtGui.QComboBox(self.toolbar)
self.themeComboBox.setToolTip(translate('OpenLP.ServiceManager',
'Select a theme for the service'))
self.ThemeComboBox.setSizeAdjustPolicy(
self.themeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToContents)
self.Toolbar.addToolbarWidget(u'ThemeWidget', self.ThemeComboBox)
self.Layout.addWidget(self.Toolbar)
self.toolbar.addToolbarWidget(u'ThemeWidget', self.themeComboBox)
self.layout.addWidget(self.toolbar)
# Create the service manager list
self.ServiceManagerList = ServiceManagerList(self)
self.ServiceManagerList.setEditTriggers(
self.serviceManagerList = ServiceManagerList(self)
self.serviceManagerList.setEditTriggers(
QtGui.QAbstractItemView.CurrentChanged |
QtGui.QAbstractItemView.DoubleClicked |
QtGui.QAbstractItemView.EditKeyPressed)
self.ServiceManagerList.setDragDropMode(
self.serviceManagerList.setDragDropMode(
QtGui.QAbstractItemView.DragDrop)
self.ServiceManagerList.setAlternatingRowColors(True)
self.ServiceManagerList.setHeaderHidden(True)
self.ServiceManagerList.setExpandsOnDoubleClick(False)
self.ServiceManagerList.setContextMenuPolicy(
self.serviceManagerList.setAlternatingRowColors(True)
self.serviceManagerList.setHeaderHidden(True)
self.serviceManagerList.setExpandsOnDoubleClick(False)
self.serviceManagerList.setContextMenuPolicy(
QtCore.Qt.CustomContextMenu)
QtCore.QObject.connect(self.ServiceManagerList,
QtCore.QObject.connect(self.serviceManagerList,
QtCore.SIGNAL('customContextMenuRequested(QPoint)'),
self.contextMenu)
self.ServiceManagerList.setObjectName(u'ServiceManagerList')
self.serviceManagerList.setObjectName(u'serviceManagerList')
# enable drop
self.ServiceManagerList.__class__.dragEnterEvent = self.dragEnterEvent
self.ServiceManagerList.__class__.dragMoveEvent = self.dragEnterEvent
self.ServiceManagerList.__class__.dropEvent = self.dropEvent
self.Layout.addWidget(self.ServiceManagerList)
self.serviceManagerList.__class__.dragEnterEvent = self.dragEnterEvent
self.serviceManagerList.__class__.dragMoveEvent = self.dragEnterEvent
self.serviceManagerList.__class__.dropEvent = self.dropEvent
self.layout.addWidget(self.serviceManagerList)
# Add the bottom toolbar
self.OrderToolbar = OpenLPToolbar(self)
self.OrderToolbar.addToolbarButton(
self.orderToolbar = OpenLPToolbar(self)
self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move to &top'),
u':/services/service_top.png',
translate('OpenLP.ServiceManager',
'Move item to the top of the service.'),
self.onServiceTop)
self.OrderToolbar.addToolbarButton(
self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &up'),
u':/services/service_up.png',
translate('OpenLP.ServiceManager',
'Move item up one position in the service.'),
self.onServiceUp)
self.OrderToolbar.addToolbarButton(
self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &down'),
u':/services/service_down.png',
translate('OpenLP.ServiceManager',
'Move item down one position in the service.'),
self.onServiceDown)
self.OrderToolbar.addToolbarButton(
self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move to &bottom'),
u':/services/service_bottom.png',
translate('OpenLP.ServiceManager',
'Move item to the end of the service.'),
self.onServiceEnd)
self.OrderToolbar.addSeparator()
self.OrderToolbar.addToolbarButton(
self.orderToolbar.addSeparator()
self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Delete From Service'),
u':/general/general_delete.png',
translate('OpenLP.ServiceManager',
'Delete the selected item from the service.'),
self.onDeleteFromService)
self.Layout.addWidget(self.OrderToolbar)
self.layout.addWidget(self.orderToolbar)
# Connect up our signals and slots
QtCore.QObject.connect(self.ThemeComboBox,
QtCore.QObject.connect(self.themeComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onThemeComboBoxSelected)
QtCore.QObject.connect(self.ServiceManagerList,
QtCore.QObject.connect(self.serviceManagerList,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.makeLive)
QtCore.QObject.connect(self.ServiceManagerList,
QtCore.QObject.connect(self.serviceManagerList,
QtCore.SIGNAL(u'itemCollapsed(QTreeWidgetItem*)'), self.collapsed)
QtCore.QObject.connect(self.ServiceManagerList,
QtCore.QObject.connect(self.serviceManagerList,
QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
@ -268,7 +268,7 @@ class ServiceManager(QtGui.QWidget):
self.suffixes.append(suffix)
def contextMenu(self, point):
item = self.ServiceManagerList.itemAt(point)
item = self.serviceManagerList.itemAt(point)
if item is None:
return
if item.parent() is None:
@ -289,7 +289,7 @@ class ServiceManager(QtGui.QWidget):
self.themeMenu.menuAction().setVisible(False)
if serviceItem[u'service_item'].is_text():
self.themeMenu.menuAction().setVisible(True)
action = self.menu.exec_(self.ServiceManagerList.mapToGlobal(point))
action = self.menu.exec_(self.serviceManagerList.mapToGlobal(point))
if action == self.editAction:
self.remoteEdit()
if action == self.maintainAction:
@ -317,23 +317,22 @@ class ServiceManager(QtGui.QWidget):
self.serviceItemEditForm.setServiceItem(
self.serviceItems[item][u'service_item'])
if self.serviceItemEditForm.exec_():
self.serviceItems[item][u'service_item'] = \
self.serviceItemEditForm.getServiceItem()
self.repaintServiceList(item, 0)
self.addServiceItem(self.serviceItemEditForm.getServiceItem(),
replace=True)
def nextItem(self):
"""
Called by the SlideController to select the
next service item
"""
if len(self.ServiceManagerList.selectedItems()) == 0:
if len(self.serviceManagerList.selectedItems()) == 0:
return
selected = self.ServiceManagerList.selectedItems()[0]
selected = self.serviceManagerList.selectedItems()[0]
lookFor = 0
serviceIterator = QtGui.QTreeWidgetItemIterator(self.ServiceManagerList)
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
while serviceIterator.value():
if lookFor == 1 and serviceIterator.value().parent() is None:
self.ServiceManagerList.setCurrentItem(serviceIterator.value())
self.serviceManagerList.setCurrentItem(serviceIterator.value())
self.makeLive()
return
if serviceIterator.value() == selected:
@ -345,15 +344,15 @@ class ServiceManager(QtGui.QWidget):
Called by the SlideController to select the
previous service item
"""
if len(self.ServiceManagerList.selectedItems()) == 0:
if len(self.serviceManagerList.selectedItems()) == 0:
return
selected = self.ServiceManagerList.selectedItems()[0]
selected = self.serviceManagerList.selectedItems()[0]
prevItem = None
serviceIterator = QtGui.QTreeWidgetItemIterator(self.ServiceManagerList)
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
while serviceIterator.value():
if serviceIterator.value() == selected:
if prevItem:
self.ServiceManagerList.setCurrentItem(prevItem)
self.serviceManagerList.setCurrentItem(prevItem)
self.makeLive()
return
if serviceIterator.value().parent() is None:
@ -370,9 +369,9 @@ class ServiceManager(QtGui.QWidget):
"""
Makes a specific item in the service live
"""
if index >= 0 and index < self.ServiceManagerList.topLevelItemCount:
item = self.ServiceManagerList.topLevelItem(index)
self.ServiceManagerList.setCurrentItem(item)
if index >= 0 and index < self.serviceManagerList.topLevelItemCount:
item = self.serviceManagerList.topLevelItem(index)
self.serviceManagerList.setCurrentItem(item)
self.makeLive()
def onMoveSelectionUp(self):
@ -380,7 +379,7 @@ class ServiceManager(QtGui.QWidget):
Moves the selection up the window
Called by the up arrow
"""
serviceIterator = QtGui.QTreeWidgetItemIterator(self.ServiceManagerList)
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
tempItem = None
setLastItem = False
while serviceIterator:
@ -405,7 +404,7 @@ class ServiceManager(QtGui.QWidget):
Moves the selection down the window
Called by the down arrow
"""
serviceIterator = QtGui.QTreeWidgetItemIterator(self.ServiceManagerList)
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
firstItem = serviceIterator
setSelected = False
while serviceIterator:
@ -498,12 +497,11 @@ class ServiceManager(QtGui.QWidget):
'Your service is unsaved, do you want to save '
'those changes before creating a new one?'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Cancel |
QtGui.QMessageBox.Save),
QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Save),
QtGui.QMessageBox.Save)
if ret == QtGui.QMessageBox.Save:
self.onSaveService()
self.ServiceManagerList.clear()
self.serviceManagerList.clear()
self.serviceItems = []
self.serviceName = u''
self.isNew = True
@ -531,10 +529,10 @@ class ServiceManager(QtGui.QWidget):
item[u'order'] = count
count += 1
#Repaint the screen
self.ServiceManagerList.clear()
self.serviceManagerList.clear()
for itemcount, item in enumerate(self.serviceItems):
serviceitem = item[u'service_item']
treewidgetitem = QtGui.QTreeWidgetItem(self.ServiceManagerList)
treewidgetitem = QtGui.QTreeWidgetItem(self.serviceManagerList)
if serviceitem.is_valid:
if serviceitem.notes:
icon = QtGui.QImage(serviceitem.icon)
@ -565,7 +563,7 @@ class ServiceManager(QtGui.QWidget):
if serviceItem == itemcount and serviceItemCount == count:
#preserve expanding status as setCurrentItem sets it to True
temp = item[u'expanded']
self.ServiceManagerList.setCurrentItem(treewidgetitem1)
self.serviceManagerList.setCurrentItem(treewidgetitem1)
item[u'expanded'] = temp
treewidgetitem.setExpanded(item[u'expanded'])
@ -656,8 +654,7 @@ class ServiceManager(QtGui.QWidget):
'Your current service is unsaved, do you want to '
'save the changes before opening a new one?'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Save),
QtGui.QMessageBox.Discard | QtGui.QMessageBox.Save),
QtGui.QMessageBox.Save)
if ret == QtGui.QMessageBox.Save:
self.onSaveService()
@ -758,7 +755,7 @@ class ServiceManager(QtGui.QWidget):
"""
Set the theme for the current service
"""
self.service_theme = unicode(self.ThemeComboBox.currentText())
self.service_theme = unicode(self.themeComboBox.currentText())
self.parent.RenderManager.set_service_theme(self.service_theme)
QtCore.QSettings().setValue(
self.parent.serviceSettingsSection + u'/service theme',
@ -771,29 +768,29 @@ class ServiceManager(QtGui.QWidget):
sure the theme combo box is in the correct state.
"""
if self.parent.RenderManager.theme_level == ThemeLevel.Global:
self.Toolbar.actions[u'ThemeLabel'].setVisible(False)
self.Toolbar.actions[u'ThemeWidget'].setVisible(False)
self.toolbar.actions[u'ThemeLabel'].setVisible(False)
self.toolbar.actions[u'ThemeWidget'].setVisible(False)
else:
self.Toolbar.actions[u'ThemeLabel'].setVisible(True)
self.Toolbar.actions[u'ThemeWidget'].setVisible(True)
self.toolbar.actions[u'ThemeLabel'].setVisible(True)
self.toolbar.actions[u'ThemeWidget'].setVisible(True)
def regenerateServiceItems(self):
"""
Rebuild the service list as things have changed and a
repaint is the easiest way to do this.
"""
#force reset of renderer as theme data has changed
# force reset of renderer as theme data has changed
self.parent.RenderManager.themedata = None
if self.serviceItems:
tempServiceItems = self.serviceItems
self.ServiceManagerList.clear()
self.serviceManagerList.clear()
self.serviceItems = []
self.isNew = True
for item in tempServiceItems:
self.addServiceItem(
item[u'service_item'], False, item[u'expanded'])
#Set to False as items may have changed rendering
#does not impact the saved song so True may also be valid
# Set to False as items may have changed rendering
# does not impact the saved song so True may also be valid
self.parent.serviceChanged(False, self.serviceName)
def addServiceItem(self, item, rebuild=False, expand=True, replace=False):
@ -802,7 +799,6 @@ class ServiceManager(QtGui.QWidget):
``item``
Service Item to be added
"""
sitem = self.findServiceItem()[0]
item.render()
@ -846,11 +842,8 @@ class ServiceManager(QtGui.QWidget):
else:
QtGui.QMessageBox.critical(self,
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', 'Your item cannot be displayed '
'as there is no handler to display it'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
translate('OpenLP.ServiceManager', 'Your item cannot be '
'displayed as there is no handler to display it'))
def getServiceItem(self):
"""
@ -879,14 +872,12 @@ class ServiceManager(QtGui.QWidget):
ItemCapabilities.AllowsPreview):
self.parent.PreviewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], 0)
self.parent.LiveController.PreviewListWidget.setFocus()
else:
QtGui.QMessageBox.critical(self,
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', 'Your item cannot be displayed '
'as there is no handler to display it'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
translate('OpenLP.ServiceManager', 'Your item cannot be '
'displayed as there is no handler to display it'))
def remoteEdit(self):
"""
@ -903,7 +894,7 @@ class ServiceManager(QtGui.QWidget):
"""
Finds a ServiceItem in the list
"""
items = self.ServiceManagerList.selectedItems()
items = self.serviceManagerList.selectedItems()
pos = 0
count = 0
for item in items:
@ -923,7 +914,6 @@ class ServiceManager(QtGui.QWidget):
``event``
Handle of the event pint passed
"""
event.accept()
@ -939,7 +929,7 @@ class ServiceManager(QtGui.QWidget):
link = event.mimeData()
if link.hasText():
plugin = event.mimeData().text()
item = self.ServiceManagerList.itemAt(event.pos())
item = self.serviceManagerList.itemAt(event.pos())
#ServiceManager started the drag and drop
if plugin == u'ServiceManager':
startpos, startCount = self.findServiceItem()
@ -983,23 +973,21 @@ class ServiceManager(QtGui.QWidget):
``theme_list``
A list of current themes to be displayed
"""
self.ThemeComboBox.clear()
self.themeComboBox.clear()
self.themeMenu.clear()
self.ThemeComboBox.addItem(u'')
self.themeComboBox.addItem(u'')
for theme in theme_list:
self.ThemeComboBox.addItem(theme)
action = context_menu_action(
self.ServiceManagerList,
None,
theme , self.onThemeChangeAction)
self.themeComboBox.addItem(theme)
action = context_menu_action(self.serviceManagerList, None, theme,
self.onThemeChangeAction)
self.themeMenu.addAction(action)
id = self.ThemeComboBox.findText(self.service_theme,
index = self.themeComboBox.findText(self.service_theme,
QtCore.Qt.MatchExactly)
# Not Found
if id == -1:
id = 0
if index == -1:
index = 0
self.service_theme = u''
self.ThemeComboBox.setCurrentIndex(id)
self.themeComboBox.setCurrentIndex(index)
self.parent.RenderManager.set_service_theme(self.service_theme)
self.regenerateServiceItems()
@ -1031,4 +1019,4 @@ class ServiceManager(QtGui.QWidget):
data_item[u'notes'] = unicode(service_item.notes)
data_item[u'selected'] = (item == curitem)
data.append(data_item)
Receiver.send_message(u'servicemanager_list_response', data)
Receiver.send_message(u'servicemanager_list_response', data)

View File

@ -28,10 +28,10 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_ServiceNoteEdit(object):
def setupUi(self, ServiceNoteEdit):
ServiceNoteEdit.setObjectName(u'ServiceNoteEdit')
ServiceNoteEdit.resize(400, 243)
self.widget = QtGui.QWidget(ServiceNoteEdit)
def setupUi(self, serviceNoteEdit):
serviceNoteEdit.setObjectName(u'serviceNoteEdit')
serviceNoteEdit.resize(400, 243)
self.widget = QtGui.QWidget(serviceNoteEdit)
self.widget.setGeometry(QtCore.QRect(20, 10, 361, 223))
self.widget.setObjectName(u'widget')
self.verticalLayout = QtGui.QVBoxLayout(self.widget)
@ -45,9 +45,9 @@ class Ui_ServiceNoteEdit(object):
self.buttonBox.setObjectName(u'buttonBox')
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi(ServiceNoteEdit)
QtCore.QMetaObject.connectSlotsByName(ServiceNoteEdit)
self.retranslateUi(serviceNoteEdit)
QtCore.QMetaObject.connectSlotsByName(serviceNoteEdit)
def retranslateUi(self, ServiceNoteEdit):
ServiceNoteEdit.setWindowTitle(
translate('OpenLP.ServiceNoteForm', 'Service Item Notes'))
def retranslateUi(self, serviceNoteEdit):
serviceNoteEdit.setWindowTitle(
translate('OpenLP.ServiceNoteForm', 'Service Item Notes'))

View File

@ -41,4 +41,4 @@ class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit):
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
self.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
self.reject)
self.reject)

View File

@ -29,19 +29,19 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, build_icon
class Ui_SettingsDialog(object):
def setupUi(self, SettingsDialog):
SettingsDialog.setObjectName(u'SettingsDialog')
SettingsDialog.resize(724, 502)
SettingsDialog.setWindowIcon(
def setupUi(self, settingsDialog):
settingsDialog.setObjectName(u'settingsDialog')
settingsDialog.resize(724, 502)
settingsDialog.setWindowIcon(
build_icon(u':/system/system_settings.png'))
self.settingsLayout = QtGui.QVBoxLayout(SettingsDialog)
self.settingsLayout = QtGui.QVBoxLayout(settingsDialog)
self.settingsLayout.setSpacing(8)
self.settingsLayout.setMargin(8)
self.settingsLayout.setObjectName(u'settingsLayout')
self.settingsTabWidget = QtGui.QTabWidget(SettingsDialog)
self.settingsTabWidget = QtGui.QTabWidget(settingsDialog)
self.settingsTabWidget.setObjectName(u'settingsTabWidget')
self.settingsLayout.addWidget(self.settingsTabWidget)
self.buttonBox = QtGui.QDialogButtonBox(SettingsDialog)
self.buttonBox = QtGui.QDialogButtonBox(settingsDialog)
sizePolicy = QtGui.QSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
@ -55,14 +55,14 @@ class Ui_SettingsDialog(object):
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(u'buttonBox')
self.settingsLayout.addWidget(self.buttonBox)
self.retranslateUi(SettingsDialog)
self.retranslateUi(settingsDialog)
self.settingsTabWidget.setCurrentIndex(0)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'accepted()'), SettingsDialog.accept)
QtCore.SIGNAL(u'accepted()'), settingsDialog.accept)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'rejected()'), SettingsDialog.reject)
QtCore.QMetaObject.connectSlotsByName(SettingsDialog)
QtCore.SIGNAL(u'rejected()'), settingsDialog.reject)
QtCore.QMetaObject.connectSlotsByName(settingsDialog)
def retranslateUi(self, SettingsDialog):
SettingsDialog.setWindowTitle(translate('OpenLP.SettingsForm',
'Configure OpenLP'))
def retranslateUi(self, settingsDialog):
settingsDialog.setWindowTitle(translate('OpenLP.SettingsForm',
'Configure OpenLP'))

View File

@ -94,4 +94,4 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
Run any post-setup code for the tabs on the form
"""
for tabIndex in range(0, self.settingsTabWidget.count()):
self.settingsTabWidget.widget(tabIndex).postSetUp()
self.settingsTabWidget.widget(tabIndex).postSetUp()

View File

@ -25,36 +25,17 @@
###############################################################################
import logging
import time
import os
from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
from openlp.core.ui import HideMode
from openlp.core.ui import HideMode, MainDisplay
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
ItemCapabilities, translate
log = logging.getLogger(__name__)
class SlideThread(QtCore.QThread):
"""
A special Qt thread class to speed up the display of text based frames.
This is threaded so it loads the frames in background
"""
def __init__(self, parent, prefix, count):
QtCore.QThread.__init__(self, parent)
self.prefix = prefix
self.count = count
def run(self):
"""
Run the thread.
"""
time.sleep(1)
for i in range(0, self.count):
Receiver.send_message(u'%s_slide_cache' % self.prefix, i)
class SlideList(QtGui.QTableWidget):
"""
Customised version of QTableWidget which can respond to keyboard
@ -97,7 +78,7 @@ class SlideController(QtGui.QWidget):
SlideController is the slide controller widget. This widget is what the
user uses to control the displaying of verses/slides/etc on the screen.
"""
def __init__(self, parent, settingsmanager, isLive=False):
def __init__(self, parent, settingsmanager, screens, isLive=False):
"""
Set up the Slide Controller.
"""
@ -105,8 +86,10 @@ class SlideController(QtGui.QWidget):
self.settingsmanager = settingsmanager
self.isLive = isLive
self.parent = parent
self.mainDisplay = self.parent.displayManager.mainDisplay
self.displayManager = self.parent.displayManager
self.screens = screens
self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height())
self.display = MainDisplay(self, screens, isLive)
self.loopList = [
u'Start Loop',
u'Loop Separator',
@ -115,13 +98,14 @@ class SlideController(QtGui.QWidget):
self.songEditList = [
u'Edit Song',
]
self.volume = 10
self.timer_id = 0
self.songEdit = False
self.selectedRow = 0
self.serviceItem = None
self.alertTab = None
self.Panel = QtGui.QWidget(parent.ControlSplitter)
self.slideList = {}
self.canDisplay = True
# Layout for holding panel
self.PanelLayout = QtGui.QVBoxLayout(self.Panel)
self.PanelLayout.setSpacing(0)
@ -133,7 +117,8 @@ class SlideController(QtGui.QWidget):
self.split = 1
self.typePrefix = u'live'
else:
self.TypeLabel.setText(translate('OpenLP.SlideController', 'Preview'))
self.TypeLabel.setText(translate('OpenLP.SlideController',
'Preview'))
self.split = 0
self.typePrefix = u'preview'
self.TypeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
@ -177,11 +162,11 @@ class SlideController(QtGui.QWidget):
sizeToolbarPolicy.setHeightForWidth(
self.Toolbar.sizePolicy().hasHeightForWidth())
self.Toolbar.setSizePolicy(sizeToolbarPolicy)
if self.isLive:
self.Toolbar.addToolbarButton(
u'First Slide', u':/slides/slide_first.png',
translate('OpenLP.SlideController', 'Move to first'),
self.onSlideSelectedFirst)
# if self.isLive:
# self.Toolbar.addToolbarButton(
# u'First Slide', u':/slides/slide_first.png',
# translate('OpenLP.SlideController', 'Move to first'),
# self.onSlideSelectedFirst)
self.Toolbar.addToolbarButton(
u'Previous Slide', u':/slides/slide_previous.png',
translate('OpenLP.SlideController', 'Move to previous'),
@ -190,11 +175,11 @@ class SlideController(QtGui.QWidget):
u'Next Slide', u':/slides/slide_next.png',
translate('OpenLP.SlideController', 'Move to next'),
self.onSlideSelectedNext)
if self.isLive:
self.Toolbar.addToolbarButton(
u'Last Slide', u':/slides/slide_last.png',
translate('OpenLP.SlideController', 'Move to last'),
self.onSlideSelectedLast)
# if self.isLive:
# self.Toolbar.addToolbarButton(
# u'Last Slide', u':/slides/slide_last.png',
# translate('OpenLP.SlideController', 'Move to last'),
# self.onSlideSelectedLast)
if self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.HideMenu = QtGui.QToolButton(self.Toolbar)
@ -213,20 +198,24 @@ class SlideController(QtGui.QWidget):
self.ThemeScreen.setCheckable(True)
QtCore.QObject.connect(self.ThemeScreen,
QtCore.SIGNAL("triggered(bool)"), self.onThemeDisplay)
self.DesktopScreen = QtGui.QAction(QtGui.QIcon(
u':/slides/slide_desktop.png'), u'Show Desktop', self.HideMenu)
self.DesktopScreen.setCheckable(True)
QtCore.QObject.connect(self.DesktopScreen,
QtCore.SIGNAL("triggered(bool)"), self.onHideDisplay)
if self.screens.display_count > 1:
self.DesktopScreen = QtGui.QAction(QtGui.QIcon(
u':/slides/slide_desktop.png'), u'Show Desktop',
self.HideMenu)
self.DesktopScreen.setCheckable(True)
QtCore.QObject.connect(self.DesktopScreen,
QtCore.SIGNAL("triggered(bool)"), self.onHideDisplay)
self.HideMenu.setDefaultAction(self.BlankScreen)
self.HideMenu.menu().addAction(self.BlankScreen)
self.HideMenu.menu().addAction(self.ThemeScreen)
self.HideMenu.menu().addAction(self.DesktopScreen)
if self.screens.display_count > 1:
self.HideMenu.menu().addAction(self.DesktopScreen)
if not self.isLive:
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton(
u'Go Live', u':/general/general_live.png',
translate('OpenLP.SlideController', 'Move to live'), self.onGoLive)
translate('OpenLP.SlideController', 'Move to live'),
self.onGoLive)
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton(
u'Edit Song', u':/general/general_edit.png',
@ -247,11 +236,12 @@ class SlideController(QtGui.QWidget):
self.DelaySpinBox.setMaximum(180)
self.Toolbar.addToolbarWidget(
u'Image SpinBox', self.DelaySpinBox)
self.DelaySpinBox.setSuffix(translate('OpenLP.SlideController', 's'))
self.DelaySpinBox.setSuffix(translate('OpenLP.SlideController',
's'))
self.DelaySpinBox.setToolTip(translate('OpenLP.SlideController',
'Delay between slides in seconds'))
self.ControllerLayout.addWidget(self.Toolbar)
#Build a Media ToolBar
# Build a Media ToolBar
self.Mediabar = OpenLPToolbar(self)
self.Mediabar.addToolbarButton(
u'Media Start', u':/slides/media_playback_start.png',
@ -271,19 +261,30 @@ class SlideController(QtGui.QWidget):
self.seekSlider.setObjectName(u'seekSlider')
self.Mediabar.addToolbarWidget(
u'Seek Slider', self.seekSlider)
self.volumeSlider = Phonon.VolumeSlider()
self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.volumeSlider.setObjectName(u'volumeSlider')
self.Mediabar.addToolbarWidget(u'Audio Volume', self.volumeSlider)
self.volumeSlider = Phonon.VolumeSlider()
self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.volumeSlider.setObjectName(u'volumeSlider')
self.Mediabar.addToolbarWidget(u'Audio Volume', self.volumeSlider)
else:
self.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
self.volumeSlider.setTickInterval(1)
self.volumeSlider.setTickPosition(QtGui.QSlider.TicksAbove)
self.volumeSlider.setMinimum(0)
self.volumeSlider.setMaximum(10)
self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
self.volumeSlider.setObjectName(u'volumeSlider')
self.Mediabar.addToolbarWidget(u'Audio Volume', self.volumeSlider)
self.ControllerLayout.addWidget(self.Mediabar)
# Build the Song Toolbar
if isLive:
self.SongMenu = QtGui.QToolButton(self.Toolbar)
self.SongMenu.setText(translate('OpenLP.SlideController', 'Go to Verse'))
self.SongMenu.setText(translate('OpenLP.SlideController',
'Go to Verse'))
self.SongMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
self.Toolbar.addToolbarWidget(u'Song Menu', self.SongMenu)
self.SongMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Go to Verse'), self.Toolbar))
translate('OpenLP.SlideController', 'Go to Verse'),
self.Toolbar))
self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
# Screen preview area
self.PreviewFrame = QtGui.QFrame(self.Splitter)
@ -322,7 +323,7 @@ class SlideController(QtGui.QWidget):
self.SlidePreview.setSizePolicy(sizePolicy)
self.SlidePreview.setFixedSize(
QtCore.QSize(self.settingsmanager.slidecontroller_image,
self.settingsmanager.slidecontroller_image / 1.3 ))
self.settingsmanager.slidecontroller_image / self.ratio))
self.SlidePreview.setFrameShape(QtGui.QFrame.Box)
self.SlidePreview.setFrameShadow(QtGui.QFrame.Plain)
self.SlidePreview.setLineWidth(1)
@ -390,17 +391,37 @@ class SlideController(QtGui.QWidget):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.refreshServiceItem)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_slide_cache' % self.typePrefix), self.slideCache)
QtCore.SIGNAL(u'config_screen_changed'), self.screenSizeChanged)
if self.isLive:
QtCore.QObject.connect(self.volumeSlider,
QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume)
def screenSizeChanged(self):
"""
Settings dialog has changed the screen size of adjust output and
screen previews
"""
log.debug(u'screenSizeChanged live = %s' % self.isLive)
# rebuild display as screen size changed
self.display = MainDisplay(self, self.screens, self.isLive)
self.display.alertTab = self.alertTab
self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height())
self.display.setup()
self.SlidePreview.setFixedSize(
QtCore.QSize(self.settingsmanager.slidecontroller_image,
self.settingsmanager.slidecontroller_image / self.ratio))
def widthChanged(self):
"""
Handle changes of width from the splitter between the live and preview
controller. Event only issues when changes have finished
"""
log.debug(u'widthChanged live = %s' % self.isLive)
width = self.parent.ControlSplitter.sizes()[self.split]
height = width * self.parent.RenderManager.screen_ratio
self.PreviewListWidget.setColumnWidth(0, width)
#Sort out image heights (Songs, bibles excluded)
# Sort out image heights (Songs, bibles excluded)
if self.serviceItem and not self.serviceItem.is_text():
for framenumber in range(len(self.serviceItem.get_frames())):
self.PreviewListWidget.setRowHeight(framenumber, height)
@ -453,8 +474,6 @@ class SlideController(QtGui.QWidget):
if item.is_media():
self.Toolbar.setVisible(False)
self.Mediabar.setVisible(True)
#self.volumeSlider.setAudioOutput(
# self.mainDisplay.videoDisplay.audio)
def enablePreviewToolBar(self, item):
"""
@ -474,22 +493,20 @@ class SlideController(QtGui.QWidget):
"""
Method to update the service item if the screen has changed
"""
log.debug(u'refreshServiceItem')
log.debug(u'refreshServiceItem live = %s' % self.isLive)
if self.serviceItem:
if self.serviceItem.is_text() or self.serviceItem.is_image():
item = self.serviceItem
item.render()
self.addServiceManagerItem(item, self.selectedRow)
self._processItem(item, self.selectedRow)
def addServiceItem(self, item):
"""
Method to install the service item into the controller
Called by plugins
"""
log.debug(u'addServiceItem')
before = time.time()
log.debug(u'addServiceItem live = %s' % self.isLive)
item.render()
log.log(15, u'Rendering took %4s' % (time.time() - before))
slideno = 0
if self.songEdit:
slideno = self.selectedRow
@ -509,8 +526,8 @@ class SlideController(QtGui.QWidget):
request the correct toolbar for the plugin.
Called by ServiceManager
"""
log.debug(u'addServiceManagerItem')
#If service item is the same as the current on only change slide
log.debug(u'addServiceManagerItem live = %s' % self.isLive)
# If service item is the same as the current on only change slide
if item.__eq__(self.serviceItem):
self.PreviewListWidget.selectRow(slideno)
self.onSlideSelected()
@ -522,17 +539,15 @@ class SlideController(QtGui.QWidget):
Loads a ServiceItem into the system from ServiceManager
Display the slide number passed
"""
log.debug(u'processManagerItem')
log.debug(u'processManagerItem live = %s' % self.isLive)
self.onStopLoop()
#If old item was a command tell it to stop
# If old item was a command tell it to stop
if self.serviceItem:
if self.serviceItem.is_command():
Receiver.send_message(u'%s_stop' %
self.serviceItem.name.lower(), [serviceItem, self.isLive])
if self.serviceItem.is_media():
self.onMediaStop()
if serviceItem.is_media():
self.onMediaStart(serviceItem)
if self.isLive:
blanked = self.BlankScreen.isChecked()
else:
@ -541,12 +556,8 @@ class SlideController(QtGui.QWidget):
[serviceItem, self.isLive, blanked, slideno])
self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split]
#Set pointing cursor when we have somthing to point at
# Set pointing cursor when we have somthing to point at
self.PreviewListWidget.setCursor(QtCore.Qt.PointingHandCursor)
before = time.time()
#Clear the old serviceItem cache to release memory
if self.serviceItem and self.serviceItem is not serviceItem:
self.serviceItem.clear_cache()
self.serviceItem = serviceItem
self.PreviewListWidget.clear()
self.PreviewListWidget.setRowCount(0)
@ -560,20 +571,19 @@ class SlideController(QtGui.QWidget):
self.PreviewListWidget.rowCount() + 1)
item = QtGui.QTableWidgetItem()
slideHeight = 0
#It is a based Text Render
if self.serviceItem.is_text():
if frame[u'verseTag']:
bits = frame[u'verseTag'].split(u':')
tag = u'%s\n%s' % (bits[0][0], bits[1][0:] )
tag1 = u'%s%s' % (bits[0][0], bits[1][0:] )
row = tag
if self.isLive:
if tag1 not in self.slideList:
self.slideList[tag1] = framenumber
self.SongMenu.menu().addAction(tag1,
self.onSongBarHandler)
else:
row += 1
if self.isLive and frame[u'verseTag'] is not None:
if tag1 not in self.slideList:
self.slideList[tag1] = framenumber
self.SongMenu.menu().addAction(tag1,
self.onSongBarHandler)
item.setText(frame[u'text'])
else:
label = QtGui.QLabel()
@ -600,15 +610,14 @@ class SlideController(QtGui.QWidget):
else:
self.PreviewListWidget.selectRow(slideno)
self.enableToolBar(serviceItem)
# Pass to display for viewing
self.display.buildHtml(self.serviceItem)
if serviceItem.is_media():
self.onMediaStart(serviceItem)
self.onSlideSelected()
self.PreviewListWidget.setFocus()
Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix,
[serviceItem])
if self.serviceItem.is_text():
st = SlideThread(
self, self.typePrefix, len(self.serviceItem.get_frames()))
st.start()
log.log(15, u'Display Rendering took %4s' % (time.time() - before))
def onTextRequest(self):
"""
@ -620,7 +629,7 @@ class SlideController(QtGui.QWidget):
dataItem = {}
if self.serviceItem.is_text():
dataItem[u'tag'] = unicode(frame[u'verseTag'])
dataItem[u'text'] = unicode(frame[u'text'])
dataItem[u'text'] = unicode(frame[u'html'])
else:
dataItem[u'tag'] = unicode(framenumber)
dataItem[u'text'] = u''
@ -630,7 +639,7 @@ class SlideController(QtGui.QWidget):
Receiver.send_message(u'slidecontroller_%s_text_response'
% self.typePrefix, data)
#Screen event methods
# Screen event methods
def onSlideSelectedFirst(self):
"""
Go to the first slide.
@ -664,9 +673,9 @@ class SlideController(QtGui.QWidget):
"""
Allow the main display to blank the main display at startup time
"""
log.debug(u'mainDisplaySetBackground')
if not self.mainDisplay.primary:
self.onBlankDisplay(True)
log.debug(u'mainDisplaySetBackground live = %s' % self.isLive)
if not self.display.primary:
self.onHideDisplay(True)
def onSlideBlank(self):
"""
@ -688,7 +697,8 @@ class SlideController(QtGui.QWidget):
self.HideMenu.setDefaultAction(self.BlankScreen)
self.BlankScreen.setChecked(checked)
self.ThemeScreen.setChecked(False)
self.DesktopScreen.setChecked(False)
if self.screens.display_count > 1:
self.DesktopScreen.setChecked(False)
QtCore.QSettings().setValue(
self.parent.generalSettingsSection + u'/screen blank',
QtCore.QVariant(checked))
@ -706,7 +716,8 @@ class SlideController(QtGui.QWidget):
self.HideMenu.setDefaultAction(self.ThemeScreen)
self.BlankScreen.setChecked(False)
self.ThemeScreen.setChecked(checked)
self.DesktopScreen.setChecked(False)
if self.screens.display_count > 1:
self.DesktopScreen.setChecked(False)
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Theme)
else:
@ -721,7 +732,8 @@ class SlideController(QtGui.QWidget):
self.HideMenu.setDefaultAction(self.DesktopScreen)
self.BlankScreen.setChecked(False)
self.ThemeScreen.setChecked(False)
self.DesktopScreen.setChecked(checked)
if self.screens.display_count > 1:
self.DesktopScreen.setChecked(checked)
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
else:
@ -758,13 +770,6 @@ class SlideController(QtGui.QWidget):
% self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
def slideCache(self, slide):
"""
Generate a slide cache item rendered and ready for use
in the background.
"""
self.serviceItem.get_rendered_frame(int(slide))
def onSlideSelected(self):
"""
Generate the preview when you click on a slide.
@ -778,24 +783,15 @@ class SlideController(QtGui.QWidget):
if self.serviceItem.is_command() and self.isLive:
self.updatePreview()
else:
before = time.time()
frame = self.serviceItem.get_rendered_frame(row)
frame, raw_html = self.serviceItem.get_rendered_frame(row)
if self.serviceItem.is_text():
frame = self.display.text(raw_html)
else:
self.display.image(frame)
if isinstance(frame, QtGui.QImage):
self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
else:
if isinstance(frame[u'main'], basestring):
self.SlidePreview.setPixmap(
QtGui.QPixmap(frame[u'main']))
else:
self.SlidePreview.setPixmap(
QtGui.QPixmap.fromImage(frame[u'main']))
log.log(
15, u'Slide Rendering took %4s' % (time.time() - before))
if self.isLive:
if self.serviceItem.is_text():
self.mainDisplay.frameView(frame, True)
else:
self.displayManager.displayImage(frame[u'main'])
self.SlidePreview.setPixmap(QtGui.QPixmap(frame))
self.selectedRow = row
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row)
@ -810,8 +806,7 @@ class SlideController(QtGui.QWidget):
row)
def updatePreview(self):
rm = self.parent.RenderManager
if not rm.screens.current[u'primary']:
if not self.screens.current[u'primary']:
# Grab now, but try again in a couple of seconds if slide change
# is slow
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
@ -819,12 +814,12 @@ class SlideController(QtGui.QWidget):
else:
label = self.PreviewListWidget.cellWidget(
self.PreviewListWidget.currentRow(), 1)
self.SlidePreview.setPixmap(label.pixmap())
if label:
self.SlidePreview.setPixmap(label.pixmap())
def grabMainDisplay(self):
rm = self.parent.RenderManager
winid = QtGui.QApplication.desktop().winId()
rect = rm.screens.current[u'size']
rect = self.screens.current[u'size']
winimg = QtGui.QPixmap.grabWindow(winid, rect.x(),
rect.y(), rect.width(), rect.height())
self.SlidePreview.setPixmap(winimg)
@ -941,7 +936,9 @@ class SlideController(QtGui.QWidget):
"""
log.debug(u'SlideController onMediaStart')
if self.isLive:
Receiver.send_message(u'videodisplay_start', item)
file = os.path.join(item.get_frame_path(), item.get_frame_title())
self.display.video(file, self.volume)
self.volumeSlider.setValue(self.volume)
else:
self.mediaObject.stop()
self.mediaObject.clearQueue()
@ -951,13 +948,21 @@ class SlideController(QtGui.QWidget):
self.seekSlider.show()
self.onMediaPlay()
def mediaVolume(self):
"""
Respond to the release of Volume Slider
"""
log.debug(u'SlideController mediaVolume')
self.volume = self.volumeSlider.value()
self.display.videoVolume(self.volume)
def onMediaPause(self):
"""
Respond to the Pause from the media Toolbar
"""
log.debug(u'SlideController onMediaPause')
if self.isLive:
Receiver.send_message(u'videodisplay_pause')
self.display.videoPause()
else:
self.mediaObject.pause()
@ -967,7 +972,7 @@ class SlideController(QtGui.QWidget):
"""
log.debug(u'SlideController onMediaPlay')
if self.isLive:
Receiver.send_message(u'videodisplay_play')
self.display.videoPlay()
else:
self.SlidePreview.hide()
self.video.show()
@ -979,9 +984,9 @@ class SlideController(QtGui.QWidget):
"""
log.debug(u'SlideController onMediaStop')
if self.isLive:
Receiver.send_message(u'videodisplay_stop')
self.display.videoStop()
else:
self.mediaObject.stop()
self.video.hide()
self.SlidePreview.clear()
self.SlidePreview.show()
self.SlidePreview.show()

View File

@ -27,7 +27,7 @@
from PyQt4 import QtCore, QtGui
class SplashScreen(object):
def __init__(self, version):
def __init__(self):
self.splash_screen = QtGui.QSplashScreen()
self.setupUi()
@ -55,4 +55,4 @@ class SplashScreen(object):
self.splash_screen.show()
def finish(self, widget):
self.splash_screen.finish(widget)
self.splash_screen.finish(widget)

View File

@ -49,71 +49,71 @@ class ThemeManager(QtGui.QWidget):
QtGui.QWidget.__init__(self, parent)
self.parent = parent
self.settingsSection = u'themes'
self.serviceComboBox = self.parent.ServiceManagerContents.ThemeComboBox
self.Layout = QtGui.QVBoxLayout(self)
self.Layout.setSpacing(0)
self.Layout.setMargin(0)
self.serviceComboBox = self.parent.ServiceManagerContents.themeComboBox
self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0)
self.layout.setMargin(0)
self.amendThemeForm = AmendThemeForm(self)
self.Toolbar = OpenLPToolbar(self)
self.Toolbar.addToolbarButton(
self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'New Theme'),
u':/themes/theme_new.png',
translate('OpenLP.ThemeManager', 'Create a new theme.'),
self.onAddTheme)
self.Toolbar.addToolbarButton(
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Edit Theme'),
u':/themes/theme_edit.png',
translate('OpenLP.ThemeManager', 'Edit a theme.'),
self.onEditTheme)
self.Toolbar.addToolbarButton(
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Delete Theme'),
u':/general/general_delete.png',
translate('OpenLP.ThemeManager', 'Delete a theme.'),
self.onDeleteTheme)
self.Toolbar.addSeparator()
self.Toolbar.addToolbarButton(
self.toolbar.addSeparator()
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Import Theme'),
u':/general/general_import.png',
translate('OpenLP.ThemeManager', 'Import a theme.'),
self.onImportTheme)
self.Toolbar.addToolbarButton(
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Export Theme'),
u':/general/general_export.png',
translate('OpenLP.ThemeManager', 'Export a theme.'),
self.onExportTheme)
self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
self.Layout.addWidget(self.Toolbar)
self.ThemeListWidget = QtGui.QListWidget(self)
self.ThemeListWidget.setAlternatingRowColors(True)
self.ThemeListWidget.setIconSize(QtCore.QSize(88, 50))
self.Layout.addWidget(self.ThemeListWidget)
self.ThemeListWidget.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
self.ThemeListWidget.addAction(
context_menu_action(self.ThemeListWidget,
self.themeWidget = QtGui.QWidgetAction(self.toolbar)
self.layout.addWidget(self.toolbar)
self.themeListWidget = QtGui.QListWidget(self)
self.themeListWidget.setAlternatingRowColors(True)
self.themeListWidget.setIconSize(QtCore.QSize(88, 50))
self.layout.addWidget(self.themeListWidget)
self.themeListWidget.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
self.themeListWidget.addAction(
context_menu_action(self.themeListWidget,
u':/themes/theme_edit.png',
translate('OpenLP.ThemeManager', '&Edit Theme'),
self.onEditTheme))
self.ThemeListWidget.addAction(
context_menu_separator(self.ThemeListWidget))
self.ThemeListWidget.addAction(
context_menu_action(self.ThemeListWidget,
self.themeListWidget.addAction(
context_menu_separator(self.themeListWidget))
self.themeListWidget.addAction(
context_menu_action(self.themeListWidget,
u':/general/general_delete.png',
translate('OpenLP.ThemeManager', '&Delete Theme'),
self.onDeleteTheme))
self.ThemeListWidget.addAction(
context_menu_action(self.ThemeListWidget,
self.themeListWidget.addAction(
context_menu_action(self.themeListWidget,
u':/general/general_export.png',
translate('OpenLP.ThemeManager', 'Set As &Global Default'),
self.changeGlobalFromScreen))
self.ThemeListWidget.addAction(
context_menu_action(self.ThemeListWidget,
self.themeListWidget.addAction(
context_menu_action(self.themeListWidget,
u':/general/general_export.png',
translate('OpenLP.ThemeManager', 'E&xport Theme'),
self.onExportTheme))
self.ThemeListWidget.addAction(
context_menu_separator(self.ThemeListWidget))
self.themeListWidget.addAction(
context_menu_separator(self.themeListWidget))
#Signals
QtCore.QObject.connect(self.ThemeListWidget,
QtCore.QObject.connect(self.themeListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.changeGlobalFromScreen)
QtCore.QObject.connect(Receiver.get_receiver(),
@ -138,18 +138,18 @@ class ThemeManager(QtGui.QWidget):
tab
"""
log.debug(u'changeGlobalFromTab %s', themeName)
for count in range (0, self.ThemeListWidget.count()):
#reset the old name
item = self.ThemeListWidget.item(count)
for count in range (0, self.themeListWidget.count()):
# reset the old name
item = self.themeListWidget.item(count)
oldName = item.text()
newName = unicode(item.data(QtCore.Qt.UserRole).toString())
if oldName != newName:
self.ThemeListWidget.item(count).setText(newName)
#Set the new name
self.themeListWidget.item(count).setText(newName)
# Set the new name
if themeName == newName:
name = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % newName
self.ThemeListWidget.item(count).setText(name)
self.themeListWidget.item(count).setText(name)
def changeGlobalFromScreen(self, index = -1):
"""
@ -157,21 +157,21 @@ class ThemeManager(QtGui.QWidget):
Theme Manager list
"""
log.debug(u'changeGlobalFromScreen %s', index)
selected_row = self.ThemeListWidget.currentRow()
for count in range (0, self.ThemeListWidget.count()):
item = self.ThemeListWidget.item(count)
selected_row = self.themeListWidget.currentRow()
for count in range (0, self.themeListWidget.count()):
item = self.themeListWidget.item(count)
oldName = item.text()
#reset the old name
# reset the old name
if oldName != unicode(item.data(QtCore.Qt.UserRole).toString()):
self.ThemeListWidget.item(count).setText(
self.themeListWidget.item(count).setText(
unicode(item.data(QtCore.Qt.UserRole).toString()))
#Set the new name
# Set the new name
if count == selected_row:
self.global_theme = unicode(
self.ThemeListWidget.item(count).text())
self.themeListWidget.item(count).text())
name = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % self.global_theme
self.ThemeListWidget.item(count).setText(name)
self.themeListWidget.item(count).setText(name)
QtCore.QSettings().setValue(
self.settingsSection + u'/global theme',
QtCore.QVariant(self.global_theme))
@ -194,10 +194,10 @@ class ThemeManager(QtGui.QWidget):
Loads the settings for the theme that is to be edited and launches the
theme editing form so the user can make their changes.
"""
if check_item_selected(self.ThemeListWidget,
if check_item_selected(self.themeListWidget,
translate('OpenLP.ThemeManager',
'You must select a theme to edit.')):
item = self.ThemeListWidget.currentItem()
item = self.themeListWidget.currentItem()
themeName = unicode(item.text())
if themeName != unicode(item.data(QtCore.Qt.UserRole).toString()):
self.editingDefault = True
@ -217,10 +217,10 @@ class ThemeManager(QtGui.QWidget):
self.global_theme = unicode(QtCore.QSettings().value(
self.settingsSection + u'/global theme',
QtCore.QVariant(u'')).toString())
if check_item_selected(self.ThemeListWidget,
if check_item_selected(self.themeListWidget,
translate('OpenLP.ThemeManager',
'You must select a theme to delete.')):
item = self.ThemeListWidget.currentItem()
item = self.themeListWidget.currentItem()
theme = unicode(item.text())
# confirm deletion
answer = QtGui.QMessageBox.question(self,
@ -235,8 +235,7 @@ class ThemeManager(QtGui.QWidget):
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'),
translate('OpenLP.ThemeManager',
'You are unable to delete the default theme.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
'You are unable to delete the default theme.'))
else:
for plugin in self.parent.plugin_manager.plugins:
if plugin.usesTheme(theme):
@ -252,8 +251,8 @@ class ThemeManager(QtGui.QWidget):
unicode(translate('OpenLP.ThemeManager',
'Theme %s is use by the service manager.')) % theme)
return
row = self.ThemeListWidget.row(item)
self.ThemeListWidget.takeItem(row)
row = self.themeListWidget.row(item)
self.themeListWidget.takeItem(row)
self.deleteTheme(theme)
def deleteTheme(self, theme):
@ -281,7 +280,7 @@ class ThemeManager(QtGui.QWidget):
"""
Save the theme in a zip file
"""
item = self.ThemeListWidget.currentItem()
item = self.themeListWidget.currentItem()
if item is None:
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'),
@ -296,7 +295,7 @@ class ThemeManager(QtGui.QWidget):
path = unicode(path)
if path:
SettingsManager.set_last_dir(self.settingsSection, path, 1)
themePath = os.path.join(path, theme + u'.theme')
themePath = os.path.join(path, theme + u'.otz')
zip = None
try:
zip = zipfile.ZipFile(themePath, u'w')
@ -346,12 +345,11 @@ class ThemeManager(QtGui.QWidget):
"""
log.debug(u'Load themes from dir')
self.themelist = []
self.ThemeListWidget.clear()
#root, dirs, files = os.walk(self.path)
self.themeListWidget.clear()
dirList = os.listdir(self.path)
for name in dirList:
if name.endswith(u'.png'):
#check to see file is in theme root directory
# check to see file is in theme root directory
theme = os.path.join(self.path, name)
if os.path.exists(theme):
textName = os.path.splitext(name)[0]
@ -371,7 +369,7 @@ class ThemeManager(QtGui.QWidget):
item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole,
QtCore.QVariant(textName))
self.ThemeListWidget.addItem(item_name)
self.themeListWidget.addItem(item_name)
self.themelist.append(textName)
self.pushThemes()
@ -622,15 +620,15 @@ class ThemeManager(QtGui.QWidget):
self.serviceComboBox.setCurrentIndex(newThemeIndex)
if self.editingDefault:
if self.saveThemeName != name:
newThemeItem = self.ThemeListWidget.findItems(name,
newThemeItem = self.themeListWidget.findItems(name,
QtCore.Qt.MatchExactly)[0]
newThemeIndex = self.ThemeListWidget.indexFromItem(
newThemeIndex = self.themeListWidget.indexFromItem(
newThemeItem).row()
self.global_theme = unicode(
self.ThemeListWidget.item(newThemeIndex).text())
self.themeListWidget.item(newThemeIndex).text())
newName = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % self.global_theme
self.ThemeListWidget.item(newThemeIndex).setText(newName)
self.themeListWidget.item(newThemeIndex).setText(newName)
QtCore.QSettings().setValue(
self.settingsSection + u'/global theme',
QtCore.QVariant(self.global_theme))
@ -661,9 +659,8 @@ class ThemeManager(QtGui.QWidget):
"""
Call the RenderManager to build a Sample Image
"""
log.debug(u'generateImage %s ', themedata)
frame = self.parent.RenderManager.generate_preview(themedata)
return frame
log.debug(u'generateImage \n%s ', themedata)
return self.parent.RenderManager.generate_preview(themedata)
def getPreviewImage(self, theme):
"""
@ -733,8 +730,6 @@ class ThemeManager(QtGui.QWidget):
theme.display_slideTransition = theme.display_slideTransition
theme.font_footer_color = theme.font_footer_color.strip()
theme.font_footer_height = int(theme.font_footer_height.strip())
theme.font_footer_indentation = \
int(theme.font_footer_indentation.strip())
theme.font_footer_italics = str_to_bool(theme.font_footer_italics)
theme.font_footer_name = theme.font_footer_name.strip()
#theme.font_footer_override
@ -747,7 +742,6 @@ class ThemeManager(QtGui.QWidget):
theme.font_main_color = theme.font_main_color.strip()
theme.font_main_height = int(theme.font_main_height.strip())
theme.font_main_italics = str_to_bool(theme.font_main_italics)
theme.font_main_indentation = int(theme.font_main_indentation)
theme.font_main_name = theme.font_main_name.strip()
#theme.font_main_override
theme.font_main_proportion = int(theme.font_main_proportion.strip())
@ -757,4 +751,9 @@ class ThemeManager(QtGui.QWidget):
theme.font_main_y = int(theme.font_main_y.strip())
#theme.theme_mode
theme.theme_name = theme.theme_name.strip()
#theme.theme_version
#theme.theme_version
# Remove the Transparent settings as they are not relevent
if theme.background_mode == u'transparent':
theme.background_mode = u'opaque'
theme.background_type = u'solid'
theme.background_startColor = u'#000000'

View File

@ -207,4 +207,4 @@ class ThemesTab(SettingsTab):
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(preview)
self.DefaultListView.setPixmap(preview)

View File

@ -27,20 +27,70 @@
The :mod:`utils` module provides the utility libraries for OpenLP
"""
import os
import sys
import logging
import os
import re
import sys
import time
import urllib2
from datetime import datetime
from PyQt4 import QtGui, QtCore
import openlp
from openlp.core.lib import translate
from openlp.core.lib import Receiver, translate
log = logging.getLogger(__name__)
images_filter = None
class VersionThread(QtCore.QThread):
"""
A special Qt thread class to fetch the version of OpenLP from the website.
This is threaded so that it doesn't affect the loading time of OpenLP.
"""
def __init__(self, parent, app_version):
QtCore.QThread.__init__(self, parent)
self.app_version = app_version
self.version_splitter = re.compile(
r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))?')
def run(self):
"""
Run the thread.
"""
time.sleep(1)
Receiver.send_message(u'maindisplay_blank_check')
version = check_latest_version(self.app_version)
remote_version = {}
local_version = {}
match = self.version_splitter.match(version)
if match:
remote_version[u'major'] = int(match.group(1))
remote_version[u'minor'] = int(match.group(2))
remote_version[u'release'] = int(match.group(3))
if len(match.groups()) > 3 and match.group(4):
remote_version[u'revision'] = int(match.group(4))
else:
return
match = self.version_splitter.match(self.app_version[u'full'])
if match:
local_version[u'major'] = int(match.group(1))
local_version[u'minor'] = int(match.group(2))
local_version[u'release'] = int(match.group(3))
if len(match.groups()) > 3 and match.group(4):
local_version[u'revision'] = int(match.group(4))
else:
return
if remote_version[u'major'] > local_version[u'major'] or \
remote_version[u'minor'] > local_version[u'minor'] or \
remote_version[u'release'] > local_version[u'release']:
Receiver.send_message(u'openlp_version_check', u'%s' % version)
elif remote_version.get(u'revision') and \
local_version.get(u'revision') and \
remote_version[u'revision'] > local_version[u'revision']:
Receiver.send_message(u'openlp_version_check', u'%s' % version)
class AppLocation(object):
"""
The :class:`AppLocation` class is a static class which retrieves a
@ -101,10 +151,10 @@ class AppLocation(object):
return plugin_path
elif dir_type == AppLocation.VersionDir:
if hasattr(sys, u'frozen') and sys.frozen == 1:
plugin_path = os.path.abspath(os.path.split(sys.argv[0])[0])
version_path = os.path.abspath(os.path.split(sys.argv[0])[0])
else:
plugin_path = os.path.split(openlp.__file__)[0]
return plugin_path
version_path = os.path.split(openlp.__file__)[0]
return version_path
elif dir_type == AppLocation.CacheDir:
if sys.platform == u'win32':
path = os.path.join(os.getenv(u'APPDATA'), u'openlp')
@ -160,11 +210,14 @@ def check_latest_version(current_version):
else:
req = urllib2.Request(u'http://www.openlp.org/files/version.txt')
req.add_header(u'User-Agent', u'OpenLP/%s' % current_version[u'full'])
remote_version = None
try:
version_string = unicode(urllib2.urlopen(req, None).read()).strip()
remote_version = unicode(urllib2.urlopen(req, None).read()).strip()
except IOError, e:
if hasattr(e, u'reason'):
log.exception(u'Reason for failure: %s', e.reason)
if remote_version:
version_string = remote_version
return version_string
def add_actions(target, actions):
@ -213,4 +266,4 @@ def get_images_filter():
from languagemanager import LanguageManager
__all__ = [u'AppLocation', u'check_latest_version', u'add_actions',
u'get_filesystem_encoding', u'LanguageManager']
u'get_filesystem_encoding', u'LanguageManager']

View File

@ -54,10 +54,10 @@ class LanguageManager(object):
"""
if LanguageManager.AutoLanguage:
language = QtCore.QLocale.system().name()
lang_Path = AppLocation.get_directory(AppLocation.AppDir)
lang_Path = os.path.join(lang_Path, u'resources', u'i18n')
lang_path = AppLocation.get_directory(AppLocation.AppDir)
lang_path = os.path.join(lang_path, u'resources', u'i18n')
app_translator = QtCore.QTranslator()
if app_translator.load("openlp_" + language, lang_Path):
if app_translator.load("openlp_" + language, lang_path):
return app_translator
@staticmethod
@ -143,4 +143,4 @@ class LanguageManager(object):
"""
if LanguageManager.__qmList__ is None:
LanguageManager.init_qm_list()
return LanguageManager.__qmList__
return LanguageManager.__qmList__

View File

@ -25,4 +25,4 @@
###############################################################################
"""
The :mod:`plugins` module provides all the project produced plugins
"""
"""

View File

@ -26,4 +26,4 @@
"""
The :mod:`alerts` module provides the Alerts plugin for producing impromptu
on-screen announcements during a service.
"""
"""

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
from openlp.core.lib import Plugin, build_icon, translate
from openlp.core.lib.db import Manager
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
from openlp.plugins.alerts.lib.db import init_schema
@ -45,8 +45,7 @@ class AlertsPlugin(Plugin):
self.icon = build_icon(u':/plugins/plugin_alerts.png')
self.alertsmanager = AlertsManager(self)
self.manager = Manager(u'alerts', init_schema)
self.alertForm = AlertForm(self.manager, self)
self.status = PluginStatus.Active
self.alertForm = AlertForm(self)
def getSettingsTab(self):
"""
@ -66,11 +65,9 @@ class AlertsPlugin(Plugin):
"""
log.info(u'add tools menu')
self.toolsAlertItem = QtGui.QAction(tools_menu)
AlertIcon = build_icon(u':/plugins/plugin_alerts.png')
self.toolsAlertItem.setIcon(AlertIcon)
self.toolsAlertItem.setIcon(build_icon(u':/plugins/plugin_alerts.png'))
self.toolsAlertItem.setObjectName(u'toolsAlertItem')
self.toolsAlertItem.setText(
translate('AlertsPlugin', '&Alert'))
self.toolsAlertItem.setText(translate('AlertsPlugin', '&Alert'))
self.toolsAlertItem.setStatusTip(
translate('AlertsPlugin', 'Show an alert message.'))
self.toolsAlertItem.setShortcut(u'F7')
@ -83,16 +80,16 @@ class AlertsPlugin(Plugin):
log.info(u'Alerts Initialising')
Plugin.initialise(self)
self.toolsAlertItem.setVisible(True)
self.liveController.alertTab = self.alertsTab
def finalise(self):
log.info(u'Plugin Finalise')
log.info(u'Alerts Finalising')
Plugin.finalise(self)
self.toolsAlertItem.setVisible(False)
def toggleAlertsState(self):
self.alertsActive = not self.alertsActive
QtCore.QSettings().setValue(
self.settingsSection + u'/active',
QtCore.QSettings().setValue(self.settingsSection + u'/active',
QtCore.QVariant(self.alertsActive))
def onAlertsTrigger(self):
@ -103,4 +100,4 @@ class AlertsPlugin(Plugin):
about_text = translate('AlertsPlugin', '<strong>Alerts Plugin</strong>'
'<br />The alert plugin controls the displaying of nursery alerts '
'on the display screen')
return about_text
return about_text

View File

@ -24,4 +24,4 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from alertform import AlertForm
from alertform import AlertForm

View File

@ -140,4 +140,4 @@ class Ui_AlertDialog(object):
self.DisplayCloseButton.setText(
translate('AlertsPlugin.AlertForm', 'Display && Cl&ose'))
self.CloseButton.setText(
translate('AlertsPlugin.AlertForm', '&Close'))
translate('AlertsPlugin.AlertForm', '&Close'))

View File

@ -35,14 +35,14 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
"""
Provide UI for the alert system
"""
def __init__(self, manager, parent):
def __init__(self, plugin):
"""
Initialise the alert form
"""
self.manager = manager
self.parent = parent
self.manager = plugin.manager
self.parent = plugin
self.item_id = None
QtGui.QDialog.__init__(self, None)
QtGui.QDialog.__init__(self, plugin.formparent)
self.setupUi(self)
QtCore.QObject.connect(self.DisplayButton, QtCore.SIGNAL(u'clicked()'),
self.onDisplayClicked)
@ -155,4 +155,4 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
text = text.replace(u'<>', unicode(self.ParameterEdit.text()))
self.parent.alertsmanager.displayAlert(text)
return True
return False
return False

View File

@ -25,4 +25,4 @@
###############################################################################
from alertsmanager import AlertsManager
from alertstab import AlertsTab
from alertstab import AlertsTab

View File

@ -32,18 +32,9 @@ from openlp.core.lib import Receiver, translate
log = logging.getLogger(__name__)
HTMLCODE = u"""
<p style=\"color:%s;
background-color:%s;
font-family:%s;
font-size: %spt; \">
%s
</p>
"""
class AlertsManager(QtCore.QObject):
"""
AlertsTab is the Alerts settings tab in the settings dialog.
AlertsManager manages the settings of Alerts.
"""
log.info(u'Alert Manager loaded')
@ -94,10 +85,7 @@ class AlertsManager(QtCore.QObject):
return
text = self.alertList.pop(0)
alertTab = self.parent.alertsTab
text = HTMLCODE % (alertTab.font_color, alertTab.bg_color,
alertTab.font_face, alertTab.font_size, text)
self.parent.previewController.parent.displayManager.addAlert(text,
alertTab.location)
self.parent.liveController.display.alert(text)
# check to see if we have a timer running
if self.timer_id == 0:
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
@ -111,10 +99,8 @@ class AlertsManager(QtCore.QObject):
"""
log.debug(u'timer event')
alertTab = self.parent.alertsTab
if event.timerId() == self.timer_id:
self.parent.previewController.parent.displayManager.addAlert(u'',
alertTab.location)
self.parent.liveController.display.alert(u'')
self.killTimer(self.timer_id)
self.timer_id = 0
self.generateAlert()
self.generateAlert()

View File

@ -261,7 +261,7 @@ class AlertsTab(SettingsTab):
self.font_face = unicode(settings.value(
u'font face', QtCore.QVariant(QtGui.QFont().family())).toString())
self.location = settings.value(
u'location', QtCore.QVariant(0)).toInt()[0]
u'location', QtCore.QVariant(1)).toInt()[0]
settings.endGroup()
self.FontSizeSpinBox.setValue(self.font_size)
self.TimeoutSpinBox.setValue(self.timeout)
@ -295,4 +295,5 @@ class AlertsTab(SettingsTab):
font.setPointSize(self.font_size)
self.FontPreview.setFont(font)
self.FontPreview.setStyleSheet(u'background-color: %s; color: %s' %
(self.bg_color, self.font_color))
(self.bg_color, self.font_color))

View File

@ -55,4 +55,4 @@ def init_schema(url):
mapper(AlertItem, alerts_table)
metadata.create_all(checkfirst=True)
return session
return session

View File

@ -26,4 +26,4 @@
"""
The :mod:`bibles' module provides the Bible plugin to enable OpenLP to display
scripture.
"""
"""

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
from openlp.core.lib import Plugin, build_icon, translate
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
log = logging.getLogger(__name__)
@ -41,8 +41,6 @@ class BiblePlugin(Plugin):
self.weight = -9
self.icon_path = u':/plugins/plugin_bibles.png'
self.icon = build_icon(self.icon_path)
# Register the bible Manager.
self.status = PluginStatus.Active
self.manager = None
def initialise(self):
@ -50,14 +48,14 @@ class BiblePlugin(Plugin):
if self.manager is None:
self.manager = BibleManager(self)
Plugin.initialise(self)
self.ImportBibleItem.setVisible(True)
self.ExportBibleItem.setVisible(True)
self.importBibleItem.setVisible(True)
self.exportBibleItem.setVisible(True)
def finalise(self):
log.info(u'Plugin Finalise')
Plugin.finalise(self)
self.ImportBibleItem.setVisible(False)
self.ExportBibleItem.setVisible(False)
self.importBibleItem.setVisible(False)
self.exportBibleItem.setVisible(False)
def getSettingsTab(self):
return BiblesTab(self.name)
@ -67,23 +65,23 @@ class BiblePlugin(Plugin):
return BibleMediaItem(self, self.icon, self.name)
def addImportMenuItem(self, import_menu):
self.ImportBibleItem = QtGui.QAction(import_menu)
self.ImportBibleItem.setObjectName(u'ImportBibleItem')
import_menu.addAction(self.ImportBibleItem)
self.ImportBibleItem.setText(
self.importBibleItem = QtGui.QAction(import_menu)
self.importBibleItem.setObjectName(u'importBibleItem')
import_menu.addAction(self.importBibleItem)
self.importBibleItem.setText(
translate('BiblesPlugin', '&Bible'))
# signals and slots
QtCore.QObject.connect(self.ImportBibleItem,
QtCore.QObject.connect(self.importBibleItem,
QtCore.SIGNAL(u'triggered()'), self.onBibleImportClick)
self.ImportBibleItem.setVisible(False)
self.importBibleItem.setVisible(False)
def addExportMenuItem(self, export_menu):
self.ExportBibleItem = QtGui.QAction(export_menu)
self.ExportBibleItem.setObjectName(u'ExportBibleItem')
export_menu.addAction(self.ExportBibleItem)
self.ExportBibleItem.setText(translate(
self.exportBibleItem = QtGui.QAction(export_menu)
self.exportBibleItem.setObjectName(u'exportBibleItem')
export_menu.addAction(self.exportBibleItem)
self.exportBibleItem.setText(translate(
'BiblesPlugin', '&Bible'))
self.ExportBibleItem.setVisible(False)
self.exportBibleItem.setVisible(False)
def onBibleImportClick(self):
if self.mediaItem:
@ -117,4 +115,4 @@ class BiblePlugin(Plugin):
``newTheme``
The new name the plugin should now use.
"""
self.settings_tab.bible_theme = newTheme
self.settings_tab.bible_theme = newTheme

View File

@ -26,4 +26,4 @@
from importwizardform import ImportWizardForm
__all__ = ['ImportWizardForm']
__all__ = ['ImportWizardForm']

View File

@ -381,4 +381,4 @@ class Ui_BibleImportWizard(object):
'Please wait while your Bible is imported.'))
self.ImportProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Ready.'))
self.ImportProgressBar.setFormat(u'%p%')
self.ImportProgressBar.setFormat(u'%p%')

View File

@ -50,8 +50,8 @@ class WebDownload(object):
}
@classmethod
def get_name(cls, id):
return cls.Names[id]
def get_name(cls, name):
return cls.Names[name]
class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
@ -129,8 +129,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
'Invalid Bible Location'),
translate('BiblesPlugin.ImportWizardForm',
'You need to specify a file to import your '
'Bible from.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
'Bible from.'))
self.OSISLocationEdit.setFocus()
return False
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
@ -140,8 +139,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
'Invalid Books File'),
translate('BiblesPlugin.ImportWizardForm',
'You need to specify a file with books of '
'the Bible to use in the import.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
'the Bible to use in the import.'))
self.BooksLocationEdit.setFocus()
return False
elif self.field(u'csv_versefile').toString() == u'':
@ -150,8 +148,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
'Invalid Verse File'),
translate('BiblesPlugin.ImportWizardForm',
'You need to specify a file of Bible '
'verses to import.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
'verses to import.'))
self.CsvVerseLocationEdit.setFocus()
return False
elif self.field(u'source_format').toInt()[0] == \
@ -162,8 +159,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
'Invalid OpenSong Bible'),
translate('BiblesPlugin.ImportWizardForm',
'You need to specify an OpenSong Bible '
'file to import.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
'file to import.'))
self.OpenSongFileEdit.setFocus()
return False
return True
@ -178,8 +174,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
'Empty Version Name'),
translate('BiblesPlugin.ImportWizardForm',
'You need to specify a version name for your '
'Bible.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
'Bible.'))
self.VersionNameEdit.setFocus()
return False
elif license_copyright == u'':
@ -189,8 +184,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
translate('BiblesPlugin.ImportWizardForm',
'You need to set a copyright for your Bible! '
'Bibles in the Public Domain need to be marked as '
'such.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
'such.'))
self.CopyrightEdit.setFocus()
return False
elif self.manager.exists(license_version):
@ -199,8 +193,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
'Bible Exists'),
translate('BiblesPlugin.ImportWizardForm',
'This Bible already exists! Please import '
'a different Bible or first delete the existing one.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
'a different Bible or first delete the existing one.'))
self.VersionNameEdit.setFocus()
return False
return True
@ -260,8 +253,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
if self.currentId() == 3:
Receiver.send_message(u'bibles_stop_import')
def onCurrentIdChanged(self, id):
if id == 3:
def onCurrentIdChanged(self, pageId):
if pageId == 3:
self.preImport()
self.performImport()
self.postImport()
@ -327,6 +320,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
#Load and store Crosswalk Bibles
filepath = AppLocation.get_directory(AppLocation.PluginsDir)
filepath = os.path.join(filepath, u'bibles', u'resources')
books_file = None
try:
self.web_bible_list[WebDownload.Crosswalk] = {}
books_file = open(
@ -348,6 +342,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
if books_file:
books_file.close()
#Load and store BibleGateway Bibles
books_file = None
try:
self.web_bible_list[WebDownload.BibleGateway] = {}
books_file = open(os.path.join(filepath, u'biblegateway.csv'), 'r')
@ -457,4 +452,4 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.ImportProgressBar.setValue(self.ImportProgressBar.maximum())
self.finishButton.setVisible(True)
self.cancelButton.setVisible(False)
Receiver.send_message(u'openlp_process_events')
Receiver.send_message(u'openlp_process_events')

View File

@ -23,8 +23,163 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`lib` module contains all the library functionality for the bibles
plugin.
"""
import logging
import re
log = logging.getLogger(__name__)
BIBLE_REFERENCE = re.compile(
r'^([\w ]+?) *([0-9]+)' # Initial book and chapter
r'(?: *[:|v|V] *([0-9]+))?' # Verse for first chapter
r'(?: *- *([0-9]+|end$))?' # Range for verses or chapters
r'(?:(?:,([0-9]+))?' # Second chapter
r' *[,|:|v|V] *([0-9]+|end$)' # More range for verses or chapters
r'(?: *- *([0-9]+|end$))?)?$', # End of second verse range
re.UNICODE)
def check_end(match_group):
"""
Check if a regular expression match group contains the text u'end' or
should be converted to an int.
``match_group``
The match group to check.
"""
if match_group == u'end':
return -1
else:
return int(match_group)
def parse_reference(reference):
"""
This is the über-awesome function that takes a person's typed in string
and converts it to a reference list, a list of references to be queried
from the Bible database files.
BIBLE_REFERENCE regular expression produces the following match groups:
0 This is a special group consisting of the whole string that matched.
1 [\w ]+ The book the reference is from.
2 [0-9]+ The first (or only) chapter in the reference.
3 None|[0-9]+ None or the only verse or the first verse in a
verse range or the start verse in a chapter range.
4 None|[0-9]+|end None or the end verse of the first verse range or
the end chapter of a chapter range.
5 None|[0-9]+ None or the second chapter in multiple
(non-ranged) chapters.
6 None|[0-9]+|end None, the start of the second verse range or the
end of a chapter range.
7 None|[0-9]+|end None or the end of the second verse range.
The reference list is a list of tuples, with each tuple structured like
this::
(book, chapter, start_verse, end_verse)
``reference``
The bible reference to parse.
Returns None or a reference list.
"""
reference = reference.strip()
log.debug('parse_reference("%s")', reference)
unified_ref_list = []
match = BIBLE_REFERENCE.match(reference)
if match:
log.debug(u'Matched reference %s' % reference)
book = match.group(1)
chapter = int(match.group(2))
if match.group(7):
# Two verse ranges
vr1_start = int(match.group(3))
vr1_end = int(match.group(4))
unified_ref_list.append((book, chapter, vr1_start, vr1_end))
vr2_start = int(match.group(6))
vr2_end = check_end(match.group(7))
if match.group(5):
# One verse range per chapter
chapter2 = int(match.group(5))
unified_ref_list.append((book, chapter2, vr2_start, vr2_end))
else:
unified_ref_list.append((book, chapter, vr2_start, vr2_end))
elif match.group(6):
# Chapter range with verses
if match.group(3):
vr1_start = int(match.group(3))
else:
vr1_start = 1
if match.group(2) == match.group(4):
vr1_end = int(match.group(6))
unified_ref_list.append((book, chapter, vr1_start, vr1_end))
else:
vr1_end = -1
unified_ref_list.append((book, chapter, vr1_start, vr1_end))
vr2_end = check_end(match.group(6))
if int(match.group(4)) > chapter:
for i in range(chapter + 1, int(match.group(4)) + 1):
if i == int(match.group(4)):
unified_ref_list.append((book, i, 1, vr2_end))
else:
unified_ref_list.append((book, i, 1, -1))
elif match.group(4):
# Chapter range or chapter and verse range
if match.group(3):
vr1_start = int(match.group(3))
vr1_end = check_end(match.group(4))
if vr1_end == -1 or vr1_end > vr1_start:
unified_ref_list.append((book, chapter, vr1_start, vr1_end))
else:
log.debug(u'Ambiguous reference: %s' % reference)
return None
elif match.group(4) != u'end':
for i in range(chapter, int(match.group(4)) + 1):
unified_ref_list.append((book, i, 1, -1))
else:
log.debug(u'Unsupported reference: %s' % reference)
return None
elif match.group(3):
# Single chapter and verse
verse = int(match.group(3))
unified_ref_list.append((book, chapter, verse, verse))
else:
# Single chapter
unified_ref_list.append((book, chapter, -1, -1))
else:
log.debug(u'Invalid reference: %s' % reference)
return None
return unified_ref_list
class SearchResults(object):
"""
Encapsulate a set of search results. This is Bible-type independant.
"""
def __init__(self, book, chapter, verselist):
"""
Create the search result object.
``book``
The book of the Bible.
``chapter``
The chapter of the book.
``verselist``
The list of verses for this reading
"""
self.book = book
self.chapter = chapter
self.verselist = verselist
def has_verselist(self):
"""
Returns whether or not the verse list contains verses.
"""
return len(self.verselist) > 0
from common import BibleCommon
from manager import BibleManager
from biblestab import BiblesTab
from mediaitem import BibleMediaItem
from mediaitem import BibleMediaItem

View File

@ -241,10 +241,10 @@ class BiblesTab(SettingsTab):
self.BibleThemeComboBox.addItem(u'')
for theme in theme_list:
self.BibleThemeComboBox.addItem(theme)
id = self.BibleThemeComboBox.findText(
index = self.BibleThemeComboBox.findText(
unicode(self.bible_theme), QtCore.Qt.MatchExactly)
if id == -1:
if index == -1:
# Not Found
id = 0
index = 0
self.bible_theme = u''
self.BibleThemeComboBox.setCurrentIndex(id)
self.BibleThemeComboBox.setCurrentIndex(index)

View File

@ -1,280 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import urllib2
import logging
import re
import chardet
import htmlentitydefs
only_verses = re.compile(r'([\w .]+)[ ]+([0-9]+)[ ]*[:|v|V][ ]*([0-9]+)'
r'(?:[ ]*-[ ]*([0-9]+|end))?(?:[ ]*,[ ]*([0-9]+)'
r'(?:[ ]*-[ ]*([0-9]+|end))?)?',
re.UNICODE)
chapter_range = re.compile(r'([\w .]+)[ ]+([0-9]+)[ ]*[:|v|V][ ]*'
r'([0-9]+|end)[ ]*-[ ]*([0-9]+)[ ]*[:|v|V][ ]*([0-9]+|end)',
re.UNICODE)
log = logging.getLogger(__name__)
def parse_reference(reference):
"""
This is the über-awesome function that takes a person's typed in string
and converts it to a reference list, a list of references to be queried
from the Bible database files.
The reference list is a list of tuples, with each tuple structured like
this::
(book, chapter, start_verse, end_verse)
"""
reference = reference.strip()
log.debug('parse_reference("%s")', reference)
reference_list = []
# We start with the most "complicated" match first, so that they are found
# first, and we don't have any "false positives".
match = chapter_range.match(reference)
if match:
log.debug('Found a chapter range.')
book = match.group(1)
from_verse = match.group(3)
to_verse = match.group(5)
if int(match.group(2)) == int(match.group(4)):
reference_list.append(
(match.group(1), int(match.group(2)), from_verse, to_verse)
)
else:
if int(match.group(2)) > int(match.group(4)):
from_chapter = int(match.group(4))
to_chapter = int(match.group(2))
else:
from_chapter = int(match.group(2))
to_chapter = int(match.group(4))
for chapter in xrange(from_chapter, to_chapter + 1):
if chapter == from_chapter:
reference_list.append(
(match.group(1), chapter, from_verse, -1)
)
elif chapter == to_chapter:
reference_list.append(
(match.group(1), chapter, 1, to_verse)
)
else:
reference_list.append(
(match.group(1), chapter, 1, -1)
)
else:
match = only_verses.match(reference)
if match:
log.debug('Found a verse range.')
book = match.group(1)
chapter = match.group(2)
verse = match.group(3)
if match.group(4) is None:
reference_list.append((book, chapter, verse, verse))
elif match.group(5) is None:
end_verse = match.group(4)
if end_verse == u'end':
end_verse = -1
reference_list.append((book, chapter, verse, end_verse))
elif match.group(6) is None:
reference_list.extend([
(book, chapter, verse, match.group(4)),
(book, chapter, match.group(5), match.group(5))
])
else:
end_verse = match.group(6)
if end_verse == u'end':
end_verse = -1
reference_list.extend([
(book, chapter, verse, match.group(4)),
(book, chapter, match.group(5), end_verse)
])
else:
log.debug('Didn\'t find anything.')
log.debug(reference_list)
return reference_list
class SearchResults(object):
"""
Encapsulate a set of search results. This is Bible-type independant.
"""
def __init__(self, book, chapter, verselist):
"""
Create the search result object.
``book``
The book of the Bible.
``chapter``
The chapter of the book.
``verselist``
The list of verses for this reading
"""
self.book = book
self.chapter = chapter
self.verselist = verselist
def get_verselist(self):
"""
Returns the list of verses.
"""
return self.verselist
def get_book(self):
"""
Returns the book of the Bible.
"""
return self.book
def get_chapter(self):
"""
Returns the chapter of the book.
"""
return self.chapter
def has_verselist(self):
"""
Returns whether or not the verse list contains verses.
"""
return len(self.verselist) > 0
class BibleCommon(object):
"""
A common ancestor for bible download sites.
"""
log.info(u'BibleCommon')
def _get_web_text(self, urlstring, proxyurl):
"""
Get the HTML from the web page.
``urlstring``
The URL of the page to open.
``proxyurl``
The URL of a proxy server used to access the Internet.
"""
log.debug(u'get_web_text %s %s', proxyurl, urlstring)
if proxyurl:
proxy_support = urllib2.ProxyHandler({'http': self.proxyurl})
http_support = urllib2.HTTPHandler()
opener = urllib2.build_opener(proxy_support, http_support)
urllib2.install_opener(opener)
xml_string = u''
req = urllib2.Request(urlstring)
#Make us look like an IE Browser on XP to stop blocking by web site
req.add_header(u'User-Agent',
u'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)')
try:
handle = urllib2.urlopen(req)
html = handle.read()
details = chardet.detect(html)
xml_string = unicode(html, details[u'encoding'])
except IOError, e:
if hasattr(e, u'reason'):
log.exception(u'Reason for failure: %s', e.reason)
return xml_string
def _clean_text(self, text):
"""
Clean up text and remove extra characters after been downloaded from
the Internet.
``text``
The text from the web page that needs to be cleaned up.
"""
#return text.rstrip()
# Remove Headings from the Text
start_tag = text.find(u'<h')
while start_tag > -1:
end_tag = text.find(u'</h', start_tag)
text = text[:(start_tag - 1)] + text[(end_tag + 4)]
start_tag = text.find(u'<h')
# Remove Support References from the Text
start_tag = text.find(u'<sup>')
while start_tag > -1:
end_tag = text.find(u'</sup>')
text = text[:start_tag] + text[end_tag + 6:len(text)]
start_tag = text.find(u'<sup>')
start_tag = text.find(u'<SUP>')
while start_tag > -1:
end_tag = text.find(u'</SUP>')
text = text[:start_tag] + text[end_tag + 6:len(text)]
start_tag = text.find(u'<SUP>')
# Static Clean ups
text = text.replace(u'\n', u'')
text = text.replace(u'\r', u'')
text = text.replace(u'&nbsp;', u'')
text = text.replace(u'<P>', u'')
text = text.replace(u'<I>', u'')
text = text.replace(u'</I>', u'')
text = text.replace(u'<P />', u'')
text = text.replace(u'<p />', u'')
text = text.replace(u'</P>', u'')
text = text.replace(u'<BR>', u'')
text = text.replace(u'<BR />', u'')
text = text.replace(u'&quot;', u'\"')
text = text.replace(u'&apos;', u'\'')
# Remove some other tags
start_tag = text.find(u'<')
while start_tag > -1:
end_tag = text.find(u'>', start_tag)
text = text[:start_tag] + text[end_tag + 1:]
start_tag = text.find(u'<')
text = text.replace(u'>', u'')
return text.rstrip().lstrip()
def unescape(text):
"""
Removes HTML or XML character references and entities from a text string.
Courtesy of Fredrik Lundh, http://effbot.org/zone/re-sub.htm#unescape-html
@param text The HTML (or XML) source text.
@return The plain text, as a Unicode string, if necessary.
"""
def fixup(markup):
text = markup.group(0)
if text.startswith(u'&#'):
# character reference
try:
if text.startswith(u'&#x'):
return unichr(int(text[3:-1], 16))
else:
return unichr(int(text[2:-1]))
except ValueError:
pass
else:
# named entity
try:
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
except KeyError:
pass
return text # leave as is
return re.sub(u'&#?\w+;', fixup, text)

View File

@ -113,4 +113,4 @@ class CSVBible(BibleDB):
self.wizard.incrementProgressBar(u'Import canceled!')
return False
else:
return success
return success

View File

@ -306,6 +306,13 @@ class BibleDB(QtCore.QObject, Manager):
Book.abbreviation.like(book + u'%'))
return db_book
def get_books(self):
"""
A wrapper so both local and web bibles have a get_books() method that
manager can call. Used in the media manager advanced search tab.
"""
return self.get_all_objects(Book, order_by_ref=Book.id)
def get_verses(self, reference_list):
"""
This is probably the most used function. It retrieves the list of
@ -424,4 +431,4 @@ class BibleDB(QtCore.QObject, Manager):
log.debug(books)
log.debug(u'...............................Verses ')
verses = self.session.query(Verse).all()
log.debug(verses)
log.debug(verses)

View File

@ -30,13 +30,13 @@ import re
import sqlite3
import urllib
import urllib2
from HTMLParser import HTMLParseError
from BeautifulSoup import BeautifulSoup, Tag, NavigableString
from BeautifulSoup import BeautifulSoup, NavigableString
from openlp.core.lib import Receiver
from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.common import BibleCommon, SearchResults, \
unescape
from openlp.plugins.bibles.lib import SearchResults
from openlp.plugins.bibles.lib.db import BibleDB, Book
log = logging.getLogger(__name__)
@ -106,6 +106,7 @@ class HTTPBooks(object):
"""
if not isinstance(name, unicode):
name = unicode(name)
name = name.title()
books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM books WHERE name = ? OR '
u'abbreviation = ?', (name, name))
@ -138,10 +139,10 @@ class HTTPBooks(object):
u'verses FROM chapters WHERE book_id = ?', (book[u'id'],))
if chapters:
return {
u'id': chapters[chapter][0],
u'book_id': chapters[chapter][1],
u'chapter': chapters[chapter][2],
u'verses': chapters[chapter][3]
u'id': chapters[chapter-1][0],
u'book_id': chapters[chapter-1][1],
u'chapter': chapters[chapter-1][2],
u'verses': chapters[chapter-1][3]
}
else:
return None
@ -176,11 +177,10 @@ class HTTPBooks(object):
return 0
class BGExtract(BibleCommon):
class BGExtract(object):
"""
Extract verses from BibleGateway
"""
def __init__(self, proxyurl=None):
log.debug(u'init %s', proxyurl)
self.proxyurl = proxyurl
@ -202,78 +202,48 @@ class BGExtract(BibleCommon):
url_params = urllib.urlencode(
{u'search': u'%s %s' % (bookname, chapter),
u'version': u'%s' % version})
# Let's get the page, and then open it in BeautifulSoup, so as to
# attempt to make "easy" work of bad HTML.
page = urllib2.urlopen(
u'http://www.biblegateway.com/passage/?%s' % url_params)
log.debug(u'BibleGateway url = %s' % page.geturl())
Receiver.send_message(u'openlp_process_events')
soup = BeautifulSoup(page)
Receiver.send_message(u'openlp_process_events')
verses = soup.find(u'div', u'result-text-style-normal')
verse_number = 0
verse_list = {0: u''}
# http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html
# This is a PERFECT example of opening the Cthulu tag!
# O Bible Gateway, why doth ye such horrific HTML produce?
for verse in verses:
page = None
try:
page = urllib2.urlopen(
u'http://www.biblegateway.com/passage/?%s' % url_params)
log.debug(u'BibleGateway url = %s' % page.geturl())
Receiver.send_message(u'openlp_process_events')
if isinstance(verse, Tag) and verse.name == u'div' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] == u'footnotes':
break
if isinstance(verse, Tag) and verse.name == u'sup' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] != u'versenum':
continue
if isinstance(verse, Tag) and verse.name == u'p' and not verse.contents:
continue
if isinstance(verse, Tag) and (verse.name == u'p' or verse.name == u'font') and verse.contents:
for item in verse.contents:
Receiver.send_message(u'openlp_process_events')
if isinstance(item, Tag) and (item.name == u'h4' or item.name == u'h5'):
continue
if isinstance(item, Tag) and item.name == u'sup' and filter(lambda a: a[0] == u'class', item.attrs)[0][1] != u'versenum':
continue
if isinstance(item, Tag) and item.name == u'p' and not item.contents:
continue
if isinstance(item, Tag) and item.name == u'sup':
verse_number = int(str(item.contents[0]))
verse_list[verse_number] = u''
continue
if isinstance(item, Tag) and item.name == u'font':
for subitem in item.contents:
Receiver.send_message(u'openlp_process_events')
if isinstance(subitem, Tag) and subitem.name == u'sup' and filter(lambda a: a[0] == u'class', subitem.attrs)[0][1] != u'versenum':
continue
if isinstance(subitem, Tag) and subitem.name == u'p' and not subitem.contents:
continue
if isinstance(subitem, Tag) and subitem.name == u'sup':
verse_number = int(str(subitem.contents[0]))
verse_list[verse_number] = u''
continue
if isinstance(subitem, NavigableString):
verse_list[verse_number] = verse_list[verse_number] + subitem.replace(u'&nbsp;', u' ')
continue
if isinstance(item, NavigableString):
verse_list[verse_number] = verse_list[verse_number] + item.replace(u'&nbsp;', u' ')
continue
if isinstance(verse, Tag) and verse.name == u'sup':
verse_number = int(str(verse.contents[0]))
verse_list[verse_number] = u''
continue
if isinstance(verse, NavigableString):
if not isinstance(verse, unicode):
verse = unicode(verse, u'utf8')
verse_list[verse_number] = verse_list[verse_number] + \
unescape(verse.replace(u'&nbsp;', u' '))
# Delete the "0" element, since we don't need it, it's just there for
# some stupid initial whitespace, courtesy of Bible Gateway.
del verse_list[0]
# Finally, return the list of verses in a "SearchResults" object.
except urllib2.URLError:
log.exception(u'The web bible page could not be downloaded.')
finally:
if not page:
return None
cleaner = [(re.compile('&nbsp;|<br />'), lambda match: '')]
soup = None
try:
soup = BeautifulSoup(page, markupMassage=cleaner)
except HTMLParseError:
log.exception(u'BeautifulSoup could not parse the bible page.')
finally:
if not soup:
return None
Receiver.send_message(u'openlp_process_events')
footnotes = soup.findAll(u'sup', u'footnote')
[footnote.extract() for footnote in footnotes]
cleanup = [(re.compile('\s+'), lambda match: ' ')]
verses = BeautifulSoup(str(soup), markupMassage=cleanup)
content = verses.find(u'div', u'result-text-style-normal')
verse_count = len(verses.findAll(u'sup', u'versenum'))
found_count = 0
verse_list = {}
while found_count < verse_count:
content = content.findNext(u'sup', u'versenum')
raw_verse_num = content.next
raw_verse_text = raw_verse_num.next
verse_list[int(str(raw_verse_num))] = unicode(raw_verse_text)
found_count += 1
return SearchResults(bookname, chapter, verse_list)
class CWExtract(BibleCommon):
class CWExtract(object):
"""
Extract verses from CrossWalk/BibleStudyTools
"""
def __init__(self, proxyurl=None):
log.debug(u'init %s', proxyurl)
self.proxyurl = proxyurl
@ -296,11 +266,23 @@ class CWExtract(BibleCommon):
chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % \
(version, urlbookname.lower(), chapter)
log.debug(u'URL: %s', chapter_url)
page = urllib2.urlopen(chapter_url)
Receiver.send_message(u'openlp_process_events')
if not page:
return None
soup = BeautifulSoup(page)
page = None
try:
page = urllib2.urlopen(chapter_url)
Receiver.send_message(u'openlp_process_events')
except urllib2.URLError:
log.exception(u'The web bible page could not be downloaded.')
finally:
if not page:
return None
soup = None
try:
soup = BeautifulSoup(page)
except HTMLParseError:
log.exception(u'BeautifulSoup could not parse the bible page.')
finally:
if not soup:
return None
Receiver.send_message(u'openlp_process_events')
htmlverses = soup.findAll(u'span', u'versetext')
verses = {}
@ -433,13 +415,12 @@ class HTTPBible(BibleDB):
## if it was there. By reusing the returned book name
## we get a correct book. For example it is possible
## to request ac and get Acts back.
bookname = search_results.get_book()
bookname = search_results.book
Receiver.send_message(u'openlp_process_events')
# check to see if book/chapter exists
db_book = self.get_book(bookname)
self.create_chapter(db_book.id,
search_results.get_chapter(),
search_results.get_verselist())
self.create_chapter(db_book.id, search_results.chapter,
search_results.verselist)
Receiver.send_message(u'openlp_process_events')
Receiver.send_message(u'bibles_hideprogress')
Receiver.send_message(u'openlp_process_events')
@ -451,15 +432,11 @@ class HTTPBible(BibleDB):
"""
log.debug(u'get_chapter %s, %s', book, chapter)
log.debug(u'source = %s', self.download_source)
try:
if self.download_source.lower() == u'crosswalk':
ev = CWExtract(self.proxy_server)
else:
ev = BGExtract(self.proxy_server)
return ev.get_bible_chapter(self.download_name, book, chapter)
except:
log.exception("Failed to get bible chapter")
return None
if self.download_source.lower() == u'crosswalk':
ev = CWExtract(self.proxy_server)
else:
ev = BGExtract(self.proxy_server)
return ev.get_bible_chapter(self.download_name, book, chapter)
def get_books(self):
"""
@ -491,14 +468,3 @@ class HTTPBible(BibleDB):
The chapter whose verses are being counted.
"""
return HTTPBooks.get_verse_count(book, chapter)
def set_proxy_server(self, server):
"""
Sets the proxy server.
**Note: This is not actually used.**
``server``
The hostname or IP address of the proxy server.
"""
self.proxy_server = server

View File

@ -26,13 +26,13 @@
import logging
from PyQt4 import QtCore
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsManager
from openlp.core.lib import SettingsManager, translate
from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.db import BibleDB, Book, BibleMeta
from openlp.plugins.bibles.lib import parse_reference
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from common import parse_reference
from opensong import OpenSongBible
from osis import OSISBible
from csvbible import CSVBible
@ -63,20 +63,20 @@ class BibleFormat(object):
WebDownload = 3
@staticmethod
def get_class(id):
def get_class(format):
"""
Return the appropriate imeplementation class.
``id``
``format``
The Bible format.
"""
if id == BibleFormat.OSIS:
if format == BibleFormat.OSIS:
return OSISBible
elif id == BibleFormat.CSV:
elif format == BibleFormat.CSV:
return CSVBible
elif id == BibleFormat.OpenSong:
elif format == BibleFormat.OpenSong:
return OpenSongBible
elif id == BibleFormat.WebDownload:
elif format == BibleFormat.WebDownload:
return HTTPBible
else:
return None
@ -149,7 +149,7 @@ class BibleManager(object):
file=filename, download_source=source.value,
download_name=download_name)
if meta_proxy:
web_bible.set_proxy_server(meta_proxy.value)
web_bible.proxy_server = meta_proxy.value
self.db_cache[name] = web_bible
log.debug(u'Bibles reloaded')
@ -199,8 +199,7 @@ class BibleManager(object):
u'name': book.name,
u'chapters': self.db_cache[bible].get_chapter_count(book.name)
}
for book in self.db_cache[bible].get_all_objects(Book,
order_by_ref=Book.id)
for book in self.db_cache[bible].get_books()
]
def get_chapter_count(self, bible, book):
@ -230,13 +229,33 @@ class BibleManager(object):
``versetext``
Unicode. The scripture reference. Valid scripture references are:
- Genesis 1
- Genesis 1-2
- Genesis 1:1
- Genesis 1:1-10
- Genesis 1:1-10,15-20
- Genesis 1:1-2:10
- Genesis 1:1-10,2:1-10
"""
log.debug(u'BibleManager.get_verses("%s", "%s")', bible, versetext)
reflist = parse_reference(versetext)
return self.db_cache[bible].get_verses(reflist)
if reflist:
return self.db_cache[bible].get_verses(reflist)
else:
QtGui.QMessageBox.information(self.parent.mediaItem,
translate('BiblesPlugin.BibleManager',
'Scripture Reference Error'),
translate('BiblesPlugin.BibleManager', 'Your scripture '
'reference is either not supported by OpenLP or invalid. '
'Please make sure your reference conforms to one of the '
'following patterns:\n\n'
'Book Chapter\n'
'Book Chapter-Chapter\n'
'Book Chapter:Verse-Verse\n'
'Book Chapter:Verse-Verse,Verse-Verse\n'
'Book Chapter:Verse-Verse,Chapter:Verse-Verse\n'
'Book Chapter:Verse-Chapter:Verse\n'))
return None
def save_meta_data(self, bible, version, copyright, permissions):
"""
@ -267,4 +286,4 @@ class BibleManager(object):
bible = unicode(bible)
if bible == name:
return True
return False
return False

View File

@ -59,10 +59,10 @@ class BibleMediaItem(MediaManagerItem):
self.pluginNameVisible = translate('BiblesPlugin.MediaItem', 'Bible')
self.IconPath = u'songs/song'
self.ListViewWithDnD_class = BibleListView
self.lastReference = []
MediaManagerItem.__init__(self, parent, icon, title)
# place to store the search results
# place to store the search results for both bibles
self.search_results = {}
self.dual_search_results = {}
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles)
@ -344,7 +344,7 @@ class BibleMediaItem(MediaManagerItem):
self.QuickMessage.setText(text)
self.AdvancedMessage.setText(text)
Receiver.send_message(u'openlp_process_events')
#minor delay to get the events processed
# minor delay to get the events processed
time.sleep(0.1)
def loadBibles(self):
@ -387,10 +387,7 @@ class BibleMediaItem(MediaManagerItem):
QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.MediaItem', 'No Book Found'),
translate('BiblesPlugin.MediaItem',
'No matching book could be found in this Bible.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok
)
'No matching book could be found in this Bible.'))
def onAdvancedVersionComboBox(self):
self.initialiseBible(
@ -404,9 +401,10 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedBookComboBox.itemData(item).toInt()[0])
def onImportClick(self):
self.bibleimportform = ImportWizardForm(self,
self.parent.manager, self.parent)
self.bibleimportform.exec_()
if not hasattr(self, u'import_wizard'):
self.import_wizard = ImportWizardForm(self, self.parent.manager,
self.parent)
self.import_wizard.exec_()
self.reloadBibles()
def onAdvancedFromVerse(self):
@ -426,19 +424,21 @@ class BibleMediaItem(MediaManagerItem):
def onAdvancedSearchButton(self):
log.debug(u'Advanced Search Button pressed')
bible = unicode(self.AdvancedVersionComboBox.currentText())
dual_bible = unicode(self.AdvancedSecondBibleComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText())
chapter_from = int(self.AdvancedFromChapter.currentText())
chapter_to = int(self.AdvancedToChapter.currentText())
verse_from = int(self.AdvancedFromVerse.currentText())
verse_to = int(self.AdvancedToVerse.currentText())
versetext = u'%s %s:%s-%s:%s' % (book, chapter_from, verse_from, \
chapter_to, verse_to)
versetext = u'%s %s:%s-%s:%s' % (book, chapter_from, verse_from,
chapter_to, verse_to)
self.search_results = self.parent.manager.get_verses(bible, versetext)
if dual_bible:
self.dual_search_results = self.parent.manager.get_verses(
dual_bible, versetext)
if self.ClearAdvancedSearchComboBox.currentIndex() == 0:
self.listView.clear()
self.lastReference = []
self.lastReference.append(versetext)
self.displayResults(bible)
self.displayResults(bible, dual_bible)
def onAdvancedFromChapter(self):
bible = unicode(self.AdvancedVersionComboBox.currentText())
@ -453,124 +453,136 @@ class BibleMediaItem(MediaManagerItem):
def onQuickSearchButton(self):
log.debug(u'Quick Search Button pressed')
bible = unicode(self.QuickVersionComboBox.currentText())
dual_bible = unicode(self.QuickSecondBibleComboBox.currentText())
text = unicode(self.QuickSearchEdit.text())
if self.ClearQuickSearchComboBox.currentIndex() == 0:
self.listView.clear()
self.lastReference = []
self.lastReference.append(text)
self.search_results = self.parent.manager.get_verses(bible, text)
if dual_bible:
self.dual_search_results = self.parent.manager.get_verses(
dual_bible, text)
if self.search_results:
self.displayResults(bible)
self.displayResults(bible, dual_bible)
def generateSlideData(self, service_item, item=None):
"""
Generates and formats the slides for the service item.
"""
log.debug(u'generating slide data')
items = self.listView.selectedIndexes()
if len(items) == 0:
return False
old_chapter = u''
raw_slides = []
raw_footer = []
bible_text = u''
old_chapter = u''
raw_footer = []
raw_slides = []
service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop)
service_item.add_capability(ItemCapabilities.AllowsAdditions)
#If we want to use a 2nd translation / version
bible2 = u''
if self.SearchTabWidget.currentIndex() == 0:
bible2 = unicode(self.QuickSecondBibleComboBox.currentText())
else:
bible2 = unicode(self.AdvancedSecondBibleComboBox.currentText())
if bible2:
bible2_verses = []
for scripture in self.lastReference:
bible2_verses.extend(self.parent.manager.get_verses(bible2,
scripture))
bible2_version = self.parent.manager.get_meta_data(bible2,
u'Version')
bible2_copyright = self.parent.manager.get_meta_data(bible2,
u'Copyright')
bible2_permission = self.parent.manager.get_meta_data(bible2,
u'Permissions')
if bible2_version:
bible2_version = bible2_version.value
else:
bible2_version = u''
if bible2_copyright:
bible2_copyright = bible2_copyright.value
else:
bible2_copyright = u''
if bible2_permission:
bible2_permission = bible2_permission.value
else:
bible2_permission = u''
# Let's loop through the main lot, and assemble our verses
# Let's loop through the main lot, and assemble our verses.
for item in items:
bitem = self.listView.item(item.row())
reference = bitem.data(QtCore.Qt.UserRole)
if isinstance(reference, QtCore.QVariant):
reference = reference.toPyObject()
#bible = self._decodeQtObject(reference, 'bible')
book = self._decodeQtObject(reference, 'book')
chapter = self._decodeQtObject(reference, 'chapter')
verse = self._decodeQtObject(reference, 'verse')
text = self._decodeQtObject(reference, 'text')
bible = self._decodeQtObject(reference, 'bible')
version = self._decodeQtObject(reference, 'version')
copyright = self._decodeQtObject(reference, 'copyright')
#permission = self._decodeQtObject(reference, 'permission')
text = self._decodeQtObject(reference, 'text')
dual_bible = self._decodeQtObject(reference, 'dual_bible')
if dual_bible:
dual_version = self._decodeQtObject(reference,
'dual_version')
dual_copyright = self._decodeQtObject(reference,
'dual_copyright')
#dual_permission = self._decodeQtObject(reference,
# 'dual_permission')
dual_text = self._decodeQtObject(reference, 'dual_text')
if self.parent.settings_tab.display_style == 1:
verse_text = self.formatVerse(old_chapter, chapter, verse,
u'(', u')')
u'{su}(', u'){/su}')
elif self.parent.settings_tab.display_style == 2:
verse_text = self.formatVerse(old_chapter, chapter, verse,
u'{', u'}')
u'{su}{', u'}{/su}')
elif self.parent.settings_tab.display_style == 3:
verse_text = self.formatVerse(old_chapter, chapter, verse,
u'[', u']')
u'{su}[', u']{/su}')
else:
verse_text = self.formatVerse(old_chapter, chapter, verse,
u'', u'')
u'{su}', u'{/su}')
old_chapter = chapter
footer = u'%s (%s %s)' % (book, version, copyright)
#If not found add to footer
# If not found add to footer
if footer not in raw_footer:
raw_footer.append(footer)
if bible2:
footer = u'%s (%s %s)' % (book, bible2_version,
bible2_copyright)
#If not found add second version and copyright to footer
if dual_bible:
footer = u'%s (%s %s)' % (book, dual_version,
dual_copyright)
# If not found add second version and copyright to footer.
if footer not in raw_footer:
raw_footer.append(footer)
bible_text = u'%s %s \n\n %s %s' % (verse_text, text,
verse_text, bible2_verses[item.row()].text)
verse_text, dual_text)
raw_slides.append(bible_text)
bible_text = u''
else:
#Paragraph style force new line per verse
# If we are 'Verse Per Line' then force a new line.
if self.parent.settings_tab.layout_style == 1:
text = text + u'\n\n'
text = text + u'\n'
else:
# split the line but do not replace line breaks in renderer
service_item.add_capability(ItemCapabilities.NoLineBreaks)
text = text + u'\n'
bible_text = u'%s %s %s' % (bible_text, verse_text, text)
#if we are verse per slide then create slide
# If we are 'Verse Per Slide' then create a new slide.
if self.parent.settings_tab.layout_style == 0:
raw_slides.append(bible_text)
bible_text = u''
if not service_item.title:
service_item.title = u'%s %s' % (book, verse_text)
elif service_item.title.find(
translate('BiblesPlugin.MediaItem', 'etc')) == -1:
service_item.title = u'%s, %s' % (service_item.title,
translate('BiblesPlugin.MediaItem', 'etc'))
# If we are not 'Verse Per Slide' we have to make sure, that we
# add more verses.
else:
if item.row() < len(items) - 1:
bitem = items[item.row() + 1]
reference = bitem.data(QtCore.Qt.UserRole)
if isinstance(reference, QtCore.QVariant):
reference = reference.toPyObject()
bible_new = self._decodeQtObject(reference, 'bible')
dual_bible_new = self._decodeQtObject(reference,
'dual_bible')
if dual_bible_new:
raw_slides.append(bible_text)
bible_text = u''
elif bible != bible_new:
raw_slides.append(bible_text)
bible_text = u''
else:
raw_slides.append(bible_text)
bible_text = u''
# service item title
if not service_item.title:
if dual_bible:
service_item.title = u'%s (%s, %s) %s' % (book, version,
dual_version, verse_text)
else:
service_item.title = u'%s (%s) %s' % (book, version, verse_text)
elif service_item.title.find(
translate('BiblesPlugin.MediaItem', 'etc')) == -1:
service_item.title = u'%s, %s' % (service_item.title,
translate('BiblesPlugin.MediaItem', 'etc'))
# item theme
if len(self.parent.settings_tab.bible_theme) == 0:
service_item.theme = None
else:
service_item.theme = self.parent.settings_tab.bible_theme
#if we are verse per slide we have already been added
if self.parent.settings_tab.layout_style != 0 and not bible2:
raw_slides.append(bible_text)
for slide in raw_slides:
service_item.add_from_text(slide[:30], slide)
if service_item.raw_footer:
for foot in raw_footer:
service_item.raw_footer.append(foot)
for footer in raw_footer:
service_item.raw_footer.append(footer)
else:
service_item.raw_footer = raw_footer
return True
@ -602,8 +614,8 @@ class BibleMediaItem(MediaManagerItem):
row, QtCore.QVariant(book[u'chapters']))
if first:
first = False
self.initialiseChapterVerse(
bible, book[u'name'], book[u'chapters'])
self.initialiseChapterVerse(bible, book[u'name'],
book[u'chapters'])
def initialiseChapterVerse(self, bible, book, chapters):
log.debug(u'initialiseChapterVerse %s, %s', bible, book)
@ -627,36 +639,69 @@ class BibleMediaItem(MediaManagerItem):
for i in range(int(range_from), int(range_to) + 1):
combo.addItem(unicode(i))
def displayResults(self, bible):
def displayResults(self, bible, dual_bible=None):
"""
Displays the search results in the media manager. All data needed for
further action is saved for/in each row.
"""
version = self.parent.manager.get_meta_data(bible, u'Version')
copyright = self.parent.manager.get_meta_data(bible, u'Copyright')
permission = self.parent.manager.get_meta_data(bible, u'Permissions')
if not permission:
permission = u''
else:
permission = permission.value
#permission = self.parent.manager.get_meta_data(bible, u'Permissions')
if dual_bible:
dual_version = self.parent.manager.get_meta_data(dual_bible,
u'Version')
dual_copyright = self.parent.manager.get_meta_data(dual_bible,
u'Copyright')
dual_permission = self.parent.manager.get_meta_data(dual_bible,
u'Permissions')
if dual_permission:
dual_permission = dual_permission.value
else:
dual_permission = u''
# We count the number of rows which are maybe already present.
start_count = self.listView.count()
for count, verse in enumerate(self.search_results):
bible_text = u' %s %d:%d (%s)' % \
(verse.book.name, verse.chapter, verse.verse, bible)
if dual_bible:
vdict = {
'book':QtCore.QVariant(verse.book.name),
'chapter':QtCore.QVariant(verse.chapter),
'verse':QtCore.QVariant(verse.verse),
'bible':QtCore.QVariant(bible),
'version':QtCore.QVariant(version.value),
'copyright':QtCore.QVariant(copyright.value),
#'permission':QtCore.QVariant(permission.value),
'text':QtCore.QVariant(verse.text),
'dual_bible':QtCore.QVariant(dual_bible),
'dual_version':QtCore.QVariant(dual_version.value),
'dual_copyright':QtCore.QVariant(dual_copyright.value),
#'dual_permission':QtCore.QVariant(dual_permission),
'dual_text':QtCore.QVariant(
self.dual_search_results[count].text)
}
bible_text = u' %s %d:%d (%s, %s)' % (verse.book.name,
verse.chapter, verse.verse, version.value, dual_version.value)
else:
vdict = {
'book':QtCore.QVariant(verse.book.name),
'chapter':QtCore.QVariant(verse.chapter),
'verse':QtCore.QVariant(verse.verse),
'bible':QtCore.QVariant(bible),
'version':QtCore.QVariant(version.value),
'copyright':QtCore.QVariant(copyright.value),
#'permission':QtCore.QVariant(permission.value),
'text':QtCore.QVariant(verse.text),
'dual_bible':QtCore.QVariant(dual_bible)
}
bible_text = u' %s %d:%d (%s)' % (verse.book.name,
verse.chapter, verse.verse, version.value)
# set the row title
bible_verse = QtGui.QListWidgetItem(bible_text)
#bible_verse.setData(QtCore.Qt.UserRole,
# QtCore.QVariant(bible_text))
vdict = {
'bible': QtCore.QVariant(bible),
'version': QtCore.QVariant(version.value),
'copyright': QtCore.QVariant(copyright.value),
'permission': QtCore.QVariant(permission),
'book': QtCore.QVariant(verse.book.name),
'chapter': QtCore.QVariant(verse.chapter),
'verse': QtCore.QVariant(verse.verse),
'text': QtCore.QVariant(verse.text)
}
bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(vdict))
self.listView.addItem(bible_verse)
row = self.listView.setCurrentRow(count)
row = self.listView.setCurrentRow(count + start_count)
if row:
row.setSelected(True)
def searchByReference(self, bible, search):
log.debug(u'searchByReference %s, %s', bible, search)
self.search_results = self.parent.manager.get_verses(bible, search)
self.search_results = {}
self.dual_search_results = {}

View File

@ -102,4 +102,4 @@ class OpenSongBible(BibleDB):
self.wizard.incrementProgressBar(u'Import canceled!')
return False
else:
return success
return success

View File

@ -184,4 +184,4 @@ class OSISBible(BibleDB):
self.wizard.incrementProgressBar(u'Import canceled!')
return False
else:
return success
return success

View File

@ -27,4 +27,4 @@
The :mod:`custom` module provides the Custom plugin which allows custom,
themed, text based items to be displayed without having to misuse another item
type.
"""
"""

View File

@ -28,7 +28,7 @@ import logging
from forms import EditCustomForm
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
from openlp.core.lib import Plugin, build_icon, translate
from openlp.core.lib.db import Manager
from openlp.plugins.custom.lib import CustomMediaItem, CustomTab
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
@ -53,7 +53,6 @@ class CustomPlugin(Plugin):
self.edit_custom_form = EditCustomForm(self.custommanager)
self.icon_path = u':/plugins/plugin_custom.png'
self.icon = build_icon(self.icon_path)
self.status = PluginStatus.Active
def getSettingsTab(self):
return CustomTab(self.name)
@ -96,4 +95,4 @@ class CustomPlugin(Plugin):
CustomSlide.theme_name == oldTheme)
for custom in customsUsingTheme:
custom.theme_name = newTheme
self.custommanager.save_object(custom)
self.custommanager.save_object(custom)

View File

@ -24,4 +24,4 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from editcustomform import EditCustomForm
from editcustomform import EditCustomForm

View File

@ -27,8 +27,9 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate
from openlp.core.ui import SpellTextEdit
class Ui_customEditDialog(object):
class Ui_CustomEditDialog(object):
def setupUi(self, customEditDialog):
customEditDialog.setObjectName(u'customEditDialog')
customEditDialog.resize(590, 541)
@ -38,94 +39,94 @@ class Ui_customEditDialog(object):
self.gridLayout.setObjectName(u'gridLayout')
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(u'horizontalLayout')
self.TitleLabel = QtGui.QLabel(customEditDialog)
self.TitleLabel.setObjectName(u'TitleLabel')
self.horizontalLayout.addWidget(self.TitleLabel)
self.TitleEdit = QtGui.QLineEdit(customEditDialog)
self.TitleLabel.setBuddy(self.TitleEdit)
self.TitleEdit.setObjectName(u'TitleEdit')
self.horizontalLayout.addWidget(self.TitleEdit)
self.titleLabel = QtGui.QLabel(customEditDialog)
self.titleLabel.setObjectName(u'titleLabel')
self.horizontalLayout.addWidget(self.titleLabel)
self.titleEdit = QtGui.QLineEdit(customEditDialog)
self.titleLabel.setBuddy(self.titleEdit)
self.titleEdit.setObjectName(u'titleEdit')
self.horizontalLayout.addWidget(self.titleEdit)
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
self.horizontalLayout_4 = QtGui.QHBoxLayout()
self.horizontalLayout_4.setObjectName(u'horizontalLayout_4')
self.VerseListView = QtGui.QListWidget(customEditDialog)
self.VerseListView.setAlternatingRowColors(True)
self.VerseListView.setObjectName(u'VerseListView')
self.horizontalLayout_4.addWidget(self.VerseListView)
self.horizontalLayout4 = QtGui.QHBoxLayout()
self.horizontalLayout4.setObjectName(u'horizontalLayout4')
self.verseListView = QtGui.QListWidget(customEditDialog)
self.verseListView.setAlternatingRowColors(True)
self.verseListView.setObjectName(u'verseListView')
self.horizontalLayout4.addWidget(self.verseListView)
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(u'verticalLayout')
self.UpButton = QtGui.QPushButton(customEditDialog)
self.UpButton.setIcon(build_icon(u':/services/service_up.png'))
self.UpButton.setObjectName(u'UpButton')
self.verticalLayout.addWidget(self.UpButton)
self.upButton = QtGui.QPushButton(customEditDialog)
self.upButton.setIcon(build_icon(u':/services/service_up.png'))
self.upButton.setObjectName(u'upButton')
self.verticalLayout.addWidget(self.upButton)
spacerItem = QtGui.QSpacerItem(20, 128, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.DownButton = QtGui.QPushButton(customEditDialog)
self.DownButton.setIcon(build_icon(u':/services/service_down.png'))
self.DownButton.setObjectName(u'DownButton')
self.verticalLayout.addWidget(self.DownButton)
self.horizontalLayout_4.addLayout(self.verticalLayout)
self.gridLayout.addLayout(self.horizontalLayout_4, 1, 0, 1, 1)
self.EditWidget = QtGui.QWidget(customEditDialog)
self.EditWidget.setObjectName(u'EditWidget')
self.EditLayout_3 = QtGui.QHBoxLayout(self.EditWidget)
self.EditLayout_3.setSpacing(8)
self.EditLayout_3.setMargin(0)
self.EditLayout_3.setObjectName(u'EditLayout_3')
self.VerseTextEdit = QtGui.QTextEdit(self.EditWidget)
self.VerseTextEdit.setObjectName(u'VerseTextEdit')
self.EditLayout_3.addWidget(self.VerseTextEdit)
self.ButtonWidge = QtGui.QWidget(self.EditWidget)
self.ButtonWidge.setObjectName(u'ButtonWidge')
self.verticalLayout_2 = QtGui.QVBoxLayout(self.ButtonWidge)
self.verticalLayout_2.setObjectName(u'verticalLayout_2')
self.AddButton = QtGui.QPushButton(self.ButtonWidge)
self.AddButton.setObjectName(u'AddButton')
self.verticalLayout_2.addWidget(self.AddButton)
self.EditButton = QtGui.QPushButton(self.ButtonWidge)
self.EditButton.setObjectName(u'EditButton')
self.verticalLayout_2.addWidget(self.EditButton)
self.EditAllButton = QtGui.QPushButton(self.ButtonWidge)
self.EditAllButton.setObjectName(u'EditAllButton')
self.verticalLayout_2.addWidget(self.EditAllButton)
self.SaveButton = QtGui.QPushButton(self.ButtonWidge)
self.SaveButton.setObjectName(u'SaveButton')
self.verticalLayout_2.addWidget(self.SaveButton)
self.DeleteButton = QtGui.QPushButton(self.ButtonWidge)
self.DeleteButton.setObjectName(u'DeleteButton')
self.verticalLayout_2.addWidget(self.DeleteButton)
self.ClearButton = QtGui.QPushButton(self.ButtonWidge)
self.ClearButton.setObjectName(u'ClearButton')
self.verticalLayout_2.addWidget(self.ClearButton)
self.SplitButton = QtGui.QPushButton(self.ButtonWidge)
self.SplitButton.setObjectName(u'SplitButton')
self.verticalLayout_2.addWidget(self.SplitButton)
self.downButton = QtGui.QPushButton(customEditDialog)
self.downButton.setIcon(build_icon(u':/services/service_down.png'))
self.downButton.setObjectName(u'downButton')
self.verticalLayout.addWidget(self.downButton)
self.horizontalLayout4.addLayout(self.verticalLayout)
self.gridLayout.addLayout(self.horizontalLayout4, 1, 0, 1, 1)
self.editWidget = QtGui.QWidget(customEditDialog)
self.editWidget.setObjectName(u'editWidget')
self.editLayout3 = QtGui.QHBoxLayout(self.editWidget)
self.editLayout3.setSpacing(8)
self.editLayout3.setMargin(0)
self.editLayout3.setObjectName(u'editLayout3')
self.verseTextEdit = SpellTextEdit(self)
self.verseTextEdit.setObjectName(u'verseTextEdit')
self.editLayout3.addWidget(self.verseTextEdit)
self.buttonWidget = QtGui.QWidget(self.editWidget)
self.buttonWidget.setObjectName(u'buttonWidget')
self.verticalLayout2 = QtGui.QVBoxLayout(self.buttonWidget)
self.verticalLayout2.setObjectName(u'verticalLayout2')
self.addButton = QtGui.QPushButton(self.buttonWidget)
self.addButton.setObjectName(u'addButton')
self.verticalLayout2.addWidget(self.addButton)
self.editButton = QtGui.QPushButton(self.buttonWidget)
self.editButton.setObjectName(u'editButton')
self.verticalLayout2.addWidget(self.editButton)
self.editAllButton = QtGui.QPushButton(self.buttonWidget)
self.editAllButton.setObjectName(u'editAllButton')
self.verticalLayout2.addWidget(self.editAllButton)
self.saveButton = QtGui.QPushButton(self.buttonWidget)
self.saveButton.setObjectName(u'saveButton')
self.verticalLayout2.addWidget(self.saveButton)
self.deleteButton = QtGui.QPushButton(self.buttonWidget)
self.deleteButton.setObjectName(u'deleteButton')
self.verticalLayout2.addWidget(self.deleteButton)
self.clearButton = QtGui.QPushButton(self.buttonWidget)
self.clearButton.setObjectName(u'clearButton')
self.verticalLayout2.addWidget(self.clearButton)
self.splitButton = QtGui.QPushButton(self.buttonWidget)
self.splitButton.setObjectName(u'splitButton')
self.verticalLayout2.addWidget(self.splitButton)
spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem1)
self.EditLayout_3.addWidget(self.ButtonWidge)
self.gridLayout.addWidget(self.EditWidget, 2, 0, 1, 1)
self.horizontalLayout_3 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setObjectName(u'horizontalLayout_3')
self.ThemeLabel = QtGui.QLabel(customEditDialog)
self.ThemeLabel.setObjectName(u'ThemeLabel')
self.horizontalLayout_3.addWidget(self.ThemeLabel)
self.ThemeComboBox = QtGui.QComboBox(customEditDialog)
self.ThemeLabel.setBuddy(self.ThemeComboBox)
self.ThemeComboBox.setObjectName(u'ThemeComboBox')
self.horizontalLayout_3.addWidget(self.ThemeComboBox)
self.gridLayout.addLayout(self.horizontalLayout_3, 3, 0, 1, 1)
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(u'horizontalLayout_2')
self.CreditLabel = QtGui.QLabel(customEditDialog)
self.CreditLabel.setObjectName(u'CreditLabel')
self.horizontalLayout_2.addWidget(self.CreditLabel)
self.CreditEdit = QtGui.QLineEdit(customEditDialog)
self.CreditLabel.setBuddy(self.CreditEdit)
self.CreditEdit.setObjectName(u'CreditEdit')
self.horizontalLayout_2.addWidget(self.CreditEdit)
self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1)
self.verticalLayout2.addItem(spacerItem1)
self.editLayout3.addWidget(self.buttonWidget)
self.gridLayout.addWidget(self.editWidget, 2, 0, 1, 1)
self.horizontalLayout3 = QtGui.QHBoxLayout()
self.horizontalLayout3.setObjectName(u'horizontalLayout3')
self.themeLabel = QtGui.QLabel(customEditDialog)
self.themeLabel.setObjectName(u'themeLabel')
self.horizontalLayout3.addWidget(self.themeLabel)
self.themeComboBox = QtGui.QComboBox(customEditDialog)
self.themeLabel.setBuddy(self.themeComboBox)
self.themeComboBox.setObjectName(u'themeComboBox')
self.horizontalLayout3.addWidget(self.themeComboBox)
self.gridLayout.addLayout(self.horizontalLayout3, 3, 0, 1, 1)
self.horizontalLayout2 = QtGui.QHBoxLayout()
self.horizontalLayout2.setObjectName(u'horizontalLayout2')
self.creditLabel = QtGui.QLabel(customEditDialog)
self.creditLabel.setObjectName(u'creditLabel')
self.horizontalLayout2.addWidget(self.creditLabel)
self.creditEdit = QtGui.QLineEdit(customEditDialog)
self.creditLabel.setBuddy(self.creditEdit)
self.creditEdit.setObjectName(u'creditEdit')
self.horizontalLayout2.addWidget(self.creditEdit)
self.gridLayout.addLayout(self.horizontalLayout2, 4, 0, 1, 1)
self.buttonBox = QtGui.QDialogButtonBox(customEditDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
@ -141,49 +142,49 @@ class Ui_customEditDialog(object):
def retranslateUi(self, customEditDialog):
customEditDialog.setWindowTitle(
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
self.UpButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide up once '
self.upButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide up one '
'position.'))
self.DownButton.setToolTip(
self.downButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide down one '
'position.'))
self.TitleLabel.setText(
self.titleLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Title:'))
self.AddButton.setText(
self.addButton.setText(
translate('CustomPlugin.EditCustomForm', 'Add New'))
self.AddButton.setToolTip(
self.addButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Add a new slide at '
'bottom.'))
self.EditButton.setText(
self.editButton.setText(
translate('CustomPlugin.EditCustomForm', 'Edit'))
self.EditButton.setToolTip(
self.editButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit the selected '
'slide.'))
self.EditAllButton.setText(
self.editAllButton.setText(
translate('CustomPlugin.EditCustomForm', 'Edit All'))
self.EditAllButton.setToolTip(
self.editAllButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit all the slides at '
'once.'))
self.SaveButton.setText(
self.saveButton.setText(
translate('CustomPlugin.EditCustomForm', 'Save'))
self.SaveButton.setToolTip(
self.saveButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Save the slide currently '
'being edited.'))
self.DeleteButton.setText(
self.deleteButton.setText(
translate('CustomPlugin.EditCustomForm', 'Delete'))
self.DeleteButton.setToolTip(
self.deleteButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Delete the selected '
'slide.'))
self.ClearButton.setText(
self.clearButton.setText(
translate('CustomPlugin.EditCustomForm', 'Clear'))
self.ClearButton.setToolTip(
self.clearButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Clear edit area'))
self.SplitButton.setText(
self.splitButton.setText(
translate('CustomPlugin.EditCustomForm', 'Split Slide'))
self.SplitButton.setToolTip(
self.splitButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Split a slide into two '
'by inserting a slide splitter.'))
self.ThemeLabel.setText(
self.themeLabel.setText(
translate('CustomPlugin.EditCustomForm', 'The&me:'))
self.CreditLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Credits:'))
self.creditLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Credits:'))

View File

@ -28,14 +28,14 @@ import logging
from PyQt4 import QtCore, QtGui
from editcustomdialog import Ui_customEditDialog
from openlp.core.lib import Receiver, translate
from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide
from editcustomdialog import Ui_CustomEditDialog
log = logging.getLogger(__name__)
class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
"""
Class documentation goes here.
"""
@ -55,28 +55,28 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
self.previewButton, QtGui.QDialogButtonBox.ActionRole)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview)
QtCore.QObject.connect(self.AddButton,
QtCore.QObject.connect(self.addButton,
QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed)
QtCore.QObject.connect(self.EditButton,
QtCore.QObject.connect(self.editButton,
QtCore.SIGNAL(u'pressed()'), self.onEditButtonPressed)
QtCore.QObject.connect(self.EditAllButton,
QtCore.QObject.connect(self.editAllButton,
QtCore.SIGNAL(u'pressed()'), self.onEditAllButtonPressed)
QtCore.QObject.connect(self.SaveButton,
QtCore.QObject.connect(self.saveButton,
QtCore.SIGNAL(u'pressed()'), self.onSaveButtonPressed)
QtCore.QObject.connect(self.DeleteButton,
QtCore.QObject.connect(self.deleteButton,
QtCore.SIGNAL(u'pressed()'), self.onDeleteButtonPressed)
QtCore.QObject.connect(self.ClearButton,
QtCore.QObject.connect(self.clearButton,
QtCore.SIGNAL(u'pressed()'), self.onClearButtonPressed)
QtCore.QObject.connect(self.UpButton,
QtCore.QObject.connect(self.upButton,
QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed)
QtCore.QObject.connect(self.DownButton,
QtCore.QObject.connect(self.downButton,
QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed)
QtCore.QObject.connect(self.SplitButton,
QtCore.QObject.connect(self.splitButton,
QtCore.SIGNAL(u'pressed()'), self.onSplitButtonPressed)
QtCore.QObject.connect(self.VerseListView,
QtCore.QObject.connect(self.verseListView,
QtCore.SIGNAL(u'itemDoubleClicked(QListWidgetItem*)'),
self.onVerseListViewSelected)
QtCore.QObject.connect(self.VerseListView,
QtCore.QObject.connect(self.verseListView,
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
self.onVerseListViewPressed)
QtCore.QObject.connect(Receiver.get_receiver(),
@ -93,45 +93,45 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
def initialise(self):
self.editAll = False
self.AddButton.setEnabled(True)
self.DeleteButton.setEnabled(False)
self.EditButton.setEnabled(False)
self.EditAllButton.setEnabled(True)
self.SaveButton.setEnabled(False)
self.ClearButton.setEnabled(False)
self.SplitButton.setEnabled(False)
self.TitleEdit.setText(u'')
self.CreditEdit.setText(u'')
self.VerseTextEdit.clear()
self.VerseListView.clear()
self.addButton.setEnabled(True)
self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(True)
self.saveButton.setEnabled(False)
self.clearButton.setEnabled(False)
self.splitButton.setEnabled(False)
self.titleEdit.setText(u'')
self.creditEdit.setText(u'')
self.verseTextEdit.clear()
self.verseListView.clear()
#make sure we have a new item
self.customSlide = CustomSlide()
self.ThemeComboBox.addItem(u'')
self.themeComboBox.addItem(u'')
def loadThemes(self, themelist):
self.ThemeComboBox.clear()
self.ThemeComboBox.addItem(u'')
self.themeComboBox.clear()
self.themeComboBox.addItem(u'')
for themename in themelist:
self.ThemeComboBox.addItem(themename)
self.themeComboBox.addItem(themename)
def loadCustom(self, id, preview=False):
self.customSlide = CustomSlide()
self.initialise()
if id != 0:
self.customSlide = self.custommanager.get_object(CustomSlide, id)
self.TitleEdit.setText(self.customSlide.title)
self.CreditEdit.setText(self.customSlide.credits)
self.titleEdit.setText(self.customSlide.title)
self.creditEdit.setText(self.customSlide.credits)
customXML = CustomXMLParser(self.customSlide.text)
verseList = customXML.get_verses()
for verse in verseList:
self.VerseListView.addItem(verse[1])
self.verseListView.addItem(verse[1])
theme = self.customSlide.theme_name
id = self.ThemeComboBox.findText(theme, QtCore.Qt.MatchExactly)
id = self.themeComboBox.findText(theme, QtCore.Qt.MatchExactly)
if id == -1:
id = 0 # Not Found
self.ThemeComboBox.setCurrentIndex(id)
self.themeComboBox.setCurrentIndex(id)
else:
self.ThemeComboBox.setCurrentIndex(0)
self.themeComboBox.setCurrentIndex(0)
#if not preview hide the preview button
self.previewButton.setVisible(False)
if preview:
@ -151,134 +151,133 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
valid, message = self._validate()
if not valid:
QtGui.QMessageBox.critical(self,
translate('CustomPlugin.EditCustomForm', 'Error'), message,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
translate('CustomPlugin.EditCustomForm', 'Error'), message)
return False
sxml = CustomXMLBuilder()
sxml.new_document()
sxml.add_lyrics_to_song()
count = 1
for i in range (0, self.VerseListView.count()):
for i in range(0, self.verseListView.count()):
sxml.add_verse_to_lyrics(u'custom', unicode(count),
unicode(self.VerseListView.item(i).text()))
unicode(self.verseListView.item(i).text()))
count += 1
self.customSlide.title = unicode(self.TitleEdit.displayText(), u'utf-8')
self.customSlide.title = unicode(self.titleEdit.displayText(), u'utf-8')
self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8')
self.customSlide.credits = unicode(self.CreditEdit.displayText(),
self.customSlide.credits = unicode(self.creditEdit.displayText(),
u'utf-8')
self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText(),
self.customSlide.theme_name = unicode(self.themeComboBox.currentText(),
u'utf-8')
return self.custommanager.save_object(self.customSlide)
def onUpButtonPressed(self):
selectedRow = self.VerseListView.currentRow()
selectedRow = self.verseListView.currentRow()
if selectedRow != 0:
qw = self.VerseListView.takeItem(selectedRow)
self.VerseListView.insertItem(selectedRow - 1, qw)
self.VerseListView.setCurrentRow(selectedRow - 1)
qw = self.verseListView.takeItem(selectedRow)
self.verseListView.insertItem(selectedRow - 1, qw)
self.verseListView.setCurrentRow(selectedRow - 1)
def onDownButtonPressed(self):
selectedRow = self.VerseListView.currentRow()
selectedRow = self.verseListView.currentRow()
# zero base arrays
if selectedRow != self.VerseListView.count() - 1:
qw = self.VerseListView.takeItem(selectedRow)
self.VerseListView.insertItem(selectedRow + 1, qw)
self.VerseListView.setCurrentRow(selectedRow + 1)
if selectedRow != self.verseListView.count() - 1:
qw = self.verseListView.takeItem(selectedRow)
self.verseListView.insertItem(selectedRow + 1, qw)
self.verseListView.setCurrentRow(selectedRow + 1)
def onClearButtonPressed(self):
self.VerseTextEdit.clear()
self.verseTextEdit.clear()
self.editAll = False
self.AddButton.setEnabled(True)
self.EditAllButton.setEnabled(True)
self.SaveButton.setEnabled(False)
self.addButton.setEnabled(True)
self.editAllButton.setEnabled(True)
self.saveButton.setEnabled(False)
def onVerseListViewPressed(self, item):
self.DeleteButton.setEnabled(True)
self.EditButton.setEnabled(True)
self.deleteButton.setEnabled(True)
self.editButton.setEnabled(True)
def onVerseListViewSelected(self, item):
self.editText(item.text())
def onAddButtonPressed(self):
self.VerseListView.addItem(self.VerseTextEdit.toPlainText())
self.DeleteButton.setEnabled(False)
self.VerseTextEdit.clear()
self.verseListView.addItem(self.verseTextEdit.toPlainText())
self.deleteButton.setEnabled(False)
self.verseTextEdit.clear()
def onEditButtonPressed(self):
self.editText(self.VerseListView.currentItem().text())
self.editText(self.verseListView.currentItem().text())
def onEditAllButtonPressed(self):
self.editAll = True
self.AddButton.setEnabled(False)
self.SplitButton.setEnabled(True)
if self.VerseListView.count() > 0:
self.addButton.setEnabled(False)
self.splitButton.setEnabled(True)
if self.verseListView.count() > 0:
verse_list = u''
for row in range(0, self.VerseListView.count()):
item = self.VerseListView.item(row)
for row in range(0, self.verseListView.count()):
item = self.verseListView.item(row)
verse_list += item.text()
if row != self.VerseListView.count() - 1:
if row != self.verseListView.count() - 1:
verse_list += u'\n[---]\n'
self.editText(verse_list)
def editText(self, text):
self.beforeText = text
self.VerseTextEdit.setPlainText(text)
self.DeleteButton.setEnabled(False)
self.EditButton.setEnabled(False)
self.EditAllButton.setEnabled(False)
self.SaveButton.setEnabled(True)
self.ClearButton.setEnabled(True)
self.verseTextEdit.setPlainText(text)
self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(False)
self.saveButton.setEnabled(True)
self.clearButton.setEnabled(True)
def onSaveButtonPressed(self):
if self.editAll:
self.VerseListView.clear()
for row in unicode(self.VerseTextEdit.toPlainText()).split(
self.verseListView.clear()
for row in unicode(self.verseTextEdit.toPlainText()).split(
u'\n[---]\n'):
self.VerseListView.addItem(row)
self.verseListView.addItem(row)
else:
self.VerseListView.currentItem().setText(
self.VerseTextEdit.toPlainText())
self.verseListView.currentItem().setText(
self.verseTextEdit.toPlainText())
#number of lines has change
if len(self.beforeText.split(u'\n')) != \
len(self.VerseTextEdit.toPlainText().split(u'\n')):
len(self.verseTextEdit.toPlainText().split(u'\n')):
tempList = {}
for row in range(0, self.VerseListView.count()):
tempList[row] = self.VerseListView.item(row).text()
self.VerseListView.clear()
for row in range(0, self.verseListView.count()):
tempList[row] = self.verseListView.item(row).text()
self.verseListView.clear()
for row in range (0, len(tempList)):
self.VerseListView.addItem(tempList[row])
self.VerseListView.repaint()
self.AddButton.setEnabled(True)
self.SaveButton.setEnabled(False)
self.EditButton.setEnabled(False)
self.EditAllButton.setEnabled(True)
self.SplitButton.setEnabled(False)
self.VerseTextEdit.clear()
self.verseListView.addItem(tempList[row])
self.verseListView.repaint()
self.addButton.setEnabled(True)
self.saveButton.setEnabled(False)
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(True)
self.splitButton.setEnabled(False)
self.verseTextEdit.clear()
def onSplitButtonPressed(self):
if self.VerseTextEdit.textCursor().columnNumber() != 0:
self.VerseTextEdit.insertPlainText(u'\n')
self.VerseTextEdit.insertPlainText(u'[---]\n' )
self.VerseTextEdit.setFocus()
if self.verseTextEdit.textCursor().columnNumber() != 0:
self.verseTextEdit.insertPlainText(u'\n')
self.verseTextEdit.insertPlainText(u'[---]\n' )
self.verseTextEdit.setFocus()
def onDeleteButtonPressed(self):
self.VerseListView.takeItem(self.VerseListView.currentRow())
self.EditButton.setEnabled(False)
self.EditAllButton.setEnabled(True)
self.verseListView.takeItem(self.verseListView.currentRow())
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(True)
def _validate(self):
if len(self.TitleEdit.displayText()) == 0:
self.TitleEdit.setFocus()
if len(self.titleEdit.displayText()) == 0:
self.titleEdit.setFocus()
return False, translate('CustomPlugin.EditCustomForm',
'You need to type in a title.')
# must have 1 slide
if self.VerseListView.count() == 0:
self.VerseTextEdit.setFocus()
if self.verseListView.count() == 0:
self.verseTextEdit.setFocus()
return False, translate('CustomPlugin.EditCustomForm',
'You need to add at least one slide')
if self.VerseTextEdit.toPlainText():
self.VerseTextEdit.setFocus()
if self.verseTextEdit.toPlainText():
self.verseTextEdit.setFocus()
return False, translate('CustomPlugin.EditCustomForm',
'You have one or more unsaved slides, please either save your '
'slide(s) or clear your changes.')
return True, u''
return True, u''

View File

@ -26,4 +26,4 @@
from customxmlhandler import CustomXMLBuilder, CustomXMLParser
from mediaitem import CustomMediaItem
from customtab import CustomTab
from customtab import CustomTab

View File

@ -38,29 +38,29 @@ class CustomTab(SettingsTab):
def setupUi(self):
self.setObjectName(u'CustomTab')
self.tabTitleVisible = translate('CustomPlugin.CustomTab', 'Custom')
self.CustomLayout = QtGui.QFormLayout(self)
self.CustomLayout.setSpacing(8)
self.CustomLayout.setMargin(8)
self.CustomLayout.setObjectName(u'CustomLayout')
self.CustomModeGroupBox = QtGui.QGroupBox(self)
self.CustomModeGroupBox.setObjectName(u'CustomModeGroupBox')
self.CustomModeLayout = QtGui.QVBoxLayout(self.CustomModeGroupBox)
self.CustomModeLayout.setSpacing(8)
self.CustomModeLayout.setMargin(8)
self.CustomModeLayout.setObjectName(u'CustomModeLayout')
self.DisplayFooterCheckBox = QtGui.QCheckBox(self.CustomModeGroupBox)
self.DisplayFooterCheckBox.setObjectName(u'DisplayFooterCheckBox')
self.CustomModeLayout.addWidget(self.DisplayFooterCheckBox)
self.CustomLayout.setWidget(
0, QtGui.QFormLayout.LabelRole, self.CustomModeGroupBox)
QtCore.QObject.connect(self.DisplayFooterCheckBox,
self.customLayout = QtGui.QFormLayout(self)
self.customLayout.setSpacing(8)
self.customLayout.setMargin(8)
self.customLayout.setObjectName(u'customLayout')
self.customModeGroupBox = QtGui.QGroupBox(self)
self.customModeGroupBox.setObjectName(u'customModeGroupBox')
self.customModeLayout = QtGui.QVBoxLayout(self.customModeGroupBox)
self.customModeLayout.setSpacing(8)
self.customModeLayout.setMargin(8)
self.customModeLayout.setObjectName(u'customModeLayout')
self.displayFooterCheckBox = QtGui.QCheckBox(self.customModeGroupBox)
self.displayFooterCheckBox.setObjectName(u'displayFooterCheckBox')
self.customModeLayout.addWidget(self.displayFooterCheckBox)
self.customLayout.setWidget(
0, QtGui.QFormLayout.LabelRole, self.customModeGroupBox)
QtCore.QObject.connect(self.displayFooterCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onDisplayFooterCheckBoxChanged)
def retranslateUi(self):
self.CustomModeGroupBox.setTitle(translate('CustomPlugin.CustomTab',
self.customModeGroupBox.setTitle(translate('CustomPlugin.CustomTab',
'Custom Display'))
self.DisplayFooterCheckBox.setText(
self.displayFooterCheckBox.setText(
translate('CustomPlugin.CustomTab', 'Display footer'))
def onDisplayFooterCheckBoxChanged(self, check_state):
@ -73,8 +73,8 @@ class CustomTab(SettingsTab):
self.displayFooter = QtCore.QSettings().value(
self.settingsSection + u'/display footer',
QtCore.QVariant(True)).toBool()
self.DisplayFooterCheckBox.setChecked(self.displayFooter)
self.displayFooterCheckBox.setChecked(self.displayFooter)
def save(self):
QtCore.QSettings().setValue(self.settingsSection + u'/display footer',
QtCore.QVariant(self.displayFooter))
QtCore.QVariant(self.displayFooter))

View File

@ -154,4 +154,4 @@ class CustomXMLParser(object):
"""
Debugging aid to dump XML so that we can see what we have.
"""
return dump(self.custom_xml)
return dump(self.custom_xml)

View File

@ -59,4 +59,4 @@ def init_schema(url):
mapper(CustomSlide, custom_slide_table)
metadata.create_all(checkfirst=True)
return session
return session

View File

@ -183,4 +183,4 @@ class CustomMediaItem(MediaManagerItem):
else:
raw_footer.append(u'')
service_item.raw_footer = raw_footer
return True
return True

View File

@ -26,4 +26,4 @@
"""
The :mod:`images` module provides the Images plugin. The Images plugin
provides the facility to display images from OpenLP.
"""
"""

View File

@ -26,8 +26,8 @@
import logging
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
from openlp.plugins.images.lib import ImageMediaItem, ImageTab
from openlp.core.lib import Plugin, build_icon, translate
from openlp.plugins.images.lib import ImageMediaItem
log = logging.getLogger(__name__)
@ -39,10 +39,6 @@ class ImagePlugin(Plugin):
self.weight = -7
self.icon_path = u':/plugins/plugin_images.png'
self.icon = build_icon(self.icon_path)
self.status = PluginStatus.Active
def getSettingsTab(self):
return ImageTab(self.name)
def getMediaManagerItem(self):
# Create the MediaManagerItem object
@ -60,4 +56,4 @@ class ImagePlugin(Plugin):
'background, which renders text-based items like songs with the '
'selected image as a background instead of the background '
'provided by the theme.')
return about_text
return about_text

View File

@ -25,4 +25,3 @@
###############################################################################
from mediaitem import ImageMediaItem
from imagetab import ImageTab

View File

@ -1,93 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, Receiver, translate
class ImageTab(SettingsTab):
"""
ImageTab is the Image settings tab in the settings dialog.
"""
def __init__(self, title):
SettingsTab.__init__(self, title)
def setupUi(self):
self.setObjectName(u'ImageTab')
self.tabTitleVisible = translate('ImagePlugin.ImageTab', 'Images')
self.ImageLayout = QtGui.QFormLayout(self)
self.ImageLayout.setSpacing(8)
self.ImageLayout.setMargin(8)
self.ImageLayout.setObjectName(u'ImageLayout')
self.ImageSettingsGroupBox = QtGui.QGroupBox(self)
self.ImageSettingsGroupBox.setObjectName(u'ImageSettingsGroupBox')
self.TimeoutLayout = QtGui.QHBoxLayout(self.ImageSettingsGroupBox)
self.TimeoutLayout.setSpacing(8)
self.TimeoutLayout.setMargin(8)
self.TimeoutLayout.setObjectName(u'TimeoutLayout')
self.TimeoutLabel = QtGui.QLabel(self.ImageSettingsGroupBox)
self.TimeoutLabel.setObjectName(u'TimeoutLabel')
self.TimeoutLayout.addWidget(self.TimeoutLabel)
self.TimeoutSpinBox = QtGui.QSpinBox(self.ImageSettingsGroupBox)
self.TimeoutSpinBox.setMinimum(1)
self.TimeoutSpinBox.setMaximum(180)
self.TimeoutSpinBox.setObjectName(u'TimeoutSpinBox')
self.TimeoutLayout.addWidget(self.TimeoutSpinBox)
self.TimeoutSpacer = QtGui.QSpacerItem(147, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.TimeoutLayout.addItem(self.TimeoutSpacer)
self.ImageLayout.setWidget(
0, QtGui.QFormLayout.LabelRole, self.ImageSettingsGroupBox)
# Signals and slots
QtCore.QObject.connect(self.TimeoutSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
def retranslateUi(self):
self.ImageSettingsGroupBox.setTitle(
translate('ImagePlugin.ImageTab', 'Image Settings'))
self.TimeoutLabel.setText(
translate('ImagePlugin.ImageTab', 'Slide loop delay:'))
self.TimeoutSpinBox.setSuffix(
translate('ImagePlugin.ImageTab', 'sec'))
def onTimeoutSpinBoxChanged(self):
self.loop_delay = self.TimeoutSpinBox.value()
def load(self):
self.loop_delay = QtCore.QSettings().value(
self.settingsSection + u'/loop delay',
QtCore.QVariant(5)).toInt()[0]
self.TimeoutSpinBox.setValue(self.loop_delay)
def save(self):
QtCore.QSettings().setValue(self.settingsSection + u'/loop delay',
QtCore.QVariant(self.loop_delay))
Receiver.send_message(u'slidecontroller_live_spin_delay',
self.loop_delay)
def postSetUp(self):
Receiver.send_message(u'slidecontroller_live_spin_delay',
self.loop_delay)

View File

@ -110,8 +110,14 @@ class ImageMediaItem(MediaManagerItem):
u':/slides/slide_blank.png',
translate('ImagePlugin.MediaItem', 'Replace Live Background'),
self.onReplaceClick, False)
self.resetButton = self.toolbar.addToolbarButton(
translate('ImagePlugin.MediaItem', u'Reset Background'),
u':/system/system_close.png',
translate('ImagePlugin.MediaItem', 'Reset Live Background'),
self.onResetClick, False)
# Add the song widget to the page layout
self.pageLayout.addWidget(self.ImageWidget)
self.resetButton.setVisible(False)
def onDeleteClick(self):
"""
@ -169,6 +175,10 @@ class ImageMediaItem(MediaManagerItem):
else:
return False
def onResetClick(self):
self.resetButton.setVisible(False)
self.parent.liveController.display.resetImage()
def onReplaceClick(self):
if check_item_selected(self.listView,
translate('ImagePlugin.MediaItem',
@ -178,7 +188,8 @@ class ImageMediaItem(MediaManagerItem):
bitem = self.listView.item(item.row())
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
frame = QtGui.QImage(unicode(filename))
self.parent.displayManager.displayImageWithText(frame)
self.parent.liveController.display.image(frame)
self.resetButton.setVisible(True)
def onPreviewClick(self):
MediaManagerItem.onPreviewClick(self)
MediaManagerItem.onPreviewClick(self)

View File

@ -28,4 +28,4 @@ The :mod:`media` module provides the Media plugin which allows OpenLP to
display videos. The media supported depends not only on the Python support
but also extensively on the codecs installed on the underlying operating system
being picked up and usable by Python.
"""
"""

View File

@ -26,4 +26,4 @@
from mediaitem import MediaMediaItem
__all__ = ['MediaMediaItem']
__all__ = ['MediaMediaItem']

View File

@ -97,8 +97,17 @@ class MediaMediaItem(MediaManagerItem):
u':/slides/slide_blank.png',
translate('MediaPlugin.MediaItem', 'Replace Live Background'),
self.onReplaceClick, False)
self.resetButton = self.toolbar.addToolbarButton(
u'Reset Background', u':/system/system_close.png',
translate('ImagePlugin.MediaItem', 'Reset Live Background'),
self.onResetClick, False)
# Add the song widget to the page layout
self.pageLayout.addWidget(self.ImageWidget)
self.resetButton.setVisible(False)
def onResetClick(self):
self.resetButton.setVisible(False)
self.parent.liveController.display.resetVideo()
def onReplaceClick(self):
if check_item_selected(self.listView,
@ -106,7 +115,8 @@ class MediaMediaItem(MediaManagerItem):
'You must select a media file to replace the background with.')):
item = self.listView.currentItem()
filename = unicode(item.data(QtCore.Qt.UserRole).toString())
self.parent.displayManager.displayVideo(filename)
self.parent.liveController.display.video(filename, 0)
self.resetButton.setVisible(True)
def generateSlideData(self, service_item, item=None):
if item is None:
@ -149,4 +159,4 @@ class MediaMediaItem(MediaManagerItem):
img = QtGui.QPixmap(u':/media/media_video.png').toImage()
item_name.setIcon(build_icon(img))
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
self.listView.addItem(item_name)
self.listView.addItem(item_name)

View File

@ -28,7 +28,7 @@ import logging
from PyQt4.phonon import Phonon
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
from openlp.core.lib import Plugin, build_icon, translate
from openlp.plugins.media.lib import MediaMediaItem
log = logging.getLogger(__name__)
@ -43,7 +43,6 @@ class MediaPlugin(Plugin):
self.icon = build_icon(self.icon_path)
# passed with drag and drop messages
self.dnd_id = u'Media'
self.status = PluginStatus.Active
self.audio_list = u''
self.video_list = u''
for mimetype in Phonon.BackendCapabilities.availableMimeTypes():
@ -76,4 +75,4 @@ class MediaPlugin(Plugin):
def about(self):
about_text = translate('MediaPlugin', '<strong>Media Plugin</strong>'
'<br />The media plugin provides playback of audio and video.')
return about_text
return about_text

View File

@ -26,4 +26,4 @@
"""
The :mod:`presentations` module provides the Presentations plugin which allows
OpenLP to show presentations from most popular presentation packages.
"""
"""

View File

@ -27,4 +27,4 @@
from presentationcontroller import PresentationController
from messagelistener import MessageListener
from mediaitem import PresentationMediaItem
from presentationtab import PresentationTab
from presentationtab import PresentationTab

View File

@ -69,8 +69,8 @@ class ImpressController(PresentationController):
"""
log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Impress')
self.supports = [u'.odp']
self.alsosupports = [u'.ppt', u'.pps', u'.pptx', u'.ppsx']
self.supports = [u'odp']
self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx']
self.process = None
self.desktop = None
self.manager = None
@ -463,4 +463,4 @@ class ImpressDocument(PresentationDocument):
shape = notes.getByIndex(idx)
if shape.supportsService("com.sun.star.drawing.Text"):
text += shape.getString() + '\n'
return text
return text

View File

@ -79,7 +79,6 @@ class PresentationMediaItem(MediaManagerItem):
'Select Presentation(s)')
self.Automatic = translate('PresentationPlugin.MediaItem',
'Automatic')
self.buildFileMaskString()
def buildFileMaskString(self):
"""
@ -92,7 +91,7 @@ class PresentationMediaItem(MediaManagerItem):
self.controllers[controller].alsosupports
for type in types:
if fileType.find(type) == -1:
fileType += u'*%s ' % type
fileType += u'*.%s ' % type
self.parent.serviceManager.supportedSuffixes(type)
self.OnNewFileMasks = translate('PresentationPlugin.MediaItem',
'Presentations (%s)' % fileType)
@ -164,7 +163,7 @@ class PresentationMediaItem(MediaManagerItem):
self.DisplayTypeComboBox.insertItem(0, self.Automatic)
self.DisplayTypeComboBox.setCurrentIndex(0)
if QtCore.QSettings().value(self.settingsSection + u'/override app',
QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
self.PresentationWidget.show()
else:
self.PresentationWidget.hide()
@ -189,8 +188,7 @@ class PresentationMediaItem(MediaManagerItem):
translate('PresentationPlugin.MediaItem',
'File Exists'),
translate('PresentationPlugin.MediaItem',
'A presentation with that filename already exists.'),
QtGui.QMessageBox.Ok)
'A presentation with that filename already exists.'))
continue
controller_name = self.findControllerByType(filename)
if controller_name:
@ -214,8 +212,7 @@ class PresentationMediaItem(MediaManagerItem):
self, translate('PresentationPlugin.MediaItem',
'Unsupported File'),
translate('PresentationPlugin.MediaItem',
'This type of presentation is not supported'),
QtGui.QMessageBox.Ok)
'This type of presentation is not supported'))
continue
item_name = QtGui.QListWidgetItem(filename)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
@ -288,7 +285,7 @@ class PresentationMediaItem(MediaManagerItem):
"supports" the extension. If none found, then look for a controller
which "alsosupports" it instead.
"""
filetype = os.path.splitext(filename)[1]
filetype = filename.split(u'.')[1]
if not filetype:
return None
for controller in self.controllers:
@ -299,4 +296,4 @@ class PresentationMediaItem(MediaManagerItem):
if self.controllers[controller].enabled():
if filetype in self.controllers[controller].alsosupports:
return controller
return None
return None

View File

@ -367,4 +367,4 @@ class MessageListener(object):
to check which slide is currently displayed so the slidecontroller
view can be updated
"""
self.live_handler.poll()
self.live_handler.poll()

View File

@ -54,7 +54,7 @@ class PowerpointController(PresentationController):
"""
log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Powerpoint')
self.supports = [u'.ppt', u'.pps', u'.pptx', u'.ppsx']
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
self.process = None
def check_available(self):
@ -310,4 +310,4 @@ class PowerpointDocument(PresentationDocument):
shape = shapes(idx + 1)
if shape.HasTextFrame:
text += shape.TextFrame.TextRange.Text + '\n'
return text
return text

View File

@ -50,7 +50,7 @@ class PptviewController(PresentationController):
log.debug(u'Initialising')
self.process = None
PresentationController.__init__(self, plugin, u'Powerpoint Viewer')
self.supports = [u'.ppt', u'.pps', u'.pptx', u'.ppsx']
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
def check_available(self):
"""
@ -150,7 +150,8 @@ class PptviewDocument(PresentationDocument):
if self.check_thumbnails():
return
for idx in range(self.get_slide_count()):
path = u'%s\\slide%s.bmp' % (self.get_temp_folder(), unicode(idx + 1))
path = u'%s\\slide%s.bmp' % (self.get_temp_folder(),
unicode(idx + 1))
self.convert_thumbnail(path, idx + 1)
def close_presentation(self):
@ -246,4 +247,4 @@ class PptviewDocument(PresentationDocument):
"""
Triggers the previous slide on the running presentation
"""
self.controller.process.PrevStep(self.pptid)
self.controller.process.PrevStep(self.pptid)

Some files were not shown because too many files have changed in this diff Show More