forked from openlp/openlp
HEAD
This commit is contained in:
commit
7ebf4434a5
16
openlp.pyw
16
openlp.pyw
@ -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()
|
||||
|
@ -1 +1 @@
|
||||
1.9.2
|
||||
1.9.2-bzr987
|
@ -25,4 +25,4 @@
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`openlp` module contains all the project produced OpenLP functionality
|
||||
"""
|
||||
"""
|
||||
|
@ -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.
|
||||
"""
|
||||
"""
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -270,4 +270,4 @@ class Receiver(object):
|
||||
"""
|
||||
Get the global ``eventreceiver`` instance.
|
||||
"""
|
||||
return Receiver.eventreceiver
|
||||
return Receiver.eventreceiver
|
||||
|
445
openlp/core/lib/htmlbuilder.py
Normal file
445
openlp/core/lib/htmlbuilder.py
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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 = {}
|
@ -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
|
||||
|
@ -88,4 +88,4 @@ class SettingsTab(QtGui.QWidget):
|
||||
"""
|
||||
Changes which need to be made after setup of application
|
||||
"""
|
||||
pass
|
||||
pass
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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']
|
||||
|
@ -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'))
|
||||
|
@ -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)
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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'))
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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'))
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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'))
|
||||
|
@ -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)
|
||||
|
@ -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'))
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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'
|
||||
|
@ -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)
|
||||
|
@ -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']
|
||||
|
@ -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__
|
||||
|
@ -25,4 +25,4 @@
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`plugins` module provides all the project produced plugins
|
||||
"""
|
||||
"""
|
||||
|
@ -26,4 +26,4 @@
|
||||
"""
|
||||
The :mod:`alerts` module provides the Alerts plugin for producing impromptu
|
||||
on-screen announcements during a service.
|
||||
"""
|
||||
"""
|
||||
|
@ -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
|
||||
|
@ -24,4 +24,4 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
from alertform import AlertForm
|
||||
from alertform import AlertForm
|
||||
|
@ -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'))
|
||||
|
@ -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
|
||||
|
@ -25,4 +25,4 @@
|
||||
###############################################################################
|
||||
|
||||
from alertsmanager import AlertsManager
|
||||
from alertstab import AlertsTab
|
||||
from alertstab import AlertsTab
|
||||
|
@ -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()
|
||||
|
@ -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))
|
||||
|
||||
|
@ -55,4 +55,4 @@ def init_schema(url):
|
||||
mapper(AlertItem, alerts_table)
|
||||
|
||||
metadata.create_all(checkfirst=True)
|
||||
return session
|
||||
return session
|
||||
|
@ -26,4 +26,4 @@
|
||||
"""
|
||||
The :mod:`bibles' module provides the Bible plugin to enable OpenLP to display
|
||||
scripture.
|
||||
"""
|
||||
"""
|
||||
|
@ -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
|
||||
|
@ -26,4 +26,4 @@
|
||||
|
||||
from importwizardform import ImportWizardForm
|
||||
|
||||
__all__ = ['ImportWizardForm']
|
||||
__all__ = ['ImportWizardForm']
|
||||
|
@ -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%')
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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' ', 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'"', u'\"')
|
||||
text = text.replace(u''', 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)
|
@ -113,4 +113,4 @@ class CSVBible(BibleDB):
|
||||
self.wizard.incrementProgressBar(u'Import canceled!')
|
||||
return False
|
||||
else:
|
||||
return success
|
||||
return success
|
||||
|
@ -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)
|
||||
|
@ -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' ', u' ')
|
||||
continue
|
||||
if isinstance(item, NavigableString):
|
||||
verse_list[verse_number] = verse_list[verse_number] + item.replace(u' ', 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' ', 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(' |<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
|
@ -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
|
||||
|
@ -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 = {}
|
||||
|
@ -102,4 +102,4 @@ class OpenSongBible(BibleDB):
|
||||
self.wizard.incrementProgressBar(u'Import canceled!')
|
||||
return False
|
||||
else:
|
||||
return success
|
||||
return success
|
||||
|
@ -184,4 +184,4 @@ class OSISBible(BibleDB):
|
||||
self.wizard.incrementProgressBar(u'Import canceled!')
|
||||
return False
|
||||
else:
|
||||
return success
|
||||
return success
|
||||
|
Binary file not shown.
@ -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.
|
||||
"""
|
||||
"""
|
||||
|
@ -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)
|
||||
|
@ -24,4 +24,4 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
from editcustomform import EditCustomForm
|
||||
from editcustomform import EditCustomForm
|
||||
|
@ -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:'))
|
||||
|
@ -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''
|
||||
|
@ -26,4 +26,4 @@
|
||||
|
||||
from customxmlhandler import CustomXMLBuilder, CustomXMLParser
|
||||
from mediaitem import CustomMediaItem
|
||||
from customtab import CustomTab
|
||||
from customtab import CustomTab
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -59,4 +59,4 @@ def init_schema(url):
|
||||
mapper(CustomSlide, custom_slide_table)
|
||||
|
||||
metadata.create_all(checkfirst=True)
|
||||
return session
|
||||
return session
|
||||
|
@ -183,4 +183,4 @@ class CustomMediaItem(MediaManagerItem):
|
||||
else:
|
||||
raw_footer.append(u'')
|
||||
service_item.raw_footer = raw_footer
|
||||
return True
|
||||
return True
|
||||
|
@ -26,4 +26,4 @@
|
||||
"""
|
||||
The :mod:`images` module provides the Images plugin. The Images plugin
|
||||
provides the facility to display images from OpenLP.
|
||||
"""
|
||||
"""
|
||||
|
@ -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
|
||||
|
@ -25,4 +25,3 @@
|
||||
###############################################################################
|
||||
|
||||
from mediaitem import ImageMediaItem
|
||||
from imagetab import ImageTab
|
@ -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)
|
@ -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)
|
||||
|
@ -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.
|
||||
"""
|
||||
"""
|
||||
|
@ -26,4 +26,4 @@
|
||||
|
||||
from mediaitem import MediaMediaItem
|
||||
|
||||
__all__ = ['MediaMediaItem']
|
||||
__all__ = ['MediaMediaItem']
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -26,4 +26,4 @@
|
||||
"""
|
||||
The :mod:`presentations` module provides the Presentations plugin which allows
|
||||
OpenLP to show presentations from most popular presentation packages.
|
||||
"""
|
||||
"""
|
||||
|
@ -27,4 +27,4 @@
|
||||
from presentationcontroller import PresentationController
|
||||
from messagelistener import MessageListener
|
||||
from mediaitem import PresentationMediaItem
|
||||
from presentationtab import PresentationTab
|
||||
from presentationtab import PresentationTab
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user