forked from openlp/openlp
merge trunk
This commit is contained in:
commit
0c2b68ac54
@ -390,163 +390,207 @@ is the function which has to be called from outside. The generated and returned
|
||||
import logging
|
||||
|
||||
from PyQt5 import QtWebKit
|
||||
from string import Template
|
||||
|
||||
from openlp.core.common import Settings
|
||||
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, VerticalType, HorizontalType
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# TODO: Verify where this is used before converting to python3
|
||||
HTMLSRC = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLP Display</title>
|
||||
<style>
|
||||
*{
|
||||
HTML_SRC = Template("""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLP Display</title>
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body {
|
||||
${bg_css};
|
||||
}
|
||||
.size {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#black {
|
||||
z-index: 8;
|
||||
background-color: black;
|
||||
display: none;
|
||||
}
|
||||
#bgimage {
|
||||
z-index: 1;
|
||||
}
|
||||
#image {
|
||||
z-index: 2;
|
||||
}
|
||||
${css_additions}
|
||||
#footer {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
${footer_css}
|
||||
}
|
||||
/* lyric css */${lyrics_css}
|
||||
sup {
|
||||
font-size: 0.6em;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
top: -0.3em;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
var timer = null;
|
||||
var transition = ${transitions};
|
||||
${js_additions}
|
||||
|
||||
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 = '';
|
||||
switch(state){
|
||||
case 'theme':
|
||||
lyrics = 'hidden';
|
||||
break;
|
||||
case 'black':
|
||||
black = 'block';
|
||||
break;
|
||||
case 'desktop':
|
||||
break;
|
||||
}
|
||||
document.getElementById('black').style.display = black;
|
||||
document.getElementById('lyricsmain').style.visibility = lyrics;
|
||||
document.getElementById('image').style.visibility = lyrics;
|
||||
document.getElementById('footer').style.visibility = lyrics;
|
||||
}
|
||||
|
||||
function show_footer(footertext){
|
||||
document.getElementById('footer').innerHTML = footertext;
|
||||
}
|
||||
|
||||
function show_text(new_text){
|
||||
var match = /-webkit-text-fill-color:[^;\"]+/gi;
|
||||
if(timer != null)
|
||||
clearTimeout(timer);
|
||||
/*
|
||||
QtWebkit bug with outlines and justify causing outline alignment
|
||||
problems. (Bug 859950) Surround each word with a <span> to workaround,
|
||||
but only in this scenario.
|
||||
*/
|
||||
var txt = document.getElementById('lyricsmain');
|
||||
if(window.getComputedStyle(txt).textAlign == 'justify'){
|
||||
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
|
||||
new_text = new_text.replace(/(\s| )+(?![^<]*>)/g,
|
||||
function(match) {
|
||||
return '</span>' + match + '<span>';
|
||||
});
|
||||
new_text = '<span>' + new_text + '</span>';
|
||||
}
|
||||
}
|
||||
text_fade('lyricsmain', new_text);
|
||||
}
|
||||
|
||||
function text_fade(id, new_text){
|
||||
/*
|
||||
Show the text.
|
||||
*/
|
||||
var text = document.getElementById(id);
|
||||
if(text == null) return;
|
||||
if(!transition){
|
||||
text.innerHTML = new_text;
|
||||
return;
|
||||
}
|
||||
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
|
||||
text.style.opacity = '0.1';
|
||||
// Fade new text in after the old text has finished fading out.
|
||||
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
|
||||
}
|
||||
|
||||
function _show_text(text, new_text) {
|
||||
/*
|
||||
Helper function to show the new_text delayed.
|
||||
*/
|
||||
text.innerHTML = new_text;
|
||||
text.style.opacity = '1';
|
||||
// Wait until the text is completely visible. We want to save the timer id, to be able to call
|
||||
// clearTimeout(timer) when the text has changed before finishing fading.
|
||||
timer = window.setTimeout(function(){timer = null;}, 400);
|
||||
}
|
||||
|
||||
function show_text_completed(){
|
||||
return (timer == null);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<img id="bgimage" class="size" ${bg_image} />
|
||||
<img id="image" class="size" ${image} />
|
||||
${html_additions}
|
||||
<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
|
||||
<div id="footer" class="footer"></div>
|
||||
<div id="black" class="size"></div>
|
||||
</body>
|
||||
</html>
|
||||
""")
|
||||
|
||||
LYRICS_SRC = Template("""
|
||||
.lyricstable {
|
||||
z-index: 5;
|
||||
position: absolute;
|
||||
display: table;
|
||||
${stable}
|
||||
}
|
||||
.lyricscell {
|
||||
display: table-cell;
|
||||
word-wrap: break-word;
|
||||
-webkit-transition: opacity 0.4s ease;
|
||||
${lyrics}
|
||||
}
|
||||
.lyricsmain {
|
||||
${main}
|
||||
}
|
||||
""")
|
||||
|
||||
FOOTER_SRC = Template("""
|
||||
left: ${left}px;
|
||||
bottom: ${bottom}px;
|
||||
width: ${width}px;
|
||||
font-family: ${family};
|
||||
font-size: ${size}pt;
|
||||
color: ${color};
|
||||
text-align: left;
|
||||
white-space: ${space};
|
||||
""")
|
||||
|
||||
LYRICS_FORMAT_SRC = Template("""
|
||||
${justify}word-wrap: break-word;
|
||||
text-align: ${align};
|
||||
vertical-align: ${valign};
|
||||
font-family: ${font};
|
||||
font-size: ${size}pt;
|
||||
color: ${color};
|
||||
line-height: ${line}%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body {
|
||||
%s;
|
||||
}
|
||||
.size {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 100%%;
|
||||
height: 100%%;
|
||||
}
|
||||
#black {
|
||||
z-index: 8;
|
||||
background-color: black;
|
||||
display: none;
|
||||
}
|
||||
#bgimage {
|
||||
z-index: 1;
|
||||
}
|
||||
#image {
|
||||
z-index: 2;
|
||||
}
|
||||
%s
|
||||
#footer {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
%s
|
||||
}
|
||||
/* lyric css */
|
||||
%s
|
||||
sup {
|
||||
font-size: 0.6em;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
top: -0.3em;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
var timer = null;
|
||||
var transition = %s;
|
||||
%s
|
||||
|
||||
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 = '';
|
||||
switch(state){
|
||||
case 'theme':
|
||||
lyrics = 'hidden';
|
||||
break;
|
||||
case 'black':
|
||||
black = 'block';
|
||||
break;
|
||||
case 'desktop':
|
||||
break;
|
||||
}
|
||||
document.getElementById('black').style.display = black;
|
||||
document.getElementById('lyricsmain').style.visibility = lyrics;
|
||||
document.getElementById('image').style.visibility = lyrics;
|
||||
document.getElementById('footer').style.visibility = lyrics;
|
||||
}
|
||||
|
||||
function show_footer(footertext){
|
||||
document.getElementById('footer').innerHTML = footertext;
|
||||
}
|
||||
|
||||
function show_text(new_text){
|
||||
var match = /-webkit-text-fill-color:[^;\"]+/gi;
|
||||
if(timer != null)
|
||||
clearTimeout(timer);
|
||||
/*
|
||||
QtWebkit bug with outlines and justify causing outline alignment
|
||||
problems. (Bug 859950) Surround each word with a <span> to workaround,
|
||||
but only in this scenario.
|
||||
*/
|
||||
var txt = document.getElementById('lyricsmain');
|
||||
if(window.getComputedStyle(txt).textAlign == 'justify'){
|
||||
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
|
||||
new_text = new_text.replace(/(\s| )+(?![^<]*>)/g,
|
||||
function(match) {
|
||||
return '</span>' + match + '<span>';
|
||||
});
|
||||
new_text = '<span>' + new_text + '</span>';
|
||||
}
|
||||
}
|
||||
text_fade('lyricsmain', new_text);
|
||||
}
|
||||
|
||||
function text_fade(id, new_text){
|
||||
/*
|
||||
Show the text.
|
||||
*/
|
||||
var text = document.getElementById(id);
|
||||
if(text == null) return;
|
||||
if(!transition){
|
||||
text.innerHTML = new_text;
|
||||
return;
|
||||
}
|
||||
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
|
||||
text.style.opacity = '0.1';
|
||||
// Fade new text in after the old text has finished fading out.
|
||||
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
|
||||
}
|
||||
|
||||
function _show_text(text, new_text) {
|
||||
/*
|
||||
Helper function to show the new_text delayed.
|
||||
*/
|
||||
text.innerHTML = new_text;
|
||||
text.style.opacity = '1';
|
||||
// Wait until the text is completely visible. We want to save the timer id, to be able to call
|
||||
// clearTimeout(timer) when the text has changed before finishing fading.
|
||||
timer = window.setTimeout(function(){timer = null;}, 400);
|
||||
}
|
||||
|
||||
function show_text_completed(){
|
||||
return (timer == null);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<img id="bgimage" class="size" %s />
|
||||
<img id="image" class="size" %s />
|
||||
%s
|
||||
<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
|
||||
<div id="footer" class="footer"></div>
|
||||
<div id="black" class="size"></div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
padding-bottom: ${bottom};
|
||||
padding-left: ${left}px;
|
||||
width: ${width}px;
|
||||
height: ${height}px;${font_style}${font_weight}
|
||||
""")
|
||||
|
||||
|
||||
def build_html(item, screen, is_live, background, image=None, plugins=None):
|
||||
@ -582,18 +626,17 @@ def build_html(item, screen, is_live, background, image=None, plugins=None):
|
||||
css_additions += plugin.get_display_css()
|
||||
js_additions += plugin.get_display_javascript()
|
||||
html_additions += plugin.get_display_html()
|
||||
html = HTMLSRC % (
|
||||
build_background_css(item, width),
|
||||
css_additions,
|
||||
build_footer_css(item, height),
|
||||
build_lyrics_css(item),
|
||||
'true' if theme_data and theme_data.display_slide_transition and is_live else 'false',
|
||||
js_additions,
|
||||
bgimage_src,
|
||||
image_src,
|
||||
html_additions
|
||||
)
|
||||
return html
|
||||
return HTML_SRC.substitute(bg_css=build_background_css(item, width),
|
||||
css_additions=css_additions,
|
||||
footer_css=build_footer_css(item, height),
|
||||
lyrics_css=build_lyrics_css(item),
|
||||
transitions='true' if (theme_data and
|
||||
theme_data.display_slide_transition and
|
||||
is_live) else 'false',
|
||||
js_additions=js_additions,
|
||||
bg_image=bgimage_src,
|
||||
image=image_src,
|
||||
html_additions=html_additions)
|
||||
|
||||
|
||||
def webkit_version():
|
||||
@ -650,24 +693,6 @@ def build_lyrics_css(item):
|
||||
|
||||
:param item: Service Item containing theme and location information
|
||||
"""
|
||||
# TODO: Verify this before converting to python3
|
||||
style = """
|
||||
.lyricstable {
|
||||
z-index: 5;
|
||||
position: absolute;
|
||||
display: table;
|
||||
%s
|
||||
}
|
||||
.lyricscell {
|
||||
display: table-cell;
|
||||
word-wrap: break-word;
|
||||
-webkit-transition: opacity 0.4s ease;
|
||||
%s
|
||||
}
|
||||
.lyricsmain {
|
||||
%s
|
||||
}
|
||||
"""
|
||||
theme_data = item.theme_data
|
||||
lyricstable = ''
|
||||
lyrics = ''
|
||||
@ -680,8 +705,7 @@ def build_lyrics_css(item):
|
||||
lyricsmain += ' text-shadow: {theme} {shadow}px ' \
|
||||
'{shadow}px;'.format(theme=theme_data.font_main_shadow_color,
|
||||
shadow=theme_data.font_main_shadow_size)
|
||||
lyrics_css = style % (lyricstable, lyrics, lyricsmain)
|
||||
return lyrics_css
|
||||
return LYRICS_SRC.substitute(stable=lyricstable, lyrics=lyrics, main=lyricsmain)
|
||||
|
||||
|
||||
def build_lyrics_outline_css(theme_data):
|
||||
@ -710,38 +734,23 @@ def build_lyrics_format_css(theme_data, width, height):
|
||||
"""
|
||||
align = HorizontalType.Names[theme_data.display_horizontal_align]
|
||||
valign = VerticalType.Names[theme_data.display_vertical_align]
|
||||
if theme_data.font_main_outline:
|
||||
left_margin = int(theme_data.font_main_outline_size) * 2
|
||||
else:
|
||||
left_margin = 0
|
||||
justify = 'white-space:pre-wrap;'
|
||||
left_margin = (int(theme_data.font_main_outline_size) * 2) if theme_data.font_main_outline else 0
|
||||
# fix tag incompatibilities
|
||||
if theme_data.display_horizontal_align == HorizontalType.Justify:
|
||||
justify = ''
|
||||
if theme_data.display_vertical_align == VerticalType.Bottom:
|
||||
padding_bottom = '0.5em'
|
||||
else:
|
||||
padding_bottom = '0'
|
||||
lyrics = '{justify} word-wrap: break-word; ' \
|
||||
'text-align: {align}; vertical-align: {valign}; font-family: {font}; ' \
|
||||
'font-size: {size}pt; color: {color}; line-height: {line:d}%; margin: 0;' \
|
||||
'padding: 0; padding-bottom: {bottom}; padding-left: {left}px; width: {width}px; ' \
|
||||
'height: {height}px; '.format(justify=justify,
|
||||
align=align,
|
||||
valign=valign,
|
||||
font=theme_data.font_main_name,
|
||||
size=theme_data.font_main_size,
|
||||
color=theme_data.font_main_color,
|
||||
line=100 + int(theme_data.font_main_line_adjustment),
|
||||
bottom=padding_bottom,
|
||||
left=left_margin,
|
||||
width=width,
|
||||
height=height)
|
||||
if theme_data.font_main_italics:
|
||||
lyrics += 'font-style:italic; '
|
||||
if theme_data.font_main_bold:
|
||||
lyrics += 'font-weight:bold; '
|
||||
return lyrics
|
||||
justify = '' if (theme_data.display_horizontal_align == HorizontalType.Justify) else ' white-space: pre-wrap;\n'
|
||||
padding_bottom = '0.5em' if (theme_data.display_vertical_align == VerticalType.Bottom) else '0'
|
||||
return LYRICS_FORMAT_SRC.substitute(justify=justify,
|
||||
align=align,
|
||||
valign=valign,
|
||||
font=theme_data.font_main_name,
|
||||
size=theme_data.font_main_size,
|
||||
color=theme_data.font_main_color,
|
||||
line='{line:d}'.format(line=100 + int(theme_data.font_main_line_adjustment)),
|
||||
bottom=padding_bottom,
|
||||
left=left_margin,
|
||||
width=width,
|
||||
height=height,
|
||||
font_style='\n font-style: italic;' if theme_data.font_main_italics else '',
|
||||
font_weight='\n font-weight: bold;' if theme_data.font_main_bold else '')
|
||||
|
||||
|
||||
def build_footer_css(item, height):
|
||||
@ -751,22 +760,11 @@ def build_footer_css(item, height):
|
||||
:param item: Service Item to be processed.
|
||||
:param height:
|
||||
"""
|
||||
style = """
|
||||
left: {left}px;
|
||||
bottom: {bottom}px;
|
||||
width: {width}px;
|
||||
font-family: {family};
|
||||
font-size: {size}pt;
|
||||
color: {color};
|
||||
text-align: left;
|
||||
white-space: {space};
|
||||
"""
|
||||
theme = item.theme_data
|
||||
if not theme or not item.footer:
|
||||
return ''
|
||||
bottom = height - int(item.footer.y()) - int(item.footer.height())
|
||||
whitespace = 'normal' if Settings().value('themes/wrap footer') else 'nowrap'
|
||||
lyrics_html = style.format(left=item.footer.x(), bottom=bottom, width=item.footer.width(),
|
||||
family=theme.font_footer_name, size=theme.font_footer_size,
|
||||
color=theme.font_footer_color, space=whitespace)
|
||||
return lyrics_html
|
||||
return FOOTER_SRC.substitute(left=item.footer.x(), bottom=bottom, width=item.footer.width(),
|
||||
family=theme.font_footer_name, size=theme.font_footer_size,
|
||||
color=theme.font_footer_color, space=whitespace)
|
||||
|
@ -565,13 +565,13 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
if self.has_run_wizard:
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the {button} button to return to OpenLP.'
|
||||
).format(text=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText(text)
|
||||
else:
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the {button} button to start OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText()
|
||||
self.progress_label.setText(text)
|
||||
else:
|
||||
if self.has_run_wizard:
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
@ -582,7 +582,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Click the {button} button to start OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText()
|
||||
self.progress_label.setText(text)
|
||||
self.finish_button.setVisible(True)
|
||||
self.finish_button.setEnabled(True)
|
||||
self.cancel_button.setVisible(False)
|
||||
|
@ -104,7 +104,7 @@ class Ui_EditBibleDialog(object):
|
||||
for book in BiblesResourcesDB.get_books():
|
||||
self.book_name_label[book['abbreviation']] = QtWidgets.QLabel(self.book_name_widget)
|
||||
self.book_name_label[book['abbreviation']].setObjectName(
|
||||
'book_name_label[{name}]'.format(book=book['abbreviation']))
|
||||
'book_name_label[{book}]'.format(book=book['abbreviation']))
|
||||
self.book_name_edit[book['abbreviation']] = QtWidgets.QLineEdit(self.book_name_widget)
|
||||
self.book_name_edit[book['abbreviation']].setObjectName(
|
||||
'book_name_edit[{name}]'.format(name=book['abbreviation']))
|
||||
|
@ -156,8 +156,8 @@ class OpenSongImport(SongImport):
|
||||
ustring = str(root.__getattr__(attr))
|
||||
if isinstance(fn_or_string, str):
|
||||
if attr in ['ccli']:
|
||||
ustring = ''.join(re.findall('\d+', ustring))
|
||||
if ustring:
|
||||
ustring = ''.join(re.findall('\d+', ustring))
|
||||
setattr(self, fn_or_string, int(ustring))
|
||||
else:
|
||||
setattr(self, fn_or_string, None)
|
||||
|
@ -603,7 +603,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
else:
|
||||
verse_index = VerseType.from_tag(verse[0]['type'])
|
||||
verse_tag = VerseType.translated_tags[verse_index]
|
||||
verse_def = '{tag}{label}'.format(tzg=verse_tag, text=verse[0]['label'])
|
||||
verse_def = '{tag}{text}'.format(tag=verse_tag, text=verse[0]['label'])
|
||||
service_item.add_from_text(verse[1], verse_def)
|
||||
service_item.title = song.title
|
||||
author_list = self.generate_footer(service_item, song)
|
||||
|
@ -14,177 +14,190 @@ from tests.functional import MagicMock, patch
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
HTML = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLP Display</title>
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body {
|
||||
;
|
||||
}
|
||||
.size {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#black {
|
||||
z-index: 8;
|
||||
background-color: black;
|
||||
display: none;
|
||||
}
|
||||
#bgimage {
|
||||
z-index: 1;
|
||||
}
|
||||
#image {
|
||||
z-index: 2;
|
||||
}
|
||||
plugin CSS
|
||||
#footer {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
dummy: dummy;
|
||||
}
|
||||
/* lyric css */
|
||||
|
||||
sup {
|
||||
font-size: 0.6em;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
top: -0.3em;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
var timer = null;
|
||||
var transition = false;
|
||||
plugin JS
|
||||
|
||||
function show_image(src){
|
||||
var img = document.getElementById('image');
|
||||
img.src = src;
|
||||
if(src == '')
|
||||
img.style.display = 'none';
|
||||
else
|
||||
img.style.display = 'block';
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenLP Display</title>
|
||||
<style>
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
body {
|
||||
;
|
||||
}
|
||||
.size {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#black {
|
||||
z-index: 8;
|
||||
background-color: black;
|
||||
display: none;
|
||||
}
|
||||
#bgimage {
|
||||
z-index: 1;
|
||||
}
|
||||
#image {
|
||||
z-index: 2;
|
||||
}
|
||||
plugin CSS
|
||||
#footer {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
dummy: dummy;
|
||||
}
|
||||
/* lyric css */
|
||||
sup {
|
||||
font-size: 0.6em;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
top: -0.3em;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
var timer = null;
|
||||
var transition = false;
|
||||
plugin JS
|
||||
|
||||
function show_blank(state){
|
||||
var black = 'none';
|
||||
var lyrics = '';
|
||||
switch(state){
|
||||
case 'theme':
|
||||
lyrics = 'hidden';
|
||||
break;
|
||||
case 'black':
|
||||
black = 'block';
|
||||
break;
|
||||
case 'desktop':
|
||||
break;
|
||||
function show_image(src){
|
||||
var img = document.getElementById('image');
|
||||
img.src = src;
|
||||
if(src == '')
|
||||
img.style.display = 'none';
|
||||
else
|
||||
img.style.display = 'block';
|
||||
}
|
||||
document.getElementById('black').style.display = black;
|
||||
document.getElementById('lyricsmain').style.visibility = lyrics;
|
||||
document.getElementById('image').style.visibility = lyrics;
|
||||
document.getElementById('footer').style.visibility = lyrics;
|
||||
}
|
||||
|
||||
function show_footer(footertext){
|
||||
document.getElementById('footer').innerHTML = footertext;
|
||||
}
|
||||
|
||||
function show_text(new_text){
|
||||
var match = /-webkit-text-fill-color:[^;"]+/gi;
|
||||
if(timer != null)
|
||||
clearTimeout(timer);
|
||||
/*
|
||||
QtWebkit bug with outlines and justify causing outline alignment
|
||||
problems. (Bug 859950) Surround each word with a <span> to workaround,
|
||||
but only in this scenario.
|
||||
*/
|
||||
var txt = document.getElementById('lyricsmain');
|
||||
if(window.getComputedStyle(txt).textAlign == 'justify'){
|
||||
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
|
||||
new_text = new_text.replace(/(\s| )+(?![^<]*>)/g,
|
||||
function(match) {
|
||||
return '</span>' + match + '<span>';
|
||||
});
|
||||
new_text = '<span>' + new_text + '</span>';
|
||||
function show_blank(state){
|
||||
var black = 'none';
|
||||
var lyrics = '';
|
||||
switch(state){
|
||||
case 'theme':
|
||||
lyrics = 'hidden';
|
||||
break;
|
||||
case 'black':
|
||||
black = 'block';
|
||||
break;
|
||||
case 'desktop':
|
||||
break;
|
||||
}
|
||||
document.getElementById('black').style.display = black;
|
||||
document.getElementById('lyricsmain').style.visibility = lyrics;
|
||||
document.getElementById('image').style.visibility = lyrics;
|
||||
document.getElementById('footer').style.visibility = lyrics;
|
||||
}
|
||||
text_fade('lyricsmain', new_text);
|
||||
}
|
||||
|
||||
function text_fade(id, new_text){
|
||||
/*
|
||||
Show the text.
|
||||
*/
|
||||
var text = document.getElementById(id);
|
||||
if(text == null) return;
|
||||
if(!transition){
|
||||
function show_footer(footertext){
|
||||
document.getElementById('footer').innerHTML = footertext;
|
||||
}
|
||||
|
||||
function show_text(new_text){
|
||||
var match = /-webkit-text-fill-color:[^;"]+/gi;
|
||||
if(timer != null)
|
||||
clearTimeout(timer);
|
||||
/*
|
||||
QtWebkit bug with outlines and justify causing outline alignment
|
||||
problems. (Bug 859950) Surround each word with a <span> to workaround,
|
||||
but only in this scenario.
|
||||
*/
|
||||
var txt = document.getElementById('lyricsmain');
|
||||
if(window.getComputedStyle(txt).textAlign == 'justify'){
|
||||
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
|
||||
new_text = new_text.replace(/(\s| )+(?![^<]*>)/g,
|
||||
function(match) {
|
||||
return '</span>' + match + '<span>';
|
||||
});
|
||||
new_text = '<span>' + new_text + '</span>';
|
||||
}
|
||||
}
|
||||
text_fade('lyricsmain', new_text);
|
||||
}
|
||||
|
||||
function text_fade(id, new_text){
|
||||
/*
|
||||
Show the text.
|
||||
*/
|
||||
var text = document.getElementById(id);
|
||||
if(text == null) return;
|
||||
if(!transition){
|
||||
text.innerHTML = new_text;
|
||||
return;
|
||||
}
|
||||
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
|
||||
text.style.opacity = '0.1';
|
||||
// Fade new text in after the old text has finished fading out.
|
||||
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
|
||||
}
|
||||
|
||||
function _show_text(text, new_text) {
|
||||
/*
|
||||
Helper function to show the new_text delayed.
|
||||
*/
|
||||
text.innerHTML = new_text;
|
||||
return;
|
||||
text.style.opacity = '1';
|
||||
// Wait until the text is completely visible. We want to save the timer id, to be able to call
|
||||
// clearTimeout(timer) when the text has changed before finishing fading.
|
||||
timer = window.setTimeout(function(){timer = null;}, 400);
|
||||
}
|
||||
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
|
||||
text.style.opacity = '0.1';
|
||||
// Fade new text in after the old text has finished fading out.
|
||||
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
|
||||
}
|
||||
|
||||
function _show_text(text, new_text) {
|
||||
/*
|
||||
Helper function to show the new_text delayed.
|
||||
*/
|
||||
text.innerHTML = new_text;
|
||||
text.style.opacity = '1';
|
||||
// Wait until the text is completely visible. We want to save the timer id, to be able to call
|
||||
// clearTimeout(timer) when the text has changed before finishing fading.
|
||||
timer = window.setTimeout(function(){timer = null;}, 400);
|
||||
}
|
||||
|
||||
function show_text_completed(){
|
||||
return (timer == null);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<img id="bgimage" class="size" style="display:none;" />
|
||||
<img id="image" class="size" style="display:none;" />
|
||||
plugin HTML
|
||||
<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
|
||||
<div id="footer" class="footer"></div>
|
||||
<div id="black" class="size"></div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
function show_text_completed(){
|
||||
return (timer == null);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<img id="bgimage" class="size" style="display:none;" />
|
||||
<img id="image" class="size" style="display:none;" />
|
||||
plugin HTML
|
||||
<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
|
||||
<div id="footer" class="footer"></div>
|
||||
<div id="black" class="size"></div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
BACKGROUND_CSS_RADIAL = 'background: -webkit-gradient(radial, 5 50%, 100, 5 50%, 5, from(#000000), to(#FFFFFF)) fixed'
|
||||
LYRICS_CSS = """
|
||||
.lyricstable {
|
||||
z-index: 5;
|
||||
position: absolute;
|
||||
display: table;
|
||||
left: 10px; top: 20px;
|
||||
}
|
||||
.lyricscell {
|
||||
display: table-cell;
|
||||
word-wrap: break-word;
|
||||
-webkit-transition: opacity 0.4s ease;
|
||||
lyrics_format_css
|
||||
}
|
||||
.lyricsmain {
|
||||
text-shadow: #000000 5px 5px;
|
||||
}
|
||||
"""
|
||||
.lyricstable {
|
||||
z-index: 5;
|
||||
position: absolute;
|
||||
display: table;
|
||||
left: 10px; top: 20px;
|
||||
}
|
||||
.lyricscell {
|
||||
display: table-cell;
|
||||
word-wrap: break-word;
|
||||
-webkit-transition: opacity 0.4s ease;
|
||||
lyrics_format_css
|
||||
}
|
||||
.lyricsmain {
|
||||
text-shadow: #000000 5px 5px;
|
||||
}
|
||||
"""
|
||||
LYRICS_OUTLINE_CSS = ' -webkit-text-stroke: 0.125em #000000; -webkit-text-fill-color: #FFFFFF; '
|
||||
LYRICS_FORMAT_CSS = ' word-wrap: break-word; text-align: justify; vertical-align: bottom; ' + \
|
||||
'font-family: Arial; font-size: 40pt; color: #FFFFFF; line-height: 108%; margin: 0;padding: 0; ' + \
|
||||
'padding-bottom: 0.5em; padding-left: 2px; width: 1580px; height: 810px; font-style:italic; font-weight:bold; '
|
||||
LYRICS_FORMAT_CSS = """
|
||||
word-wrap: break-word;
|
||||
text-align: justify;
|
||||
vertical-align: bottom;
|
||||
font-family: Arial;
|
||||
font-size: 40pt;
|
||||
color: #FFFFFF;
|
||||
line-height: 108%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-bottom: 0.5em;
|
||||
padding-left: 2px;
|
||||
width: 1580px;
|
||||
height: 810px;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
"""
|
||||
FOOTER_CSS_BASE = """
|
||||
left: 10px;
|
||||
bottom: 0px;
|
||||
|
@ -22,13 +22,13 @@
|
||||
"""
|
||||
This module contains tests for the OpenSong song importer.
|
||||
"""
|
||||
|
||||
import os
|
||||
from unittest import TestCase
|
||||
|
||||
from tests.helpers.songfileimport import SongImportTestHelper
|
||||
from openlp.plugins.songs.lib.importers.opensong import OpenSongImport
|
||||
from openlp.core.common import Registry
|
||||
|
||||
from tests.helpers.songfileimport import SongImportTestHelper
|
||||
from tests.functional import patch, MagicMock
|
||||
|
||||
TEST_PATH = os.path.abspath(
|
||||
@ -54,6 +54,8 @@ class TestOpenSongFileImport(SongImportTestHelper):
|
||||
self.load_external_result_data(os.path.join(TEST_PATH, 'One, Two, Three, Four, Five.json')))
|
||||
self.file_import([os.path.join(TEST_PATH, 'Amazing Grace2')],
|
||||
self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json')))
|
||||
self.file_import([os.path.join(TEST_PATH, 'Amazing Grace with bad CCLI')],
|
||||
self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace without CCLI.json')))
|
||||
|
||||
|
||||
class TestOpenSongImport(TestCase):
|
||||
|
@ -29,6 +29,7 @@ from unittest import TestCase
|
||||
|
||||
from openlp.plugins.songs.lib.importers.opensong import OpenSongImport
|
||||
from openlp.core.common import Registry
|
||||
|
||||
from tests.functional import patch, MagicMock, call
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -36,7 +37,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
class SongImportTestHelper(TestCase):
|
||||
"""
|
||||
This class is designed to be a helper class to reduce repition when testing the import of song files.
|
||||
This class is designed to be a helper class to reduce repetition when testing the import of song files.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SongImportTestHelper, self).__init__(*args, **kwargs)
|
||||
|
@ -53,4 +53,4 @@
|
||||
<key_line></key_line>
|
||||
<time_sig></time_sig>
|
||||
<style index="default_style"></style>
|
||||
</song>
|
||||
</song>
|
||||
|
56
tests/resources/opensongsongs/Amazing Grace with bad CCLI
Normal file
56
tests/resources/opensongsongs/Amazing Grace with bad CCLI
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<song>
|
||||
<title>Amazing Grace (Demonstration)</title>
|
||||
<author>John Newton, Edwin Excell & John P. Rees</author>
|
||||
<copyright>Public Domain </copyright>
|
||||
<presentation>V1 V2 V3 V4 V5</presentation>
|
||||
<capo print="false"></capo>
|
||||
<tempo></tempo>
|
||||
<ccli>GE</ccli>
|
||||
<theme>God: Assurance/Grace/Salvation</theme>
|
||||
<alttheme>Worship: Praise</alttheme>
|
||||
<user1> </user1>
|
||||
<user2> </user2>
|
||||
<user3> </user3>
|
||||
<lyrics>[V]
|
||||
;Test the chords format
|
||||
;Chords beging with .
|
||||
;Verses begin with their verse number
|
||||
;Link words with _
|
||||
;Comments begin with ;
|
||||
. D D7 G D
|
||||
1A______ma________zing grace! How sweet the sound!
|
||||
2'Twas grace that taught my heart to fear,
|
||||
3The Lord has pro____mised good to me,
|
||||
4Thro' ma________ny dan____gers, toils and snares
|
||||
5When we've been there ten thou__sand years,
|
||||
|
||||
. Bm E A A7
|
||||
1That saved a wretch like me!
|
||||
2And grace my fears re___lieved.
|
||||
3His Word my hope se___cures.
|
||||
4I have al___rea____dy come.
|
||||
5Bright shi___ning as the sun,
|
||||
|
||||
. D D7 G D
|
||||
1I once was lost, but now am found;
|
||||
2How pre___cious did that grace ap____pear,
|
||||
3He will my shield and por___tion be
|
||||
4'Tis grace that brought me safe thus far,
|
||||
5We've no less days to sing God's praise,
|
||||
|
||||
. Bm A G D
|
||||
1Was blind, but now I see.
|
||||
2The hour I first be_lieved.
|
||||
3As long as life en_dures.
|
||||
4And grace will lead me home.
|
||||
5Than when we first be_gun.
|
||||
|
||||
</lyrics>
|
||||
<hymn_number>Demonstration Songs 0</hymn_number>
|
||||
<key></key>
|
||||
<aka></aka>
|
||||
<key_line></key_line>
|
||||
<time_sig></time_sig>
|
||||
<style index="default_style"></style>
|
||||
</song>
|
@ -0,0 +1,42 @@
|
||||
{
|
||||
"authors": [
|
||||
"John Newton",
|
||||
"Edwin Excell",
|
||||
"John P. Rees"
|
||||
],
|
||||
"ccli_number": null,
|
||||
"comments": "\n\n\n",
|
||||
"copyright": "Public Domain ",
|
||||
"song_book_name": "Demonstration Songs",
|
||||
"song_number": 0,
|
||||
"title": "Amazing Grace (Demonstration)",
|
||||
"topics": [
|
||||
"Assurance",
|
||||
"Grace",
|
||||
"Praise",
|
||||
"Salvation"
|
||||
],
|
||||
"verse_order_list": [],
|
||||
"verses": [
|
||||
[
|
||||
"Amazing grace! How sweet the sound!\nThat saved a wretch like me!\nI once was lost, but now am found;\nWas blind, but now I see.",
|
||||
"v1"
|
||||
],
|
||||
[
|
||||
"'Twas grace that taught my heart to fear,\nAnd grace my fears relieved.\nHow precious did that grace appear,\nThe hour I first believed.",
|
||||
"v2"
|
||||
],
|
||||
[
|
||||
"The Lord has promised good to me,\nHis Word my hope secures.\nHe will my shield and portion be\nAs long as life endures.",
|
||||
"v3"
|
||||
],
|
||||
[
|
||||
"Thro' many dangers, toils and snares\nI have already come.\n'Tis grace that brought me safe thus far,\nAnd grace will lead me home.",
|
||||
"v4"
|
||||
],
|
||||
[
|
||||
"When we've been there ten thousand years,\nBright shining as the sun,\nWe've no less days to sing God's praise,\nThan when we first begun.",
|
||||
"v5"
|
||||
]
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user