forked from openlp/openlp
- Merged trunk on 24.7.16
- Added superflys startup traceback fix to my code - Resolved conflicts
This commit is contained in:
commit
aa1cd8fa91
|
@ -0,0 +1,17 @@
|
|||
[unittest]
|
||||
verbose = True
|
||||
|
||||
[log-capture]
|
||||
always-on = True
|
||||
clear-handlers = True
|
||||
filter = -nose
|
||||
log-level = ERROR
|
||||
|
||||
[test-result]
|
||||
always-on = True
|
||||
descriptions = True
|
||||
|
||||
[coverage]
|
||||
always-on = False
|
||||
coverage = openlp
|
||||
coverage-report = html
|
|
@ -195,7 +195,7 @@ def verify_ip_address(addr):
|
|||
return True if verify_ipv4(addr) else verify_ipv6(addr)
|
||||
|
||||
|
||||
def md5_hash(salt, data=None):
|
||||
def md5_hash(salt=None, data=None):
|
||||
"""
|
||||
Returns the hashed output of md5sum on salt,data
|
||||
using Python3 hashlib
|
||||
|
@ -205,8 +205,11 @@ def md5_hash(salt, data=None):
|
|||
:returns: str
|
||||
"""
|
||||
log.debug('md5_hash(salt="{text}")'.format(text=salt))
|
||||
if not salt and not data:
|
||||
return None
|
||||
hash_obj = hashlib.new('md5')
|
||||
hash_obj.update(salt)
|
||||
if salt:
|
||||
hash_obj.update(salt)
|
||||
if data:
|
||||
hash_obj.update(data)
|
||||
hash_value = hash_obj.hexdigest()
|
||||
|
@ -214,22 +217,30 @@ def md5_hash(salt, data=None):
|
|||
return hash_value
|
||||
|
||||
|
||||
def qmd5_hash(salt, data=None):
|
||||
def qmd5_hash(salt=None, data=None):
|
||||
"""
|
||||
Returns the hashed output of MD5Sum on salt, data
|
||||
using PyQt5.QCryptographicHash.
|
||||
using PyQt5.QCryptographicHash. Function returns a
|
||||
QByteArray instead of a text string.
|
||||
If you need a string instead, call with
|
||||
|
||||
result = str(qmd5_hash(salt=..., data=...), encoding='ascii')
|
||||
|
||||
:param salt: Initial salt
|
||||
:param data: OPTIONAL Data to hash
|
||||
:returns: str
|
||||
:returns: QByteArray
|
||||
"""
|
||||
log.debug('qmd5_hash(salt="{text}"'.format(text=salt))
|
||||
if salt is None and data is None:
|
||||
return None
|
||||
hash_obj = QHash(QHash.Md5)
|
||||
hash_obj.addData(salt)
|
||||
hash_obj.addData(data)
|
||||
if salt:
|
||||
hash_obj.addData(salt)
|
||||
if data:
|
||||
hash_obj.addData(data)
|
||||
hash_value = hash_obj.result().toHex()
|
||||
log.debug('qmd5_hash() returning "{text}"'.format(text=hash_value))
|
||||
return hash_value.data()
|
||||
log.debug('qmd5_hash() returning "{hash}"'.format(hash=hash_value))
|
||||
return hash_value
|
||||
|
||||
|
||||
def clean_button_text(button_text):
|
||||
|
|
|
@ -138,7 +138,7 @@ class CategoryList(object):
|
|||
for category in self.categories:
|
||||
if category.name == key:
|
||||
return category
|
||||
raise KeyError('Category "{keY}" does not exist.'.format(key=key))
|
||||
raise KeyError('Category "{key}" does not exist.'.format(key=key))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
|
|
|
@ -22,11 +22,12 @@
|
|||
"""
|
||||
The :mod:`db` module provides helper functions for database related methods.
|
||||
"""
|
||||
import sqlalchemy
|
||||
import logging
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
import sqlalchemy
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ def format_time(text, local_time):
|
|||
"""
|
||||
return local_time.strftime(match.group())
|
||||
|
||||
return re.sub('\%[a-zA-Z]', match_formatting, text)
|
||||
return re.sub(r'\%[a-zA-Z]', match_formatting, text)
|
||||
|
||||
|
||||
def get_locale_key(string):
|
||||
|
|
|
@ -55,6 +55,7 @@ class Registry(object):
|
|||
registry = cls()
|
||||
registry.service_list = {}
|
||||
registry.functions_list = {}
|
||||
registry.working_flags = {}
|
||||
# Allow the tests to remove Registry entries but not the live system
|
||||
registry.running_under_test = 'nose' in sys.argv[0]
|
||||
registry.initialising = True
|
||||
|
@ -90,8 +91,7 @@ class Registry(object):
|
|||
|
||||
def remove(self, key):
|
||||
"""
|
||||
Removes the registry value from the list based on the key passed in (Only valid and active for testing
|
||||
framework).
|
||||
Removes the registry value from the list based on the key passed in.
|
||||
|
||||
:param key: The service to be deleted.
|
||||
"""
|
||||
|
@ -145,3 +145,34 @@ class Registry(object):
|
|||
trace_error_handler(log)
|
||||
log.error("Event {event} called but not registered".format(event=event))
|
||||
return results
|
||||
|
||||
def get_flag(self, key):
|
||||
"""
|
||||
Extracts the working_flag value from the list based on the key passed in
|
||||
|
||||
:param key: The flag to be retrieved.
|
||||
"""
|
||||
if key in self.working_flags:
|
||||
return self.working_flags[key]
|
||||
else:
|
||||
trace_error_handler(log)
|
||||
log.error('Working Flag {key} not found in list'.format(key=key))
|
||||
raise KeyError('Working Flag {key} not found in list'.format(key=key))
|
||||
|
||||
def set_flag(self, key, reference):
|
||||
"""
|
||||
Sets a working_flag based on the key passed in.
|
||||
|
||||
:param key: The working_flag to be created this is usually a major class like "renderer" or "main_window" .
|
||||
:param reference: The data to be saved.
|
||||
"""
|
||||
self.working_flags[key] = reference
|
||||
|
||||
def remove_flag(self, key):
|
||||
"""
|
||||
Removes the working flags value from the list based on the key passed.
|
||||
|
||||
:param key: The working_flag to be deleted.
|
||||
"""
|
||||
if key in self.working_flags:
|
||||
del self.working_flags[key]
|
||||
|
|
|
@ -26,7 +26,7 @@ import datetime
|
|||
import logging
|
||||
import os
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PyQt5 import QtCore, QtGui
|
||||
|
||||
from openlp.core.common import ThemeLevel, SlideLimits, UiStrings, is_win, is_linux
|
||||
|
||||
|
@ -129,7 +129,7 @@ class Settings(QtCore.QSettings):
|
|||
'advanced/recent file count': 4,
|
||||
'advanced/save current plugin': False,
|
||||
'advanced/slide limits': SlideLimits.End,
|
||||
'advanced/slide max height': 0,
|
||||
'advanced/slide max height': -4,
|
||||
'advanced/single click preview': False,
|
||||
'advanced/single click service preview': False,
|
||||
'advanced/x11 bypass wm': X11_BYPASS_DEFAULT,
|
||||
|
|
|
@ -69,7 +69,7 @@ class UiStrings(object):
|
|||
self.Default = translate('OpenLP.Ui', 'Default')
|
||||
self.DefaultColor = translate('OpenLP.Ui', 'Default Color:')
|
||||
self.DefaultServiceName = translate('OpenLP.Ui', 'Service %Y-%m-%d %H-%M',
|
||||
'This may not contain any of the following characters: /\\?*|<>\[\]":+\n'
|
||||
'This may not contain any of the following characters: /\\?*|<>[]":+\n'
|
||||
'See http://docs.python.org/library/datetime'
|
||||
'.html#strftime-strptime-behavior for more information.')
|
||||
self.Delete = translate('OpenLP.Ui', '&Delete')
|
||||
|
|
|
@ -10,10 +10,10 @@ from datetime import datetime
|
|||
from distutils.version import LooseVersion
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from openlp.core.common import AppLocation, Settings
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
from openlp.core.common import AppLocation, Settings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
APPLICATION_VERSION = {}
|
||||
|
|
|
@ -24,13 +24,12 @@ The :mod:`lib` module contains most of the components and libraries that make
|
|||
OpenLP work.
|
||||
"""
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
import logging
|
||||
import os
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from PyQt5 import QtCore, QtGui, Qt, QtWidgets
|
||||
|
||||
|
||||
from openlp.core.common import translate
|
||||
|
||||
log = logging.getLogger(__name__ + '.__init__')
|
||||
|
@ -96,7 +95,7 @@ def get_text_file_string(text_file):
|
|||
content = None
|
||||
try:
|
||||
file_handle = open(text_file, 'r', encoding='utf-8')
|
||||
if not file_handle.read(3) == '\xEF\xBB\xBF':
|
||||
if file_handle.read(3) != '\xEF\xBB\xBF':
|
||||
# no BOM was found
|
||||
file_handle.seek(0)
|
||||
content = file_handle.read()
|
||||
|
@ -342,7 +341,6 @@ from .exceptions import ValidationError
|
|||
from .filedialog import FileDialog
|
||||
from .screen import ScreenList
|
||||
from .formattingtags import FormattingTags
|
||||
from .spelltextedit import SpellTextEdit
|
||||
from .plugin import PluginStatus, StringContent, Plugin
|
||||
from .pluginmanager import PluginManager
|
||||
from .settingstab import SettingsTab
|
||||
|
|
|
@ -122,6 +122,21 @@ def get_upgrade_op(session):
|
|||
return Operations(context)
|
||||
|
||||
|
||||
class BaseModel(object):
|
||||
"""
|
||||
BaseModel provides a base object with a set of generic functions
|
||||
"""
|
||||
@classmethod
|
||||
def populate(cls, **kwargs):
|
||||
"""
|
||||
Creates an instance of a class and populates it, returning the instance
|
||||
"""
|
||||
instance = cls()
|
||||
for key, value in kwargs.items():
|
||||
instance.__setattr__(key, value)
|
||||
return instance
|
||||
|
||||
|
||||
def upgrade_db(url, upgrade):
|
||||
"""
|
||||
Upgrade a database.
|
||||
|
@ -178,9 +193,9 @@ def upgrade_db(url, upgrade):
|
|||
version_meta = Metadata.populate(key='version', value=int(upgrade.__version__))
|
||||
session.commit()
|
||||
upgrade_version = upgrade.__version__
|
||||
version_meta = int(version_meta.value)
|
||||
version = int(version_meta.value)
|
||||
session.close()
|
||||
return version_meta, upgrade_version
|
||||
return version, upgrade_version
|
||||
|
||||
|
||||
def delete_database(plugin_name, db_file_name=None):
|
||||
|
@ -197,21 +212,6 @@ def delete_database(plugin_name, db_file_name=None):
|
|||
return delete_file(db_file_path)
|
||||
|
||||
|
||||
class BaseModel(object):
|
||||
"""
|
||||
BaseModel provides a base object with a set of generic functions
|
||||
"""
|
||||
@classmethod
|
||||
def populate(cls, **kwargs):
|
||||
"""
|
||||
Creates an instance of a class and populates it, returning the instance
|
||||
"""
|
||||
instance = cls()
|
||||
for key, value in kwargs.items():
|
||||
instance.__setattr__(key, value)
|
||||
return instance
|
||||
|
||||
|
||||
class Manager(object):
|
||||
"""
|
||||
Provide generic object persistence management
|
||||
|
|
|
@ -389,6 +389,7 @@ is the function which has to be called from outside. The generated and returned
|
|||
"""
|
||||
import logging
|
||||
|
||||
from string import Template
|
||||
from PyQt5 import QtWebKit
|
||||
|
||||
from openlp.core.common import Settings
|
||||
|
@ -396,157 +397,200 @@ from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, Vertic
|
|||
|
||||
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():
|
||||
|
@ -604,7 +647,7 @@ def webkit_version():
|
|||
webkit_ver = float(QtWebKit.qWebKitVersion())
|
||||
log.debug('Webkit version = {version}'.format(version=webkit_ver))
|
||||
except AttributeError:
|
||||
webkit_ver = 0
|
||||
webkit_ver = 0.0
|
||||
return webkit_ver
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -272,7 +272,7 @@ class ImageManager(QtCore.QObject):
|
|||
Add image to cache if it is not already there.
|
||||
"""
|
||||
log.debug('add_image {path}'.format(path=path))
|
||||
if not (path, source, width, height) in self._cache:
|
||||
if (path, source, width, height) not in self._cache:
|
||||
image = Image(path, source, background, width, height)
|
||||
self._cache[(path, source, width, height)] = image
|
||||
self._conversion_queue.put((image.priority, image.secondary_priority, image))
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
Provide plugin management
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import imp
|
||||
|
||||
from openlp.core.lib import Plugin, PluginStatus
|
||||
|
|
|
@ -40,13 +40,12 @@ log.debug('projector.lib.db module loaded')
|
|||
|
||||
from sqlalchemy import Column, ForeignKey, Integer, MetaData, String, and_
|
||||
from sqlalchemy.ext.declarative import declarative_base, declared_attr
|
||||
from sqlalchemy.orm import backref, relationship
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from openlp.core.lib.db import Manager, init_db, init_url
|
||||
from openlp.core.lib.projector.constants import PJLINK_DEFAULT_CODES
|
||||
|
||||
metadata = MetaData()
|
||||
Base = declarative_base(metadata)
|
||||
Base = declarative_base(MetaData())
|
||||
|
||||
|
||||
class CommonBase(object):
|
||||
|
@ -54,8 +53,8 @@ class CommonBase(object):
|
|||
Base class to automate table name and ID column.
|
||||
"""
|
||||
@declared_attr
|
||||
def __tablename__(cls):
|
||||
return cls.__name__.lower()
|
||||
def __tablename__(self):
|
||||
return self.__name__.lower()
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
|
||||
|
@ -131,7 +130,7 @@ class Source(CommonBase, Base):
|
|||
"""
|
||||
Return basic representation of Source table entry.
|
||||
"""
|
||||
return '<Source(pjlink_name="{name}", pjlink_code="{code}", text="{Text}")>'.format(name=self.pjlink_name,
|
||||
return '<Source(pjlink_name="{name}", pjlink_code="{code}", text="{text}")>'.format(name=self.pjlink_name,
|
||||
code=self.pjlink_code,
|
||||
text=self.text)
|
||||
model_id = Column(Integer, ForeignKey('model.id'))
|
||||
|
@ -257,7 +256,7 @@ class ProjectorDB(Manager):
|
|||
projector = self.get_object_filtered(Projector, Projector.id == dbid)
|
||||
if projector is None:
|
||||
# Not found
|
||||
log.warn('get_projector_by_id() did not find {data}'.format(data=id))
|
||||
log.warning('get_projector_by_id() did not find {data}'.format(data=id))
|
||||
return None
|
||||
log.debug('get_projectorby_id() returning 1 entry for "{entry}" id="{data}"'.format(entry=dbid,
|
||||
data=projector.id))
|
||||
|
@ -290,7 +289,7 @@ class ProjectorDB(Manager):
|
|||
projector = self.get_object_filtered(Projector, Projector.ip == ip)
|
||||
if projector is None:
|
||||
# Not found
|
||||
log.warn('get_projector_by_ip() did not find {ip}'.format(ip=ip))
|
||||
log.warning('get_projector_by_ip() did not find {ip}'.format(ip=ip))
|
||||
return None
|
||||
log.debug('get_projectorby_ip() returning 1 entry for "{ip}" id="{data}"'.format(ip=ip,
|
||||
data=projector.id))
|
||||
|
@ -307,7 +306,7 @@ class ProjectorDB(Manager):
|
|||
projector = self.get_object_filtered(Projector, Projector.name == name)
|
||||
if projector is None:
|
||||
# Not found
|
||||
log.warn('get_projector_by_name() did not find "{name}"'.format(name=name))
|
||||
log.warning('get_projector_by_name() did not find "{name}"'.format(name=name))
|
||||
return None
|
||||
log.debug('get_projector_by_name() returning one entry for "{name}" id="{data}"'.format(name=name,
|
||||
data=projector.id))
|
||||
|
@ -324,7 +323,7 @@ class ProjectorDB(Manager):
|
|||
"""
|
||||
old_projector = self.get_object_filtered(Projector, Projector.ip == projector.ip)
|
||||
if old_projector is not None:
|
||||
log.warn('add_new() skipping entry ip="{ip}" (Already saved)'.format(ip=old_projector.ip))
|
||||
log.warning('add_new() skipping entry ip="{ip}" (Already saved)'.format(ip=old_projector.ip))
|
||||
return False
|
||||
log.debug('add_new() saving new entry')
|
||||
log.debug('ip="{ip}", name="{name}", location="{location}"'.format(ip=projector.ip,
|
||||
|
@ -408,10 +407,10 @@ class ProjectorDB(Manager):
|
|||
:param source: ProjectorSource id
|
||||
:returns: ProjetorSource instance or None
|
||||
"""
|
||||
source_entry = self.get_object_filtered(ProjetorSource, ProjectorSource.id == source)
|
||||
source_entry = self.get_object_filtered(ProjectorSource, ProjectorSource.id == source)
|
||||
if source_entry is None:
|
||||
# Not found
|
||||
log.warn('get_source_by_id() did not find "{source}"'.format(source=source))
|
||||
log.warning('get_source_by_id() did not find "{source}"'.format(source=source))
|
||||
return None
|
||||
log.debug('get_source_by_id() returning one entry for "{source}""'.format(source=source))
|
||||
return source_entry
|
||||
|
@ -430,8 +429,8 @@ class ProjectorDB(Manager):
|
|||
|
||||
if source_entry is None:
|
||||
# Not found
|
||||
log.warn('get_source_by_id() not found')
|
||||
log.warn('code="{code}" projector_id="{data}"'.format(code=code, data=projector_id))
|
||||
log.warning('get_source_by_id() not found')
|
||||
log.warning('code="{code}" projector_id="{data}"'.format(code=code, data=projector_id))
|
||||
return None
|
||||
log.debug('get_source_by_id() returning one entry')
|
||||
log.debug('code="{code}" projector_id="{data}"'.format(code=code, data=projector_id))
|
||||
|
|
|
@ -58,7 +58,7 @@ SocketSTate = QAbstractSocket.SocketState
|
|||
|
||||
PJLINK_PREFIX = '%'
|
||||
PJLINK_CLASS = '1'
|
||||
PJLINK_HEADER = '%s%s' % (PJLINK_PREFIX, PJLINK_CLASS)
|
||||
PJLINK_HEADER = '{prefix}{linkclass}'.format(prefix=PJLINK_PREFIX, linkclass=PJLINK_CLASS)
|
||||
PJLINK_SUFFIX = CR
|
||||
|
||||
|
||||
|
@ -160,8 +160,10 @@ class PJLink1(QTcpSocket):
|
|||
self.source = None
|
||||
self.other_info = None
|
||||
if hasattr(self, 'timer'):
|
||||
log.debug('({ip}): Calling timer.stop()'.format(ip=self.ip))
|
||||
self.timer.stop()
|
||||
if hasattr(self, 'socket_timer'):
|
||||
log.debug('({ip}): Calling socket_timer.stop()'.format(ip=self.ip))
|
||||
self.socket_timer.stop()
|
||||
self.send_queue = []
|
||||
self.send_busy = False
|
||||
|
@ -295,6 +297,8 @@ class PJLink1(QTcpSocket):
|
|||
Processes the initial connection and authentication (if needed).
|
||||
Starts poll timer if connection is established.
|
||||
|
||||
NOTE: Qt md5 hash function doesn't work with projector authentication. Use the python md5 hash function.
|
||||
|
||||
:param data: Optional data if called from another routine
|
||||
"""
|
||||
log.debug('({ip}) check_login(data="{data}")'.format(ip=self.ip, data=data))
|
||||
|
@ -308,10 +312,10 @@ class PJLink1(QTcpSocket):
|
|||
read = self.readLine(self.maxSize)
|
||||
dontcare = self.readLine(self.maxSize) # Clean out the trailing \r\n
|
||||
if read is None:
|
||||
log.warn('({ip}) read is None - socket error?'.format(ip=self.ip))
|
||||
log.warning('({ip}) read is None - socket error?'.format(ip=self.ip))
|
||||
return
|
||||
elif len(read) < 8:
|
||||
log.warn('({ip}) Not enough data read)'.format(ip=self.ip))
|
||||
log.warning('({ip}) Not enough data read)'.format(ip=self.ip))
|
||||
return
|
||||
data = decode(read, 'ascii')
|
||||
# Possibility of extraneous data on input when reading.
|
||||
|
@ -342,23 +346,33 @@ class PJLink1(QTcpSocket):
|
|||
return
|
||||
elif data_check[1] == '0' and self.pin is not None:
|
||||
# Pin set and no authentication needed
|
||||
log.warning('({ip}) Regular connection but PIN set'.format(ip=self.name))
|
||||
self.disconnect_from_host()
|
||||
self.change_status(E_AUTHENTICATION)
|
||||
log.debug('({ip}) emitting projectorNoAuthentication() signal'.format(ip=self.name))
|
||||
log.debug('({ip}) Emitting projectorNoAuthentication() signal'.format(ip=self.name))
|
||||
self.projectorNoAuthentication.emit(self.name)
|
||||
return
|
||||
elif data_check[1] == '1':
|
||||
# Authenticated login with salt
|
||||
log.debug('({ip}) Setting hash with salt="{data}"'.format(ip=self.ip, data=data_check[2]))
|
||||
log.debug('({ip}) pin="{data}"'.format(ip=self.ip, data=self.pin))
|
||||
salt = qmd5_hash(salt=data_check[2].encode('ascii'), data=self.pin.encode('ascii'))
|
||||
if self.pin is None:
|
||||
log.warning('({ip}) Authenticated connection but no pin set'.format(ip=self.name))
|
||||
self.disconnect_from_host()
|
||||
self.change_status(E_AUTHENTICATION)
|
||||
log.debug('({ip}) Emitting projectorAuthentication() signal'.format(ip=self.name))
|
||||
self.projectorAuthentication.emit(self.name)
|
||||
return
|
||||
else:
|
||||
log.debug('({ip}) Setting hash with salt="{data}"'.format(ip=self.ip, data=data_check[2]))
|
||||
log.debug('({ip}) pin="{data}"'.format(ip=self.ip, data=self.pin))
|
||||
data_hash = str(qmd5_hash(salt=data_check[2].encode('utf-8'), data=self.pin.encode('utf-8')),
|
||||
encoding='ascii')
|
||||
else:
|
||||
salt = None
|
||||
# We're connected at this point, so go ahead and do regular I/O
|
||||
data_hash = None
|
||||
# We're connected at this point, so go ahead and setup regular I/O
|
||||
self.readyRead.connect(self.get_data)
|
||||
self.projectorReceivedData.connect(self._send_command)
|
||||
# Initial data we should know about
|
||||
self.send_command(cmd='CLSS', salt=salt)
|
||||
self.send_command(cmd='CLSS', salt=data_hash)
|
||||
self.waitForReadyRead()
|
||||
if (not self.no_poll) and (self.state() == self.ConnectedState):
|
||||
log.debug('({ip}) Starting timer'.format(ip=self.ip))
|
||||
|
@ -400,7 +414,7 @@ class PJLink1(QTcpSocket):
|
|||
self.projectorReceivedData.emit()
|
||||
return
|
||||
elif '=' not in data:
|
||||
log.warn('({ip}) get_data(): Invalid packet received'.format(ip=self.ip))
|
||||
log.warning('({ip}) get_data(): Invalid packet received'.format(ip=self.ip))
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
return
|
||||
|
@ -408,15 +422,15 @@ class PJLink1(QTcpSocket):
|
|||
try:
|
||||
(prefix, class_, cmd, data) = (data_split[0][0], data_split[0][1], data_split[0][2:], data_split[1])
|
||||
except ValueError as e:
|
||||
log.warn('({ip}) get_data(): Invalid packet - expected header + command + data'.format(ip=self.ip))
|
||||
log.warn('({ip}) get_data(): Received data: "{data}"'.format(ip=self.ip, data=data_in.strip()))
|
||||
log.warning('({ip}) get_data(): Invalid packet - expected header + command + data'.format(ip=self.ip))
|
||||
log.warning('({ip}) get_data(): Received data: "{data}"'.format(ip=self.ip, data=data_in.strip()))
|
||||
self.change_status(E_INVALID_DATA)
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
return
|
||||
|
||||
if not (self.pjlink_class in PJLINK_VALID_CMD and cmd in PJLINK_VALID_CMD[self.pjlink_class]):
|
||||
log.warn('({ip}) get_data(): Invalid packet - unknown command "{data}"'.format(ip=self.ip, data=cmd))
|
||||
log.warning('({ip}) get_data(): Invalid packet - unknown command "{data}"'.format(ip=self.ip, data=cmd))
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
return
|
||||
|
@ -459,7 +473,7 @@ class PJLink1(QTcpSocket):
|
|||
:param queue: Option to force add to queue rather than sending directly
|
||||
"""
|
||||
if self.state() != self.ConnectedState:
|
||||
log.warn('({ip}) send_command(): Not connected - returning'.format(ip=self.ip))
|
||||
log.warning('({ip}) send_command(): Not connected - returning'.format(ip=self.ip))
|
||||
self.send_queue = []
|
||||
return
|
||||
self.projectorNetwork.emit(S_NETWORK_SENDING)
|
||||
|
@ -575,7 +589,7 @@ class PJLink1(QTcpSocket):
|
|||
if cmd in self.PJLINK1_FUNC:
|
||||
self.PJLINK1_FUNC[cmd](data)
|
||||
else:
|
||||
log.warn('({ip}) Invalid command {data}'.format(ip=self.ip, data=cmd))
|
||||
log.warning('({ip}) Invalid command {data}'.format(ip=self.ip, data=cmd))
|
||||
self.send_busy = False
|
||||
self.projectorReceivedData.emit()
|
||||
|
||||
|
@ -594,7 +608,7 @@ class PJLink1(QTcpSocket):
|
|||
fill = {'Hours': int(data_dict[0]), 'On': False if data_dict[1] == '0' else True}
|
||||
except ValueError:
|
||||
# In case of invalid entry
|
||||
log.warn('({ip}) process_lamp(): Invalid data "{data}"'.format(ip=self.ip, data=data))
|
||||
log.warning('({ip}) process_lamp(): Invalid data "{data}"'.format(ip=self.ip, data=data))
|
||||
return
|
||||
lamps.append(fill)
|
||||
data_dict.pop(0) # Remove lamp hours
|
||||
|
@ -621,7 +635,7 @@ class PJLink1(QTcpSocket):
|
|||
self.send_command('INST')
|
||||
else:
|
||||
# Log unknown status response
|
||||
log.warn('({ip}) Unknown power response: {data}'.format(ip=self.ip, data=data))
|
||||
log.warning('({ip}) Unknown power response: {data}'.format(ip=self.ip, data=data))
|
||||
return
|
||||
|
||||
def process_avmt(self, data):
|
||||
|
@ -646,7 +660,7 @@ class PJLink1(QTcpSocket):
|
|||
shutter = True
|
||||
mute = True
|
||||
else:
|
||||
log.warn('({ip}) Unknown shutter response: {data}'.format(ip=self.ip, data=data))
|
||||
log.warning('({ip}) Unknown shutter response: {data}'.format(ip=self.ip, data=data))
|
||||
update_icons = shutter != self.shutter
|
||||
update_icons = update_icons or mute != self.mute
|
||||
self.shutter = shutter
|
||||
|
@ -795,7 +809,7 @@ class PJLink1(QTcpSocket):
|
|||
Initiate connection to projector.
|
||||
"""
|
||||
if self.state() == self.ConnectedState:
|
||||
log.warn('({ip}) connect_to_host(): Already connected - returning'.format(ip=self.ip))
|
||||
log.warning('({ip}) connect_to_host(): Already connected - returning'.format(ip=self.ip))
|
||||
return
|
||||
self.change_status(S_CONNECTING)
|
||||
self.connectToHost(self.ip, self.port if type(self.port) is int else int(self.port))
|
||||
|
@ -807,9 +821,9 @@ class PJLink1(QTcpSocket):
|
|||
"""
|
||||
if abort or self.state() != self.ConnectedState:
|
||||
if abort:
|
||||
log.warn('({ip}) disconnect_from_host(): Aborting connection'.format(ip=self.ip))
|
||||
log.warning('({ip}) disconnect_from_host(): Aborting connection'.format(ip=self.ip))
|
||||
else:
|
||||
log.warn('({ip}) disconnect_from_host(): Not connected - returning'.format(ip=self.ip))
|
||||
log.warning('({ip}) disconnect_from_host(): Not connected - returning'.format(ip=self.ip))
|
||||
self.reset_information()
|
||||
self.disconnectFromHost()
|
||||
try:
|
||||
|
|
|
@ -531,7 +531,7 @@ def words_split(line):
|
|||
:param line: Line to be split
|
||||
"""
|
||||
# this parse we are to be wordy
|
||||
return re.split('\s+', line)
|
||||
return re.split(r'\s+', line)
|
||||
|
||||
|
||||
def get_start_tags(raw_text):
|
||||
|
|
|
@ -34,7 +34,7 @@ import ntpath
|
|||
from PyQt5 import QtGui
|
||||
|
||||
from openlp.core.common import RegistryProperties, Settings, translate, AppLocation, md5_hash
|
||||
from openlp.core.lib import ImageSource, build_icon, clean_tags, expand_tags, create_thumb
|
||||
from openlp.core.lib import ImageSource, build_icon, clean_tags, expand_tags
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
Provide the theme XML and handling functions for OpenLP v2 themes.
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
import json
|
||||
|
||||
|
@ -165,6 +164,7 @@ class ThemeXML(object):
|
|||
jsn = get_text_file_string(json_file)
|
||||
jsn = json.loads(jsn)
|
||||
self.expand_json(jsn)
|
||||
self.background_filename = None
|
||||
|
||||
def expand_json(self, var, prev=None):
|
||||
"""
|
||||
|
@ -474,15 +474,16 @@ class ThemeXML(object):
|
|||
if element.startswith('shadow') or element.startswith('outline'):
|
||||
master = 'font_main'
|
||||
# fix bold font
|
||||
ret_value = None
|
||||
if element == 'weight':
|
||||
element = 'bold'
|
||||
if value == 'Normal':
|
||||
value = False
|
||||
ret_value = False
|
||||
else:
|
||||
value = True
|
||||
ret_value = True
|
||||
if element == 'proportion':
|
||||
element = 'size'
|
||||
return False, master, element, value
|
||||
return False, master, element, ret_value if ret_value is not None else value
|
||||
|
||||
def _create_attr(self, master, element, value):
|
||||
"""
|
||||
|
|
|
@ -179,5 +179,4 @@ def get_web_page(url, header=None, update_openlp=False):
|
|||
return page
|
||||
|
||||
|
||||
__all__ = ['get_application_version', 'check_latest_version',
|
||||
'get_web_page']
|
||||
__all__ = ['get_web_page']
|
||||
|
|
|
@ -88,7 +88,7 @@ class UiAboutDialog(object):
|
|||
|
||||
:param about_dialog: The QDialog object to translate
|
||||
"""
|
||||
about_dialog.setWindowTitle('%s OpenLP' % UiStrings().About)
|
||||
about_dialog.setWindowTitle('{about} OpenLP'.format(about=UiStrings().About))
|
||||
self.about_text_edit.setPlainText(
|
||||
translate('OpenLP.AboutForm',
|
||||
'OpenLP <version><revision> - Open Source Lyrics Projection\n'
|
||||
|
@ -200,115 +200,115 @@ class UiAboutDialog(object):
|
|||
' bring this software to you for free because\n'
|
||||
' He has set us free.')
|
||||
self.credits_text_edit.setPlainText(
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleLead}\n'
|
||||
' {nameLead}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleDevs}\n'
|
||||
' {nameDevs}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleContrib}\n'
|
||||
' {nameContrib}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleTesters}\n'
|
||||
' {nameTesters}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titlePackagers}\n'
|
||||
' {namePackagers}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
' %s\n'
|
||||
'{titleTranslators}\n'
|
||||
' {titleAF}\n'
|
||||
' {nameAF}\n'
|
||||
' {titleCS}\n'
|
||||
' {nameCS}\n'
|
||||
' {titleDA}\n'
|
||||
' {nameDA}\n'
|
||||
' {titleDE}\n'
|
||||
' {nameDE}\n'
|
||||
' {titleEL}\n'
|
||||
' {nameEL}\n'
|
||||
' {titleGB}\n'
|
||||
' {nameGB}\n'
|
||||
' {titleENZA}\n'
|
||||
' {nameENZA}\n'
|
||||
' {titleES}\n'
|
||||
' {nameES}\n'
|
||||
' {titleET}\n'
|
||||
' {nameET}\n'
|
||||
' {titleFI}\n'
|
||||
' {nameFI}\n'
|
||||
' {titleFR}\n'
|
||||
' {nameFR}\n'
|
||||
' {titleHU}\n'
|
||||
' {nameHU}\n'
|
||||
' {titleIND}\n'
|
||||
' {nameIND}\n'
|
||||
' {titleJA}\n'
|
||||
' {nameJA}\n'
|
||||
' {titleNB}\n'
|
||||
' {nameNB}\n'
|
||||
' {titleNL}\n'
|
||||
' {nameNL}\n'
|
||||
' {titlePL}\n'
|
||||
' {namePL}\n'
|
||||
' {titlePTBR}\n'
|
||||
' {namePTBR}\n'
|
||||
' {titleRU}\n'
|
||||
' {nameRU}\n'
|
||||
' {titleSV}\n'
|
||||
' {nameSV}\n'
|
||||
' {titleTALK}\n'
|
||||
' {nameTALK}\n'
|
||||
' {titleZHCN}\n'
|
||||
' {nameZHCN}\n'
|
||||
'\n'
|
||||
'%s\n'
|
||||
' %s\n'
|
||||
'{titleDOCS}\n'
|
||||
' {nameDOCS}\n'
|
||||
'\n'
|
||||
'%s\n%s' %
|
||||
(project_lead, lead,
|
||||
devs, '\n '.join(developers),
|
||||
cons, '\n '.join(contributors),
|
||||
tests, '\n '.join(testers),
|
||||
packs, '\n '.join(packagers),
|
||||
laters,
|
||||
af, '\n '.join(translators['af']),
|
||||
cs, '\n '.join(translators['cs']),
|
||||
da, '\n '.join(translators['da']),
|
||||
de, '\n '.join(translators['de']),
|
||||
el, '\n '.join(translators['el']),
|
||||
gb, '\n '.join(translators['en_GB']),
|
||||
enza, '\n '.join(translators['en_ZA']),
|
||||
es, '\n '.join(translators['es']),
|
||||
et, '\n '.join(translators['et']),
|
||||
fi, '\n '.join(translators['fi']),
|
||||
fr, '\n '.join(translators['fr']),
|
||||
hu, '\n '.join(translators['hu']),
|
||||
ind, '\n '.join(translators['id']),
|
||||
ja, '\n '.join(translators['ja']),
|
||||
nb, '\n '.join(translators['nb']),
|
||||
nl, '\n '.join(translators['nl']),
|
||||
pl, '\n '.join(translators['pl']),
|
||||
ptbr, '\n '.join(translators['pt_BR']),
|
||||
ru, '\n '.join(translators['ru']),
|
||||
sv, '\n '.join(translators['sv']),
|
||||
talk, '\n '.join(translators['ta_LK']),
|
||||
zhcn, '\n '.join(translators['zh_CN']),
|
||||
documentation, '\n '.join(documentors),
|
||||
built_with, final_credit))
|
||||
'{build}\n{final}'.format(titleLead=project_lead, nameLead=lead,
|
||||
titleDevs=devs, nameDevs='\n '.join(developers),
|
||||
titleContrib=cons, nameContrib='\n '.join(contributors),
|
||||
titleTesters=tests, nameTesters='\n '.join(testers),
|
||||
titlePackagers=packs, namePackagers='\n '.join(packagers),
|
||||
titleTranslators=laters,
|
||||
titleAF=af, nameAF='\n '.join(translators['af']),
|
||||
titleCS=cs, nameCS='\n '.join(translators['cs']),
|
||||
titleDA=da, nameDA='\n '.join(translators['da']),
|
||||
titleDE=de, nameDE='\n '.join(translators['de']),
|
||||
titleEL=el, nameEL='\n '.join(translators['el']),
|
||||
titleGB=gb, nameGB='\n '.join(translators['en_GB']),
|
||||
titleENZA=enza, nameENZA='\n '.join(translators['en_ZA']),
|
||||
titleES=es, nameES='\n '.join(translators['es']),
|
||||
titleET=et, nameET='\n '.join(translators['et']),
|
||||
titleFI=fi, nameFI='\n '.join(translators['fi']),
|
||||
titleFR=fr, nameFR='\n '.join(translators['fr']),
|
||||
titleHU=hu, nameHU='\n '.join(translators['hu']),
|
||||
titleIND=ind, nameIND='\n '.join(translators['id']),
|
||||
titleJA=ja, nameJA='\n '.join(translators['ja']),
|
||||
titleNB=nb, nameNB='\n '.join(translators['nb']),
|
||||
titleNL=nl, nameNL='\n '.join(translators['nl']),
|
||||
titlePL=pl, namePL='\n '.join(translators['pl']),
|
||||
titlePTBR=ptbr, namePTBR='\n '.join(translators['pt_BR']),
|
||||
titleRU=ru, nameRU='\n '.join(translators['ru']),
|
||||
titleSV=sv, nameSV='\n '.join(translators['sv']),
|
||||
titleTALK=talk, nameTALK='\n '.join(translators['ta_LK']),
|
||||
titleZHCN=zhcn, nameZHCN='\n '.join(translators['zh_CN']),
|
||||
titleDOCS=documentation, nameDOCS='\n '.join(documentors),
|
||||
build=built_with,
|
||||
final=final_credit))
|
||||
self.about_notebook.setTabText(self.about_notebook.indexOf(self.credits_tab),
|
||||
translate('OpenLP.AboutForm', 'Credits'))
|
||||
cr_others = ('Tim Bentley, Gerald Britton, Jonathan Corwin, Samuel Findlay, '
|
||||
'Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, '
|
||||
'Armin K\xf6hler, Erik Lundin, Edwin Lunando, Joshua Miller, '
|
||||
'Brian T. Meyer, Stevan Pettit, Andreas Preikschat, '
|
||||
'Mattias P\xf5ldaru, Christian Richter, Philip Ridout, '
|
||||
'Ken Roberts, Simon Scudder, Jeffrey Smith, Maikel Stuivenberg, '
|
||||
'Martin Thompson, Jon Tibble, Dave Warnock, Frode Woldsund, '
|
||||
'Martin Zibricky, Patrick Zimmermann')
|
||||
copyright_note = translate('OpenLP.AboutForm',
|
||||
'Copyright \xa9 2004-2016 %s\n'
|
||||
'Portions copyright \xa9 2004-2016 %s') % \
|
||||
('Raoul Snyman',
|
||||
'Tim Bentley, Gerald Britton, Jonathan Corwin, Samuel Findlay, '
|
||||
'Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, '
|
||||
'Armin K\xf6hler, Erik Lundin, Edwin Lunando, Joshua Miller, '
|
||||
'Brian T. Meyer, Stevan Pettit, Andreas Preikschat, '
|
||||
'Mattias P\xf5ldaru, Christian Richter, '
|
||||
'Philip Ridout, Simon Scudder, Jeffrey Smith, Maikel Stuivenberg, '
|
||||
'Martin Thompson, Jon Tibble, Dave Warnock, Frode Woldsund, '
|
||||
'Martin Zibricky, Patrick Zimmermann')
|
||||
'Copyright \xa9 2004-2016 {cr}\n\n'
|
||||
'Portions copyright \xa9 2004-2016 {others}').format(cr='Raoul Snyman',
|
||||
others=cr_others)
|
||||
licence = translate('OpenLP.AboutForm',
|
||||
'This program is free software; you can redistribute it and/or '
|
||||
'modify it under the terms of the GNU General Public License as '
|
||||
|
@ -690,7 +690,11 @@ class UiAboutDialog(object):
|
|||
'linking proprietary applications with the library. If this is '
|
||||
'what you want to do, use the GNU Lesser General Public License '
|
||||
'instead of this License.')
|
||||
self.license_text_edit.setPlainText('%s\n\n%s\n\n%s\n\n\n%s' % (copyright_note, licence, disclaimer, gpl_text))
|
||||
self.license_text_edit.setPlainText('{crnote}\n\n{license}\n\n{disclaimer}'
|
||||
'\n\n\n{gpl}'.format(crnote=copyright_note,
|
||||
license=licence,
|
||||
disclaimer=disclaimer,
|
||||
gpl=gpl_text))
|
||||
self.about_notebook.setTabText(self.about_notebook.indexOf(self.license_tab),
|
||||
translate('OpenLP.AboutForm', 'License'))
|
||||
self.volunteer_button.setText(translate('OpenLP.AboutForm', 'Volunteer'))
|
||||
|
|
|
@ -52,7 +52,7 @@ class AboutForm(QtWidgets.QDialog, UiAboutDialog):
|
|||
about_text = self.about_text_edit.toPlainText()
|
||||
about_text = about_text.replace('<version>', application_version['version'])
|
||||
if application_version['build']:
|
||||
build_text = translate('OpenLP.AboutForm', ' build %s') % application_version['build']
|
||||
build_text = translate('OpenLP.AboutForm', ' build {version}').format(version=application_version['build'])
|
||||
else:
|
||||
build_text = ''
|
||||
about_text = about_text.replace('<revision>', build_text)
|
||||
|
|
|
@ -87,11 +87,14 @@ class AdvancedTab(SettingsTab):
|
|||
self.ui_layout.addRow(self.expand_service_item_check_box)
|
||||
self.slide_max_height_label = QtWidgets.QLabel(self.ui_group_box)
|
||||
self.slide_max_height_label.setObjectName('slide_max_height_label')
|
||||
self.slide_max_height_spin_box = QtWidgets.QSpinBox(self.ui_group_box)
|
||||
self.slide_max_height_spin_box.setObjectName('slide_max_height_spin_box')
|
||||
self.slide_max_height_spin_box.setRange(0, 1000)
|
||||
self.slide_max_height_spin_box.setSingleStep(20)
|
||||
self.ui_layout.addRow(self.slide_max_height_label, self.slide_max_height_spin_box)
|
||||
self.slide_max_height_combo_box = QtWidgets.QComboBox(self.ui_group_box)
|
||||
self.slide_max_height_combo_box.addItem('', userData=0)
|
||||
self.slide_max_height_combo_box.addItem('', userData=-4)
|
||||
# Generate numeric values for combo box dynamically
|
||||
for px in range(60, 801, 5):
|
||||
self.slide_max_height_combo_box.addItem(str(px) + 'px', userData=px)
|
||||
self.slide_max_height_combo_box.setObjectName('slide_max_height_combo_box')
|
||||
self.ui_layout.addRow(self.slide_max_height_label, self.slide_max_height_combo_box)
|
||||
self.autoscroll_label = QtWidgets.QLabel(self.ui_group_box)
|
||||
self.autoscroll_label.setObjectName('autoscroll_label')
|
||||
self.autoscroll_combo_box = QtWidgets.QComboBox(self.ui_group_box)
|
||||
|
@ -265,7 +268,8 @@ class AdvancedTab(SettingsTab):
|
|||
'Expand new Service items on creation'))
|
||||
self.slide_max_height_label.setText(translate('OpenLP.AdvancedTab',
|
||||
'Max height for non-text slides\nin slide controller:'))
|
||||
self.slide_max_height_spin_box.setSpecialValueText(translate('OpenLP.AdvancedTab', 'Disabled'))
|
||||
self.slide_max_height_combo_box.setItemText(0, translate('OpenLP.AdvancedTab', 'Disabled'))
|
||||
self.slide_max_height_combo_box.setItemText(1, translate('OpenLP.AdvancedTab', 'Automatic'))
|
||||
self.autoscroll_label.setText(translate('OpenLP.AdvancedTab',
|
||||
'When changing slides:'))
|
||||
self.autoscroll_combo_box.setItemText(0, translate('OpenLP.AdvancedTab', 'Do not auto-scroll'))
|
||||
|
@ -308,8 +312,8 @@ class AdvancedTab(SettingsTab):
|
|||
self.service_name_label.setText(translate('OpenLP.AdvancedTab', 'Name:'))
|
||||
self.service_name_edit.setToolTip(translate('OpenLP.AdvancedTab', 'Consult the OpenLP manual for usage.'))
|
||||
self.service_name_revert_button.setToolTip(
|
||||
translate('OpenLP.AdvancedTab', 'Revert to the default service name "%s".') %
|
||||
UiStrings().DefaultServiceName)
|
||||
translate('OpenLP.AdvancedTab',
|
||||
'Revert to the default service name "{name}".').format(name=UiStrings().DefaultServiceName))
|
||||
self.service_name_example_label.setText(translate('OpenLP.AdvancedTab', 'Example:'))
|
||||
self.hide_mouse_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Mouse Cursor'))
|
||||
self.hide_mouse_check_box.setText(translate('OpenLP.AdvancedTab', 'Hide mouse cursor when over display window'))
|
||||
|
@ -355,10 +359,13 @@ class AdvancedTab(SettingsTab):
|
|||
self.single_click_preview_check_box.setChecked(settings.value('single click preview'))
|
||||
self.single_click_service_preview_check_box.setChecked(settings.value('single click service preview'))
|
||||
self.expand_service_item_check_box.setChecked(settings.value('expand service item'))
|
||||
self.slide_max_height_spin_box.setValue(settings.value('slide max height'))
|
||||
slide_max_height_value = settings.value('slide max height')
|
||||
for i in range(0, self.slide_max_height_combo_box.count()):
|
||||
if self.slide_max_height_combo_box.itemData(i) == slide_max_height_value:
|
||||
self.slide_max_height_combo_box.setCurrentIndex(i)
|
||||
autoscroll_value = settings.value('autoscrolling')
|
||||
for i in range(0, len(self.autoscroll_map)):
|
||||
if self.autoscroll_map[i] == autoscroll_value:
|
||||
if self.autoscroll_map[i] == autoscroll_value and i < self.autoscroll_combo_box.count():
|
||||
self.autoscroll_combo_box.setCurrentIndex(i)
|
||||
self.enable_auto_close_check_box.setChecked(settings.value('enable exit confirmation'))
|
||||
self.hide_mouse_check_box.setChecked(settings.value('hide mouse'))
|
||||
|
@ -391,16 +398,16 @@ class AdvancedTab(SettingsTab):
|
|||
# Since data location can be changed, make sure the path is present.
|
||||
self.current_data_path = AppLocation.get_data_path()
|
||||
if not os.path.exists(self.current_data_path):
|
||||
log.error('Data path not found %s' % self.current_data_path)
|
||||
log.error('Data path not found {path}'.format(path=self.current_data_path))
|
||||
answer = QtWidgets.QMessageBox.critical(
|
||||
self, translate('OpenLP.AdvancedTab', 'Data Directory Error'),
|
||||
translate('OpenLP.AdvancedTab', 'OpenLP data directory was not found\n\n%s\n\n'
|
||||
translate('OpenLP.AdvancedTab', 'OpenLP data directory was not found\n\n{path}\n\n'
|
||||
'This data directory was previously changed from the OpenLP '
|
||||
'default location. If the new location was on removable '
|
||||
'media, that media needs to be made available.\n\n'
|
||||
'Click "No" to stop loading OpenLP. allowing you to fix the the problem.\n\n'
|
||||
'Click "Yes" to reset the data directory to the default '
|
||||
'location.').replace('%s', self.current_data_path),
|
||||
'location.').format(path=self.current_data_path),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
if answer == QtWidgets.QMessageBox.No:
|
||||
|
@ -410,7 +417,7 @@ class AdvancedTab(SettingsTab):
|
|||
# Set data location to default.
|
||||
settings.remove('advanced/data path')
|
||||
self.current_data_path = AppLocation.get_data_path()
|
||||
log.warning('User requested data path set to default %s' % self.current_data_path)
|
||||
log.warning('User requested data path set to default {path}'.format(path=self.current_data_path))
|
||||
self.data_directory_label.setText(os.path.abspath(self.current_data_path))
|
||||
# Don't allow data directory move if running portable.
|
||||
if settings.value('advanced/is portable'):
|
||||
|
@ -439,7 +446,9 @@ class AdvancedTab(SettingsTab):
|
|||
settings.setValue('single click preview', self.single_click_preview_check_box.isChecked())
|
||||
settings.setValue('single click service preview', self.single_click_service_preview_check_box.isChecked())
|
||||
settings.setValue('expand service item', self.expand_service_item_check_box.isChecked())
|
||||
settings.setValue('slide max height', self.slide_max_height_spin_box.value())
|
||||
slide_max_height_index = self.slide_max_height_combo_box.currentIndex()
|
||||
slide_max_height_value = self.slide_max_height_combo_box.itemData(slide_max_height_index)
|
||||
settings.setValue('slide max height', slide_max_height_value)
|
||||
settings.setValue('autoscrolling', self.autoscroll_map[self.autoscroll_combo_box.currentIndex()])
|
||||
settings.setValue('enable exit confirmation', self.enable_auto_close_check_box.isChecked())
|
||||
settings.setValue('hide mouse', self.hide_mouse_check_box.isChecked())
|
||||
|
@ -542,9 +551,9 @@ class AdvancedTab(SettingsTab):
|
|||
# Make sure they want to change the data.
|
||||
answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Confirm Data Directory Change'),
|
||||
translate('OpenLP.AdvancedTab', 'Are you sure you want to change the '
|
||||
'location of the OpenLP data directory to:\n\n%s\n\nThe data '
|
||||
'directory will be changed when OpenLP is closed.').
|
||||
replace('%s', new_data_path),
|
||||
'location of the OpenLP data directory to:\n\n{path}'
|
||||
'\n\nThe data directory will be changed when OpenLP is '
|
||||
'closed.').format(path=new_data_path),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
|
@ -608,10 +617,10 @@ class AdvancedTab(SettingsTab):
|
|||
answer = QtWidgets.QMessageBox.warning(self,
|
||||
translate('OpenLP.AdvancedTab', 'Overwrite Existing Data'),
|
||||
translate('OpenLP.AdvancedTab',
|
||||
'WARNING: \n\nThe location you have selected \n\n%s\n\n'
|
||||
'appears to contain OpenLP data files. Do you wish to '
|
||||
'replace these files with the current data files?').
|
||||
replace('%s', os.path.abspath(data_path,)),
|
||||
'WARNING: \n\nThe location you have selected \n\n{path}'
|
||||
'\n\nappears to contain OpenLP data files. Do you wish to '
|
||||
'replace these files with the current data '
|
||||
'files?').format(path=os.path.abspath(data_path,)),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
|
|
|
@ -32,8 +32,6 @@ import sqlalchemy
|
|||
from PyQt5 import Qt, QtCore, QtGui, QtWebKit, QtWidgets
|
||||
from lxml import etree
|
||||
|
||||
from openlp.core.common import RegistryProperties, is_linux
|
||||
|
||||
try:
|
||||
import migrate
|
||||
MIGRATE_VERSION = getattr(migrate, '__version__', '< 0.7')
|
||||
|
@ -74,6 +72,7 @@ except ImportError:
|
|||
|
||||
from openlp.core.common import Settings, UiStrings, translate
|
||||
from openlp.core.common.versionchecker import get_application_version
|
||||
from openlp.core.common import RegistryProperties, is_linux
|
||||
|
||||
from .exceptiondialog import Ui_ExceptionDialog
|
||||
|
||||
|
@ -91,6 +90,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
|||
super(ExceptionForm, self).__init__(None, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
|
||||
self.setupUi(self)
|
||||
self.settings_section = 'crashreport'
|
||||
# TODO: Need to see how to format strings when string with tags is actually a variable
|
||||
self.report_text = '**OpenLP Bug Report**\n' \
|
||||
'Version: %s\n\n' \
|
||||
'--- Details of the Exception. ---\n\n%s\n\n ' \
|
||||
|
@ -114,21 +114,17 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
|||
openlp_version = get_application_version()
|
||||
description = self.description_text_edit.toPlainText()
|
||||
traceback = self.exception_text_edit.toPlainText()
|
||||
system = translate('OpenLP.ExceptionForm', 'Platform: %s\n') % platform.platform()
|
||||
libraries = 'Python: %s\n' % platform.python_version() + \
|
||||
'Qt5: %s\n' % Qt.qVersion() + \
|
||||
'PyQt5: %s\n' % Qt.PYQT_VERSION_STR + \
|
||||
'QtWebkit: %s\n' % WEBKIT_VERSION + \
|
||||
'SQLAlchemy: %s\n' % sqlalchemy.__version__ + \
|
||||
'SQLAlchemy Migrate: %s\n' % MIGRATE_VERSION + \
|
||||
'BeautifulSoup: %s\n' % bs4.__version__ + \
|
||||
'lxml: %s\n' % etree.__version__ + \
|
||||
'Chardet: %s\n' % CHARDET_VERSION + \
|
||||
'PyEnchant: %s\n' % ENCHANT_VERSION + \
|
||||
'Mako: %s\n' % MAKO_VERSION + \
|
||||
'pyICU: %s\n' % ICU_VERSION + \
|
||||
'pyUNO bridge: %s\n' % self._pyuno_import() + \
|
||||
'VLC: %s\n' % VLC_VERSION
|
||||
system = translate('OpenLP.ExceptionForm', 'Platform: {platform}\n').format(platform=platform.platform())
|
||||
libraries = ('Python: {python}\nQt5: {qt5}\nPyQt5: {pyqt5}\nQtWebkit: {qtwebkit}\nSQLAlchemy: {sqalchemy}\n'
|
||||
'SQLAlchemy Migrate: {migrate}\nBeautifulSoup: {soup}\nlxml: {etree}\nChardet: {chardet}\n'
|
||||
'PyEnchant: {enchant}\nMako: {mako}\npyICU: {icu}\npyUNO bridge: {uno}\n'
|
||||
'VLC: {vlc}\n').format(python=platform.python_version(), qt5=Qt.qVersion(),
|
||||
pyqt5=Qt.PYQT_VERSION_STR, qtwebkit=WEBKIT_VERSION,
|
||||
sqalchemy=sqlalchemy.__version__, migrate=MIGRATE_VERSION,
|
||||
soup=bs4.__version__, etree=etree.__version__, chardet=CHARDET_VERSION,
|
||||
enchant=ENCHANT_VERSION, mako=MAKO_VERSION, icu=ICU_VERSION,
|
||||
uno=self._pyuno_import(), vlc=VLC_VERSION)
|
||||
|
||||
if is_linux():
|
||||
if os.environ.get('KDE_FULL_SESSION') == 'true':
|
||||
system += 'Desktop: KDE SC\n'
|
||||
|
@ -178,9 +174,10 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
|||
source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line)
|
||||
if ':' in line:
|
||||
exception = line.split('\n')[-1].split(':')[0]
|
||||
subject = 'Bug report: %s in %s' % (exception, source)
|
||||
subject = 'Bug report: {error} in {source}'.format(error=exception, source=source)
|
||||
mail_urlquery = QtCore.QUrlQuery()
|
||||
mail_urlquery.addQueryItem('subject', subject)
|
||||
# TODO: Find out how to format() text that is in a variable
|
||||
mail_urlquery.addQueryItem('body', self.report_text % content)
|
||||
if self.file_attachment:
|
||||
mail_urlquery.addQueryItem('attach', self.file_attachment)
|
||||
|
@ -211,7 +208,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
|||
'Select Attachment'),
|
||||
Settings().value(self.settings_section +
|
||||
'/last directory'),
|
||||
'%s (*)' % UiStrings().AllFiles)
|
||||
'{text} (*)'.format(text=UiStrings().AllFiles))
|
||||
log.info('New files(s) %s', str(files))
|
||||
if files:
|
||||
self.file_attachment = str(files)
|
||||
|
|
|
@ -72,7 +72,7 @@ class ThemeScreenshotWorker(QtCore.QObject):
|
|||
if self.was_download_cancelled:
|
||||
return
|
||||
try:
|
||||
urllib.request.urlretrieve('%s%s' % (self.themes_url, self.screenshot),
|
||||
urllib.request.urlretrieve('{host}{name}'.format(host=self.themes_url, name=self.screenshot),
|
||||
os.path.join(gettempdir(), 'openlp', self.screenshot))
|
||||
# Signal that the screenshot has been downloaded
|
||||
self.screenshot_downloaded.emit(self.title, self.filename, self.sha256)
|
||||
|
@ -180,11 +180,13 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
user_agent = 'OpenLP/' + Registry().get('application').applicationVersion()
|
||||
self.application.process_events()
|
||||
try:
|
||||
web_config = get_web_page('%s%s' % (self.web, 'download.cfg'), header=('User-Agent', user_agent))
|
||||
web_config = get_web_page('{host}{name}'.format(host=self.web, name='download.cfg'),
|
||||
header=('User-Agent', user_agent))
|
||||
except (urllib.error.URLError, ConnectionError) as err:
|
||||
msg = QtWidgets.QMessageBox()
|
||||
title = translate('OpenLP.FirstTimeWizard', 'Network Error')
|
||||
msg.setText('{} {}'.format(title, err.code if hasattr(err, 'code') else ''))
|
||||
msg.setText('{title} {error}'.format(title=title,
|
||||
error=err.code if hasattr(err, 'code') else ''))
|
||||
msg.setInformativeText(translate('OpenLP.FirstTimeWizard',
|
||||
'There was a network error attempting to '
|
||||
'connect to retrieve initial configuration information'))
|
||||
|
@ -205,6 +207,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
trace_error_handler(log)
|
||||
self.update_screen_list_combo()
|
||||
self.application.process_events()
|
||||
# TODO: Figure out how to use a variable with format()
|
||||
self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading %s...')
|
||||
if self.has_run_wizard:
|
||||
self.songs_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songs').is_active())
|
||||
|
@ -223,9 +226,9 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
songs = songs.split(',')
|
||||
for song in songs:
|
||||
self.application.process_events()
|
||||
title = self.config.get('songs_%s' % song, 'title')
|
||||
filename = self.config.get('songs_%s' % song, 'filename')
|
||||
sha256 = self.config.get('songs_%s' % song, 'sha256', fallback='')
|
||||
title = self.config.get('songs_{song}'.format(song=song), 'title')
|
||||
filename = self.config.get('songs_{song}'.format(song=song), 'filename')
|
||||
sha256 = self.config.get('songs_{song}'.format(song=song), 'sha256', fallback='')
|
||||
item = QtWidgets.QListWidgetItem(title, self.songs_list_widget)
|
||||
item.setData(QtCore.Qt.UserRole, (filename, sha256))
|
||||
item.setCheckState(QtCore.Qt.Unchecked)
|
||||
|
@ -234,15 +237,15 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
bible_languages = bible_languages.split(',')
|
||||
for lang in bible_languages:
|
||||
self.application.process_events()
|
||||
language = self.config.get('bibles_%s' % lang, 'title')
|
||||
language = self.config.get('bibles_{lang}'.format(lang=lang), 'title')
|
||||
lang_item = QtWidgets.QTreeWidgetItem(self.bibles_tree_widget, [language])
|
||||
bibles = self.config.get('bibles_%s' % lang, 'translations')
|
||||
bibles = self.config.get('bibles_{lang}'.format(lang=lang), 'translations')
|
||||
bibles = bibles.split(',')
|
||||
for bible in bibles:
|
||||
self.application.process_events()
|
||||
title = self.config.get('bible_%s' % bible, 'title')
|
||||
filename = self.config.get('bible_%s' % bible, 'filename')
|
||||
sha256 = self.config.get('bible_%s' % bible, 'sha256', fallback='')
|
||||
title = self.config.get('bible_{bible}'.format(bible=bible), 'title')
|
||||
filename = self.config.get('bible_{bible}'.format(bible=bible), 'filename')
|
||||
sha256 = self.config.get('bible_{bible}'.format(bible=bible), 'sha256', fallback='')
|
||||
item = QtWidgets.QTreeWidgetItem(lang_item, [title])
|
||||
item.setData(0, QtCore.Qt.UserRole, (filename, sha256))
|
||||
item.setCheckState(0, QtCore.Qt.Unchecked)
|
||||
|
@ -252,10 +255,10 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
# Download the theme screenshots
|
||||
themes = self.config.get('themes', 'files').split(',')
|
||||
for theme in themes:
|
||||
title = self.config.get('theme_%s' % theme, 'title')
|
||||
filename = self.config.get('theme_%s' % theme, 'filename')
|
||||
sha256 = self.config.get('theme_%s' % theme, 'sha256', fallback='')
|
||||
screenshot = self.config.get('theme_%s' % theme, 'screenshot')
|
||||
title = self.config.get('theme_{theme}'.format(theme=theme), 'title')
|
||||
filename = self.config.get('theme_{theme}'.format(theme=theme), 'filename')
|
||||
sha256 = self.config.get('theme_{theme}'.format(theme=theme), 'sha256', fallback='')
|
||||
screenshot = self.config.get('theme_{theme}'.format(theme=theme), 'screenshot')
|
||||
worker = ThemeScreenshotWorker(self.themes_url, title, filename, sha256, screenshot)
|
||||
self.theme_screenshot_workers.append(worker)
|
||||
worker.screenshot_downloaded.connect(self.on_screenshot_downloaded)
|
||||
|
@ -421,7 +424,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
self._download_progress(block_count, block_size)
|
||||
filename.close()
|
||||
if sha256 and hasher.hexdigest() != sha256:
|
||||
log.error('sha256 sums did not match for file: {}'.format(f_path))
|
||||
log.error('sha256 sums did not match for file: {file}'.format(file=f_path))
|
||||
os.remove(f_path)
|
||||
return False
|
||||
except (urllib.error.URLError, socket.timeout) as err:
|
||||
|
@ -447,7 +450,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
themes = self.config.get('themes', 'files')
|
||||
themes = themes.split(',')
|
||||
for index, theme in enumerate(themes):
|
||||
screenshot = self.config.get('theme_%s' % theme, 'screenshot')
|
||||
screenshot = self.config.get('theme_{theme}'.format(theme=theme), 'screenshot')
|
||||
item = self.themes_list_widget.item(index)
|
||||
if item:
|
||||
item.setIcon(build_icon(os.path.join(gettempdir(), 'openlp', screenshot)))
|
||||
|
@ -507,7 +510,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
item = self.songs_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename, sha256 = item.data(QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.songs_url, filename))
|
||||
size = self._get_file_size('{path}{name}'.format(path=self.songs_url, name=filename))
|
||||
self.max_progress += size
|
||||
# Loop through the Bibles list and increase for each selected item
|
||||
iterator = QtWidgets.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
||||
|
@ -516,7 +519,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
item = iterator.value()
|
||||
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
||||
filename, sha256 = item.data(0, QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.bibles_url, filename))
|
||||
size = self._get_file_size('{path}{name}'.format(path=self.bibles_url, name=filename))
|
||||
self.max_progress += size
|
||||
iterator += 1
|
||||
# Loop through the themes list and increase for each selected item
|
||||
|
@ -525,7 +528,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
item = self.themes_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename, sha256 = item.data(QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.themes_url, filename))
|
||||
size = self._get_file_size('{path}{name}'.format(path=self.themes_url, name=filename))
|
||||
self.max_progress += size
|
||||
except urllib.error.URLError:
|
||||
trace_error_handler(log)
|
||||
|
@ -560,22 +563,26 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
if self.max_progress:
|
||||
self.progress_bar.setValue(self.progress_bar.maximum())
|
||||
if self.has_run_wizard:
|
||||
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the %s button to return to OpenLP.') %
|
||||
clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the {button} button to return to OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText(text)
|
||||
else:
|
||||
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the %s button to start OpenLP.') %
|
||||
clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
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(text)
|
||||
else:
|
||||
if self.has_run_wizard:
|
||||
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Click the %s button to return to OpenLP.') %
|
||||
clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Click the {button} button to return to OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText(text)
|
||||
else:
|
||||
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Click the %s button to start OpenLP.') %
|
||||
clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
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(text)
|
||||
self.finish_button.setVisible(True)
|
||||
self.finish_button.setEnabled(True)
|
||||
self.cancel_button.setVisible(False)
|
||||
|
@ -628,8 +635,9 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
self._increment_progress_bar(self.downloading % filename, 0)
|
||||
self.previous_size = 0
|
||||
destination = os.path.join(songs_destination, str(filename))
|
||||
if not self.url_get_file('%s%s' % (self.songs_url, filename), destination, sha256):
|
||||
missed_files.append('Song: {}'.format(filename))
|
||||
if not self.url_get_file('{path}{name}'.format(path=self.songs_url, name=filename),
|
||||
destination, sha256):
|
||||
missed_files.append('Song: {name}'.format(name=filename))
|
||||
# Download Bibles
|
||||
bibles_iterator = QtWidgets.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
||||
while bibles_iterator.value():
|
||||
|
@ -638,31 +646,34 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||
bible, sha256 = item.data(0, QtCore.Qt.UserRole)
|
||||
self._increment_progress_bar(self.downloading % bible, 0)
|
||||
self.previous_size = 0
|
||||
if not self.url_get_file('%s%s' % (self.bibles_url, bible), os.path.join(bibles_destination, bible),
|
||||
if not self.url_get_file('{path}{name}'.format(path=self.bibles_url, name=bible),
|
||||
os.path.join(bibles_destination, bible),
|
||||
sha256):
|
||||
missed_files.append('Bible: {}'.format(bible))
|
||||
missed_files.append('Bible: {name}'.format(name=bible))
|
||||
bibles_iterator += 1
|
||||
# Download themes
|
||||
for i in range(self.themes_list_widget.count()):
|
||||
item = self.themes_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
theme, sha256 = item.data(QtCore.Qt.UserRole)
|
||||
# TODO: Verify how to use format() with strings in a variable
|
||||
self._increment_progress_bar(self.downloading % theme, 0)
|
||||
self.previous_size = 0
|
||||
if not self.url_get_file('%s%s' % (self.themes_url, theme), os.path.join(themes_destination, theme),
|
||||
if not self.url_get_file('{path}{name}'.format(path=self.themes_url, name=theme),
|
||||
os.path.join(themes_destination, theme),
|
||||
sha256):
|
||||
missed_files.append('Theme: {}'.format(theme))
|
||||
missed_files.append('Theme: {name}'.format(name=theme))
|
||||
if missed_files:
|
||||
file_list = ''
|
||||
for entry in missed_files:
|
||||
file_list += '{}<br \>'.format(entry)
|
||||
file_list += '{text}<br \\>'.format(text=entry)
|
||||
msg = QtWidgets.QMessageBox()
|
||||
msg.setIcon(QtWidgets.QMessageBox.Warning)
|
||||
msg.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'Network Error'))
|
||||
msg.setText(translate('OpenLP.FirstTimeWizard', 'Unable to download some files'))
|
||||
msg.setInformativeText(translate('OpenLP.FirstTimeWizard',
|
||||
'The following files were not able to be '
|
||||
'downloaded:<br \>{}'.format(file_list)))
|
||||
'downloaded:<br \\>{text}'.format(text=file_list)))
|
||||
msg.setStandardButtons(msg.Ok)
|
||||
ans = msg.exec()
|
||||
return True
|
||||
|
|
|
@ -228,12 +228,13 @@ class UiFirstTimeWizard(object):
|
|||
:param first_time_wizard: The wizard form
|
||||
"""
|
||||
first_time_wizard.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'First Time Wizard'))
|
||||
first_time_wizard.title_label.setText('<span style="font-size:14pt; font-weight:600;">%s</span>' %
|
||||
translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard'))
|
||||
text = translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard')
|
||||
first_time_wizard.title_label.setText('<span style="font-size:14pt; font-weight:600;">{text}'
|
||||
'</span>'.format(text=text))
|
||||
button = clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.NextButton))
|
||||
first_time_wizard.information_label.setText(
|
||||
translate('OpenLP.FirstTimeWizard', 'This wizard will help you to configure OpenLP for initial use. '
|
||||
'Click the %s button below to start.') %
|
||||
clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.NextButton)))
|
||||
'Click the {button} button below to start.').format(button=button))
|
||||
self.download_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Downloading Resource Index'))
|
||||
self.download_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Please wait while the resource index is '
|
||||
'downloaded.'))
|
||||
|
@ -264,18 +265,19 @@ class UiFirstTimeWizard(object):
|
|||
self.no_internet_page.setTitle(translate('OpenLP.FirstTimeWizard', 'No Internet Connection'))
|
||||
self.no_internet_page.setSubTitle(
|
||||
translate('OpenLP.FirstTimeWizard', 'Unable to detect an Internet connection.'))
|
||||
button = clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.FinishButton))
|
||||
self.no_internet_text = translate('OpenLP.FirstTimeWizard',
|
||||
'No Internet connection was found. The First Time Wizard needs an Internet '
|
||||
'connection in order to be able to download sample songs, Bibles and themes.'
|
||||
' Click the %s button now to start OpenLP with initial settings and '
|
||||
' Click the {button} button now to start OpenLP with initial settings and '
|
||||
'no sample data.\n\nTo re-run the First Time Wizard and import this sample '
|
||||
'data at a later time, check your Internet connection and re-run this '
|
||||
'wizard by selecting "Tools/Re-run First Time Wizard" from OpenLP.') % \
|
||||
clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.FinishButton))
|
||||
'wizard by selecting "Tools/Re-run First Time Wizard" from OpenLP.'
|
||||
).format(button=button)
|
||||
button = clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.CancelButton))
|
||||
self.cancel_wizard_text = translate('OpenLP.FirstTimeWizard',
|
||||
'\n\nTo cancel the First Time Wizard completely (and not start OpenLP), '
|
||||
'click the %s button now.') % \
|
||||
clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.CancelButton))
|
||||
'click the {button} button now.').format(button=button)
|
||||
self.songs_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Songs'))
|
||||
self.songs_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download public domain songs.'))
|
||||
self.bibles_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Bibles'))
|
||||
|
|
|
@ -72,19 +72,19 @@ class FormattingTagController(object):
|
|||
"""
|
||||
for line_number, html1 in enumerate(self.protected_tags):
|
||||
if self._strip(html1['start tag']) == tag:
|
||||
return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag
|
||||
return translate('OpenLP.FormattingTagForm', 'Tag {tag} already defined.').format(tag=tag)
|
||||
if self._strip(html1['desc']) == desc:
|
||||
return translate('OpenLP.FormattingTagForm', 'Description %s already defined.') % tag
|
||||
return translate('OpenLP.FormattingTagForm', 'Description {tag} already defined.').format(tag=tag)
|
||||
for line_number, html1 in enumerate(self.custom_tags):
|
||||
if self._strip(html1['start tag']) == tag:
|
||||
return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag
|
||||
return translate('OpenLP.FormattingTagForm', 'Tag {tag} already defined.').format(tag=tag)
|
||||
if self._strip(html1['desc']) == desc:
|
||||
return translate('OpenLP.FormattingTagForm', 'Description %s already defined.') % tag
|
||||
return translate('OpenLP.FormattingTagForm', 'Description {tag} already defined.').format(tag=tag)
|
||||
tag = {
|
||||
'desc': desc,
|
||||
'start tag': '{%s}' % tag,
|
||||
'start tag': '{{{tag}}}'.format(tag=tag),
|
||||
'start html': start_html,
|
||||
'end tag': '{/%s}' % tag,
|
||||
'end tag': '{{{tag}}}'.format(tag=tag),
|
||||
'end html': end_html,
|
||||
'protected': False,
|
||||
'temporary': False
|
||||
|
@ -130,6 +130,7 @@ class FormattingTagController(object):
|
|||
elif not match.group('empty'):
|
||||
end_tags.append(tag)
|
||||
match = self.html_tag_regex.search(start_html, match.end())
|
||||
# TODO: Verify format() works with lambda
|
||||
return ''.join(map(lambda tag: '</%s>' % tag, reversed(end_tags)))
|
||||
|
||||
def start_tag_changed(self, start_html, end_html):
|
||||
|
@ -146,7 +147,8 @@ class FormattingTagController(object):
|
|||
end = self.start_html_to_end_html(start_html)
|
||||
if not end_html:
|
||||
if not end:
|
||||
return translate('OpenLP.FormattingTagForm', 'Start tag %s is not valid HTML') % start_html, None
|
||||
return translate('OpenLP.FormattingTagForm',
|
||||
'Start tag {tag} is not valid HTML').format(tag=start_html), None
|
||||
return None, end
|
||||
return None, None
|
||||
|
||||
|
@ -165,7 +167,8 @@ class FormattingTagController(object):
|
|||
if not end_html:
|
||||
return None, end
|
||||
if end and end != end_html:
|
||||
return translate('OpenLP.FormattingTagForm',
|
||||
'End tag %(end)s does not match end tag for start tag %(start)s') % \
|
||||
{'end': end, 'start': start_html}, None
|
||||
return (translate('OpenLP.FormattingTagForm',
|
||||
'End tag {end} does not match end tag for start tag {start}').format(end=end,
|
||||
start=start_html),
|
||||
None)
|
||||
return None, None
|
||||
|
|
|
@ -90,9 +90,10 @@ class FormattingTagForm(QtWidgets.QDialog, Ui_FormattingTagDialog, FormattingTag
|
|||
"""
|
||||
new_row = self.tag_table_widget.rowCount()
|
||||
self.tag_table_widget.insertRow(new_row)
|
||||
self.tag_table_widget.setItem(new_row, 0, QtWidgets.QTableWidgetItem(translate('OpenLP.FormattingTagForm',
|
||||
'New Tag %d' % new_row)))
|
||||
self.tag_table_widget.setItem(new_row, 1, QtWidgets.QTableWidgetItem('n%d' % new_row))
|
||||
self.tag_table_widget.setItem(new_row, 0,
|
||||
QtWidgets.QTableWidgetItem(translate('OpenLP.FormattingTagForm',
|
||||
'New Tag {row:d}').format(row=new_row)))
|
||||
self.tag_table_widget.setItem(new_row, 1, QtWidgets.QTableWidgetItem('n{row:d}'.format(row=new_row)))
|
||||
self.tag_table_widget.setItem(new_row, 2,
|
||||
QtWidgets.QTableWidgetItem(translate('OpenLP.FormattingTagForm', '<HTML here>')))
|
||||
self.tag_table_widget.setItem(new_row, 3, QtWidgets.QTableWidgetItem(''))
|
||||
|
|
|
@ -401,7 +401,7 @@ class GeneralTab(SettingsTab):
|
|||
"""
|
||||
Select the logo file
|
||||
"""
|
||||
file_filters = '%s;;%s (*.*)' % (get_images_filter(), UiStrings().AllFiles)
|
||||
file_filters = '{text};;{names} (*.*)'.format(text=get_images_filter(), names=UiStrings().AllFiles)
|
||||
filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(self,
|
||||
translate('OpenLP.AdvancedTab', 'Open File'), '',
|
||||
file_filters)
|
||||
|
|
|
@ -28,6 +28,7 @@ from .dockwidget import OpenLPDockWidget
|
|||
from .wizard import OpenLPWizard, WizardStrings
|
||||
from .mediadockmanager import MediaDockManager
|
||||
from .listpreviewwidget import ListPreviewWidget
|
||||
from .spelltextedit import SpellTextEdit
|
||||
|
||||
__all__ = ['ColorButton', 'ListPreviewWidget', 'ListWidgetWithDnD', 'OpenLPToolbar', 'OpenLPDockWidget',
|
||||
'OpenLPWizard', 'WizardStrings', 'MediaDockManager', 'ListPreviewWidget']
|
||||
'OpenLPWizard', 'WizardStrings', 'MediaDockManager', 'ListPreviewWidget', 'SpellTextEdit']
|
||||
|
|
|
@ -63,6 +63,7 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
|
|||
# Initialize variables.
|
||||
self.service_item = ServiceItem()
|
||||
self.screen_ratio = screen_ratio
|
||||
self.auto_row_height = 100
|
||||
# Connect signals
|
||||
self.verticalHeader().sectionResized.connect(self.row_resized)
|
||||
|
||||
|
@ -87,8 +88,14 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
|
|||
height = self.viewport().width() // self.screen_ratio
|
||||
max_img_row_height = Settings().value('advanced/slide max height')
|
||||
# Adjust for row height cap if in use.
|
||||
if isinstance(max_img_row_height, int) and max_img_row_height > 0 and height > max_img_row_height:
|
||||
height = max_img_row_height
|
||||
if isinstance(max_img_row_height, int):
|
||||
if max_img_row_height > 0 and height > max_img_row_height:
|
||||
height = max_img_row_height
|
||||
elif max_img_row_height < 0:
|
||||
# If auto setting, show that number of slides, or if the resulting slides too small, 100px.
|
||||
# E.g. If setting is -4, 4 slides will be visible, unless those slides are < 100px high.
|
||||
self.auto_row_height = max(self.viewport().height() / (-1 * max_img_row_height), 100)
|
||||
height = min(height, self.auto_row_height)
|
||||
# Apply new height to slides
|
||||
for frame_number in range(len(self.service_item.get_frames())):
|
||||
self.setRowHeight(frame_number, height)
|
||||
|
@ -99,7 +106,7 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
|
|||
"""
|
||||
# Only for non-text slides when row height cap in use
|
||||
max_img_row_height = Settings().value('advanced/slide max height')
|
||||
if self.service_item.is_text() or not isinstance(max_img_row_height, int) or max_img_row_height <= 0:
|
||||
if self.service_item.is_text() or not isinstance(max_img_row_height, int) or max_img_row_height == 0:
|
||||
return
|
||||
# Get and validate label widget containing slide & adjust max width
|
||||
try:
|
||||
|
@ -165,11 +172,15 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
|
|||
slide_height = width // self.screen_ratio
|
||||
# Setup and validate row height cap if in use.
|
||||
max_img_row_height = Settings().value('advanced/slide max height')
|
||||
if isinstance(max_img_row_height, int) and max_img_row_height > 0:
|
||||
if slide_height > max_img_row_height:
|
||||
if isinstance(max_img_row_height, int) and max_img_row_height != 0:
|
||||
if max_img_row_height > 0 and slide_height > max_img_row_height:
|
||||
# Manual Setting
|
||||
slide_height = max_img_row_height
|
||||
label.setMaximumWidth(max_img_row_height * self.screen_ratio)
|
||||
label.resize(max_img_row_height * self.screen_ratio, max_img_row_height)
|
||||
elif max_img_row_height < 0 and slide_height > self.auto_row_height:
|
||||
# Auto Setting
|
||||
slide_height = self.auto_row_height
|
||||
label.setMaximumWidth(slide_height * self.screen_ratio)
|
||||
label.resize(slide_height * self.screen_ratio, slide_height)
|
||||
# Build widget with stretch padding
|
||||
container = QtWidgets.QWidget()
|
||||
hbox = QtWidgets.QHBoxLayout()
|
||||
|
|
|
@ -142,6 +142,7 @@ class SpellTextEdit(QtWidgets.QPlainTextEdit):
|
|||
"""
|
||||
Replaces the selected text with word.
|
||||
"""
|
||||
tag = tag.replace('&', '')
|
||||
for html in FormattingTags.get_html_tags():
|
||||
if tag == html['desc']:
|
||||
cursor = self.textCursor()
|
||||
|
@ -163,7 +164,7 @@ class Highlighter(QtGui.QSyntaxHighlighter):
|
|||
"""
|
||||
Provides a text highlighter for pointing out spelling errors in text.
|
||||
"""
|
||||
WORDS = '(?iu)[\w\']+'
|
||||
WORDS = r'(?iu)[\w\']+'
|
||||
|
||||
def __init__(self, *args):
|
||||
"""
|
|
@ -33,7 +33,7 @@ import html
|
|||
import logging
|
||||
import os
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets, QtWebKit, QtWebKitWidgets, QtOpenGL, QtGui, QtMultimedia
|
||||
from PyQt5 import QtCore, QtWidgets, QtWebKit, QtWebKitWidgets, QtGui, QtMultimedia
|
||||
|
||||
from openlp.core.common import AppLocation, Registry, RegistryProperties, OpenLPMixin, Settings, translate,\
|
||||
is_macosx, is_win
|
||||
|
@ -468,9 +468,9 @@ class MainDisplay(OpenLPMixin, Display, RegistryProperties):
|
|||
self.service_item.theme_data.background_filename, ImageSource.Theme)
|
||||
if image_path:
|
||||
image_bytes = self.image_manager.get_image_bytes(image_path, ImageSource.ImagePlugin)
|
||||
html = build_html(self.service_item, self.screen, self.is_live, background, image_bytes,
|
||||
plugins=self.plugin_manager.plugins)
|
||||
self.web_view.setHtml(html)
|
||||
created_html = build_html(self.service_item, self.screen, self.is_live, background, image_bytes,
|
||||
plugins=self.plugin_manager.plugins)
|
||||
self.web_view.setHtml(created_html)
|
||||
if service_item.foot_text:
|
||||
self.footer(service_item.foot_text)
|
||||
# if was hidden keep it hidden
|
||||
|
|
|
@ -46,7 +46,6 @@ from openlp.core.ui.firsttimeform import FirstTimeForm
|
|||
from openlp.core.ui.media import MediaController
|
||||
from openlp.core.ui.printserviceform import PrintServiceForm
|
||||
from openlp.core.ui.projector.manager import ProjectorManager
|
||||
from openlp.core.ui.lib.toolbar import OpenLPToolbar
|
||||
from openlp.core.ui.lib.dockwidget import OpenLPDockWidget
|
||||
from openlp.core.ui.lib.mediadockmanager import MediaDockManager
|
||||
|
||||
|
@ -472,7 +471,8 @@ class Ui_MainWindow(object):
|
|||
self.web_site_item.setText(translate('OpenLP.MainWindow', '&Web Site'))
|
||||
for item in self.language_group.actions():
|
||||
item.setText(item.objectName())
|
||||
item.setStatusTip(translate('OpenLP.MainWindow', 'Set the interface language to %s') % item.objectName())
|
||||
item.setStatusTip(translate('OpenLP.MainWindow',
|
||||
'Set the interface language to {name}').format(name=item.objectName()))
|
||||
self.auto_language_item.setText(translate('OpenLP.MainWindow', '&Autodetect'))
|
||||
self.auto_language_item.setStatusTip(translate('OpenLP.MainWindow', 'Use the system language, if available.'))
|
||||
self.tools_add_tool_item.setText(translate('OpenLP.MainWindow', 'Add &Tool...'))
|
||||
|
@ -1337,8 +1337,10 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
|
|||
for file_id, filename in enumerate(recent_files_to_display):
|
||||
log.debug('Recent file name: {name}'.format(name=filename))
|
||||
# TODO: Verify ''.format() before committing
|
||||
action = create_action(self, '', text='&%d %s' % (file_id + 1,
|
||||
os.path.splitext(os.path.basename(str(filename)))[0]), data=filename,
|
||||
action = create_action(self, '',
|
||||
text='&{n} {name}'.format(n=file_id + 1,
|
||||
name=os.path.splitext(os.path.basename(str(filename)))[0]),
|
||||
data=filename,
|
||||
triggers=self.service_manager_contents.on_recent_service_clicked)
|
||||
self.recent_files_menu.addAction(action)
|
||||
clear_recent_files_action = create_action(self, '',
|
||||
|
|
|
@ -24,10 +24,10 @@ The :mod:`~openlp.core.ui.media` module contains classes and objects for media p
|
|||
"""
|
||||
import logging
|
||||
|
||||
from openlp.core.common import Settings
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
from openlp.core.common import Settings
|
||||
|
||||
log = logging.getLogger(__name__ + '.__init__')
|
||||
|
||||
|
||||
|
@ -134,6 +134,7 @@ def format_milliseconds(milliseconds):
|
|||
:param milliseconds: Milliseconds to format
|
||||
:return: Time string in format: hh.mm.ss,ttt
|
||||
"""
|
||||
milliseconds = int(milliseconds)
|
||||
seconds, millis = divmod(milliseconds, 1000)
|
||||
minutes, seconds = divmod(seconds, 60)
|
||||
hours, minutes = divmod(minutes, 60)
|
||||
|
|
|
@ -38,7 +38,6 @@ from openlp.core.ui.media.mediaplayer import MediaPlayer
|
|||
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players,\
|
||||
parse_optical_path
|
||||
from openlp.core.ui.lib.toolbar import OpenLPToolbar
|
||||
from openlp.core.ui.lib.dockwidget import OpenLPDockWidget
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -175,7 +174,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
|||
log.debug('_check_available_media_players')
|
||||
controller_dir = os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'core', 'ui', 'media')
|
||||
for filename in os.listdir(controller_dir):
|
||||
if filename.endswith('player.py') and not filename == 'mediaplayer.py':
|
||||
if filename.endswith('player.py') and filename != 'mediaplayer.py':
|
||||
path = os.path.join(controller_dir, filename)
|
||||
if os.path.isfile(path):
|
||||
module_name = 'openlp.core.ui.media.' + os.path.splitext(filename)[0]
|
||||
|
@ -554,7 +553,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
|||
default_player = [used_players[0]]
|
||||
if service_item.processor and service_item.processor != UiStrings().Automatic:
|
||||
# check to see if the player is usable else use the default one.
|
||||
if not service_item.processor.lower() in used_players:
|
||||
if service_item.processor.lower() not in used_players:
|
||||
used_players = default_player
|
||||
else:
|
||||
used_players = [service_item.processor.lower()]
|
||||
|
|
|
@ -224,9 +224,11 @@ class PlayerTab(SettingsTab):
|
|||
self.settings_form.register_post_process('mediaitem_media_rebuild')
|
||||
self.settings_form.register_post_process('config_screen_changed')
|
||||
|
||||
def post_set_up(self):
|
||||
def post_set_up(self, post_update=False):
|
||||
"""
|
||||
Late setup for players as the MediaController has to be initialised first.
|
||||
|
||||
:param post_update: Indicates if called before or after updates.
|
||||
"""
|
||||
for key, player in self.media_players.items():
|
||||
player = self.media_players[key]
|
||||
|
|
|
@ -112,7 +112,6 @@ def get_vlc():
|
|||
# This needs to happen on module load and not in get_vlc(), otherwise it can cause crashes on some DE on some setups
|
||||
# (reported on Gnome3, Unity, Cinnamon, all GTK+ based) when using native filedialogs...
|
||||
if is_linux() and 'nose' not in sys.argv[0] and get_vlc():
|
||||
import ctypes
|
||||
try:
|
||||
try:
|
||||
x11 = ctypes.cdll.LoadLibrary('libX11.so.6')
|
||||
|
@ -233,7 +232,7 @@ class VlcPlayer(MediaPlayer):
|
|||
"""
|
||||
vlc = get_vlc()
|
||||
start = datetime.now()
|
||||
while not media_state == display.vlc_media.get_state():
|
||||
while media_state != display.vlc_media.get_state():
|
||||
if display.vlc_media.get_state() == vlc.State.Error:
|
||||
return False
|
||||
self.application.process_events()
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
"""
|
||||
The :mod:`~openlp.core.ui.media.webkit` module contains our WebKit video player
|
||||
"""
|
||||
from PyQt5 import QtGui, QtWebKitWidgets
|
||||
|
||||
import logging
|
||||
|
||||
from PyQt5 import QtGui, QtWebKitWidgets
|
||||
|
||||
from openlp.core.common import Settings
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.ui.media import MediaState
|
||||
|
|
|
@ -74,6 +74,6 @@ class Ui_PluginViewDialog(object):
|
|||
"""
|
||||
plugin_view_dialog.setWindowTitle(translate('OpenLP.PluginForm', 'Manage Plugins'))
|
||||
self.plugin_info_group_box.setTitle(translate('OpenLP.PluginForm', 'Plugin Details'))
|
||||
self.about_label.setText('%s:' % UiStrings().About)
|
||||
self.about_label.setText('{about}:'.format(about=UiStrings().About))
|
||||
self.status_label.setText(translate('OpenLP.PluginForm', 'Status:'))
|
||||
self.status_checkbox.setText(translate('OpenLP.PluginForm', 'Active'))
|
||||
|
|
|
@ -60,6 +60,7 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
|
|||
self._clear_details()
|
||||
self.programatic_change = True
|
||||
plugin_list_width = 0
|
||||
# TODO: See how to use format() with variables
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
item = QtWidgets.QListWidgetItem(self.plugin_list_widget)
|
||||
# We do this just to make 100% sure the status is an integer as
|
||||
|
@ -94,7 +95,7 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
|
|||
"""
|
||||
Set the details of the currently selected plugin
|
||||
"""
|
||||
log.debug('PluginStatus: %s', str(self.active_plugin.status))
|
||||
log.debug('PluginStatus: {status}'.format(status=str(self.active_plugin.status)))
|
||||
self.about_text_browser.setHtml(self.active_plugin.about())
|
||||
self.programatic_change = True
|
||||
if self.active_plugin.status != PluginStatus.Disabled:
|
||||
|
@ -136,6 +137,7 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
|
|||
self.active_plugin.app_startup()
|
||||
else:
|
||||
self.active_plugin.toggle_status(PluginStatus.Inactive)
|
||||
# TODO: Verify using format() with a variable
|
||||
status_text = translate('OpenLP.PluginForm', '%s (Inactive)')
|
||||
if self.active_plugin.status == PluginStatus.Active:
|
||||
status_text = translate('OpenLP.PluginForm', '%s (Active)')
|
||||
|
|
|
@ -25,7 +25,8 @@ The UI widgets of the print service dialog.
|
|||
from PyQt5 import QtCore, QtWidgets, QtPrintSupport
|
||||
|
||||
from openlp.core.common import UiStrings, translate
|
||||
from openlp.core.lib import SpellTextEdit, build_icon
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.lib import SpellTextEdit
|
||||
|
||||
|
||||
class ZoomSize(object):
|
||||
|
|
|
@ -141,23 +141,23 @@ def Build_Tab(group, source_key, default, projector, projectordb, edit=False):
|
|||
return widget, button_count, buttonchecked
|
||||
|
||||
|
||||
def set_button_tooltip(bar):
|
||||
def set_button_tooltip(button_bar):
|
||||
"""
|
||||
Set the toolip for the standard buttons used
|
||||
|
||||
:param bar: QDialogButtonBar instance to update
|
||||
:param button_bar: QDialogButtonBar instance to update
|
||||
"""
|
||||
for button in bar.buttons():
|
||||
if bar.standardButton(button) == QDialogButtonBox.Cancel:
|
||||
for button in button_bar.buttons():
|
||||
if button_bar.standardButton(button) == QDialogButtonBox.Cancel:
|
||||
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||
'Ignoring current changes and return to OpenLP'))
|
||||
elif bar.standardButton(button) == QDialogButtonBox.Reset:
|
||||
elif button_bar.standardButton(button) == QDialogButtonBox.Reset:
|
||||
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||
'Delete all user-defined text and revert to PJLink default text'))
|
||||
elif bar.standardButton(button) == QDialogButtonBox.Discard:
|
||||
elif button_bar.standardButton(button) == QDialogButtonBox.Discard:
|
||||
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||
'Discard changes and reset to previous user-defined text'))
|
||||
elif bar.standardButton(button) == QDialogButtonBox.Ok:
|
||||
elif button_bar.standardButton(button) == QDialogButtonBox.Ok:
|
||||
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||
'Save changes and return to OpenLP'))
|
||||
else:
|
||||
|
|
|
@ -133,7 +133,7 @@ class ProjectorTab(SettingsTab):
|
|||
settings.setValue('socket timeout', self.socket_timeout_spin_box.value())
|
||||
settings.setValue('poll time', self.socket_poll_spin_box.value())
|
||||
settings.setValue('source dialog type', self.dialog_type_combo_box.currentIndex())
|
||||
settings.endGroup
|
||||
settings.endGroup()
|
||||
|
||||
def on_dialog_type_combo_box_changed(self):
|
||||
self.dialog_type = self.dialog_type_combo_box.currentIndex()
|
||||
|
|
|
@ -118,7 +118,7 @@ class Ui_ServiceManager(object):
|
|||
tooltip=translate('OpenLP.ServiceManager', 'Save this service.'),
|
||||
triggers=self.decide_save_method)
|
||||
self.toolbar.addSeparator()
|
||||
self.theme_label = QtWidgets.QLabel('%s:' % UiStrings().Theme, widget)
|
||||
self.theme_label = QtWidgets.QLabel('{theme}:'.format(theme=UiStrings().Theme), widget)
|
||||
self.theme_label.setContentsMargins(3, 3, 3, 3)
|
||||
self.theme_label.setObjectName('theme_label')
|
||||
self.toolbar.add_toolbar_widget(self.theme_label)
|
||||
|
@ -480,9 +480,10 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
:return: service array
|
||||
"""
|
||||
service = []
|
||||
core = {'lite-service': self._save_lite,
|
||||
'service-theme': self.service_theme
|
||||
}
|
||||
core = {
|
||||
'lite-service': self._save_lite,
|
||||
'service-theme': self.service_theme
|
||||
}
|
||||
service.append({'openlp_core': core})
|
||||
return service
|
||||
|
||||
|
@ -503,8 +504,8 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
path_file_name = str(self.file_name())
|
||||
path, file_name = os.path.split(path_file_name)
|
||||
base_name = os.path.splitext(file_name)[0]
|
||||
service_file_name = '%s.osj' % base_name
|
||||
self.log_debug('ServiceManager.save_file - %s' % path_file_name)
|
||||
service_file_name = '{name}.osj'.format(name=base_name)
|
||||
self.log_debug('ServiceManager.save_file - {name}'.format(name=path_file_name))
|
||||
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', path)
|
||||
service = self.create_basic_service()
|
||||
write_list = []
|
||||
|
@ -530,8 +531,9 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
self.application.set_normal_cursor()
|
||||
title = translate('OpenLP.ServiceManager', 'Service File(s) Missing')
|
||||
message = translate('OpenLP.ServiceManager',
|
||||
'The following file(s) in the service are missing: %s\n\n'
|
||||
'These files will be removed if you continue to save.') % "\n\t".join(missing_list)
|
||||
'The following file(s) in the service are missing: {name}\n\n'
|
||||
'These files will be removed if you continue to save.'
|
||||
).format(name="\n\t".join(missing_list))
|
||||
answer = QtWidgets.QMessageBox.critical(self, title, message,
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok |
|
||||
QtWidgets.QMessageBox.Cancel))
|
||||
|
@ -561,7 +563,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
service_content = json.dumps(service)
|
||||
# Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be extracted using unzip in UNIX.
|
||||
allow_zip_64 = (total_size > 2147483648 + len(service_content))
|
||||
self.log_debug('ServiceManager.save_file - allowZip64 is %s' % allow_zip_64)
|
||||
self.log_debug('ServiceManager.save_file - allowZip64 is {text}'.format(text=allow_zip_64))
|
||||
zip_file = None
|
||||
success = True
|
||||
self.main_window.increment_progress_bar()
|
||||
|
@ -584,7 +586,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
shutil.copy(audio_from, save_file)
|
||||
zip_file.write(audio_from, audio_to)
|
||||
except IOError:
|
||||
self.log_exception('Failed to save service to disk: %s' % temp_file_name)
|
||||
self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file_name))
|
||||
self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||
translate('OpenLP.ServiceManager', 'There was an error saving your file.'))
|
||||
success = False
|
||||
|
@ -596,12 +598,12 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
if success:
|
||||
try:
|
||||
shutil.copy(temp_file_name, path_file_name)
|
||||
except shutil.Error:
|
||||
except (shutil.Error, PermissionError):
|
||||
return self.save_file_as()
|
||||
except OSError as ose:
|
||||
QtWidgets.QMessageBox.critical(self, translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||
translate('OpenLP.ServiceManager', 'An error occurred while writing the '
|
||||
'service file: %s') % ose.strerror,
|
||||
'service file: {error}').format(error=ose.strerror),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
success = False
|
||||
self.main_window.add_recent_file(path_file_name)
|
||||
|
@ -623,8 +625,8 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
path_file_name = str(self.file_name())
|
||||
path, file_name = os.path.split(path_file_name)
|
||||
base_name = os.path.splitext(file_name)[0]
|
||||
service_file_name = '%s.osj' % base_name
|
||||
self.log_debug('ServiceManager.save_file - %s' % path_file_name)
|
||||
service_file_name = '{name}.osj'.format(name=base_name)
|
||||
self.log_debug('ServiceManager.save_file - {name}'.format(name=path_file_name))
|
||||
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', path)
|
||||
service = self.create_basic_service()
|
||||
self.application.set_busy_cursor()
|
||||
|
@ -645,7 +647,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
# First we add service contents.
|
||||
zip_file.writestr(service_file_name, service_content)
|
||||
except IOError:
|
||||
self.log_exception('Failed to save service to disk: %s', temp_file_name)
|
||||
self.log_exception('Failed to save service to disk: {name}'.format(name=temp_file_name))
|
||||
self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||
translate('OpenLP.ServiceManager', 'There was an error saving your file.'))
|
||||
success = False
|
||||
|
@ -657,7 +659,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
if success:
|
||||
try:
|
||||
shutil.copy(temp_file_name, path_file_name)
|
||||
except shutil.Error:
|
||||
except (shutil.Error, PermissionError):
|
||||
return self.save_file_as()
|
||||
self.main_window.add_recent_file(path_file_name)
|
||||
self.set_modified(False)
|
||||
|
@ -740,13 +742,13 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
try:
|
||||
ucs_file = zip_info.filename
|
||||
except UnicodeDecodeError:
|
||||
self.log_exception('file_name "%s" is not valid UTF-8' % zip_info.file_name)
|
||||
self.log_exception('file_name "{name}" is not valid UTF-8'.format(name=zip_info.file_name))
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager',
|
||||
'File is not a valid service.\n The content encoding is not UTF-8.'))
|
||||
continue
|
||||
os_file = ucs_file.replace('/', os.path.sep)
|
||||
os_file = os.path.basename(os_file)
|
||||
self.log_debug('Extract file: %s' % os_file)
|
||||
self.log_debug('Extract file: {name}'.format(name=os_file))
|
||||
zip_info.filename = os_file
|
||||
zip_file.extract(zip_info, self.service_path)
|
||||
if os_file.endswith('osj') or os_file.endswith('osd'):
|
||||
|
@ -773,19 +775,19 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
else:
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.'))
|
||||
self.log_error('File contains no service data')
|
||||
except (IOError, NameError, zipfile.BadZipfile):
|
||||
self.log_exception('Problem loading service file %s' % file_name)
|
||||
except (IOError, NameError):
|
||||
self.log_exception('Problem loading service file {name}'.format(name=file_name))
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager',
|
||||
'File could not be opened because it is corrupt.'))
|
||||
except zipfile.BadZipfile:
|
||||
if os.path.getsize(file_name) == 0:
|
||||
self.log_exception('Service file is zero sized: %s' % file_name)
|
||||
self.log_exception('Service file is zero sized: {name}'.format(name=file_name))
|
||||
QtWidgets.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Empty File'),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'This service file does not contain '
|
||||
'any data.'))
|
||||
else:
|
||||
self.log_exception('Service file is cannot be extracted as zip: %s' % file_name)
|
||||
self.log_exception('Service file is cannot be extracted as zip: {name}'.format(name=file_name))
|
||||
QtWidgets.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Corrupt File'),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'This file is either corrupt or it is not an OpenLP 2 '
|
||||
|
@ -874,7 +876,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
self.auto_play_slides_loop.setChecked(service_item['service_item'].auto_play_slides_loop)
|
||||
self.timed_slide_interval.setChecked(service_item['service_item'].timed_slide_interval > 0)
|
||||
if service_item['service_item'].timed_slide_interval > 0:
|
||||
delay_suffix = ' %s s' % str(service_item['service_item'].timed_slide_interval)
|
||||
delay_suffix = ' {text} s'.format(text=str(service_item['service_item'].timed_slide_interval))
|
||||
else:
|
||||
delay_suffix = ' ...'
|
||||
self.timed_slide_interval.setText(
|
||||
|
@ -1268,14 +1270,17 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
tree_widget_item.setText(0, service_item_from_item.get_display_title())
|
||||
tips = []
|
||||
if service_item_from_item.temporary_edit:
|
||||
tips.append('<strong>%s:</strong> <em>%s</em>' % (translate('OpenLP.ServiceManager', 'Edit'),
|
||||
(translate('OpenLP.ServiceManager', 'Service copy only'))))
|
||||
text1 = translate('OpenLP.ServiceManager', 'Edit')
|
||||
text2 = translate('OpenLP.ServiceManager', 'Service copy only')
|
||||
tips.append('<strong>{text1}:</strong> <em>{text2}</em>'.format(text1=text1, text2=text2))
|
||||
if service_item_from_item.theme and service_item_from_item.theme != -1:
|
||||
tips.append('<strong>%s:</strong> <em>%s</em>' %
|
||||
(translate('OpenLP.ServiceManager', 'Slide theme'), service_item_from_item.theme))
|
||||
text = translate('OpenLP.ServiceManager', 'Slide theme')
|
||||
tips.append('<strong>{text1}:</strong> <em>{text2}</em>'.format(text1=text,
|
||||
text2=service_item_from_item.theme))
|
||||
if service_item_from_item.notes:
|
||||
tips.append('<strong>%s: </strong> %s' %
|
||||
(translate('OpenLP.ServiceManager', 'Notes'), html.escape(service_item_from_item.notes)))
|
||||
text1 = translate('OpenLP.ServiceManager', 'Notes')
|
||||
text2 = html.escape(service_item_from_item.notes)
|
||||
tips.append('<strong>{text1}: </strong> {text2}'.format(text1=text1, text2=text2))
|
||||
if item['service_item'].is_capable(ItemCapabilities.HasVariableStartTime):
|
||||
tips.append(item['service_item'].get_media_time())
|
||||
tree_widget_item.setToolTip(0, '<br>'.join(tips))
|
||||
|
@ -1323,9 +1328,9 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
"""
|
||||
The theme may have changed in the settings dialog so make sure the theme combo box is in the correct state.
|
||||
"""
|
||||
visible = not self.renderer.theme_level == ThemeLevel.Global
|
||||
self.theme_label.setVisible(visible)
|
||||
self.theme_combo_box.setVisible(visible)
|
||||
visible = self.renderer.theme_level != ThemeLevel.Global
|
||||
self.toolbar.actions['theme_combo_box'].setVisible(visible)
|
||||
self.toolbar.actions['theme_label'].setVisible(visible)
|
||||
self.regenerate_service_items()
|
||||
|
||||
def regenerate_service_items(self, changed=False):
|
||||
|
@ -1637,7 +1642,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
|||
replace = True
|
||||
else:
|
||||
self.drop_position = get_parent_item_data(item) - 1
|
||||
Registry().execute('%s_add_service_item' % plugin, replace)
|
||||
Registry().execute('{plugin}_add_service_item'.format(plugin=plugin), replace)
|
||||
|
||||
def update_theme_list(self, theme_list):
|
||||
"""
|
||||
|
|
|
@ -25,7 +25,7 @@ The :mod:`~openlp.core.ui.servicenoteform` module contains the `ServiceNoteForm`
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common import Registry, RegistryProperties, translate
|
||||
from openlp.core.lib import SpellTextEdit
|
||||
from openlp.core.ui.lib import SpellTextEdit
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
|
|||
:param tab_widget: The widget to add
|
||||
:param is_visible: If this tab should be visible
|
||||
"""
|
||||
log.debug('Inserting %s tab' % tab_widget.tab_title)
|
||||
log.debug('Inserting {text} tab'.format(text=tab_widget.tab_title))
|
||||
# add the tab to get it to display in the correct part of the screen
|
||||
self.stacked_layout.addWidget(tab_widget)
|
||||
if is_visible:
|
||||
|
|
|
@ -425,11 +425,12 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
|
|||
if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||
is_valid = False
|
||||
if not is_valid:
|
||||
text = translate('OpenLP.ShortcutListDialog',
|
||||
'The shortcut "{key}" is already assigned to another action, please'
|
||||
' use a different shortcut.'
|
||||
).format(key=self.get_shortcut_string(key_sequence))
|
||||
self.main_window.warning_message(translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'),
|
||||
translate('OpenLP.ShortcutListDialog',
|
||||
'The shortcut "%s" is already assigned to another action, please'
|
||||
' use a different shortcut.') %
|
||||
self.get_shortcut_string(key_sequence, for_display=True))
|
||||
text, for_display=True)
|
||||
self.dialog_was_shown = True
|
||||
return is_valid
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ from openlp.core.lib import ItemCapabilities, ServiceItem, ImageSource, ServiceI
|
|||
build_html
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.core.ui.lib.toolbar import OpenLPToolbar
|
||||
from openlp.core.ui.lib.dockwidget import OpenLPDockWidget
|
||||
from openlp.core.ui.lib.listpreviewwidget import ListPreviewWidget
|
||||
from openlp.core.ui import HideMode, MainDisplay, Display, DisplayControllerType
|
||||
|
||||
|
@ -98,7 +97,7 @@ class DisplayController(QtWidgets.QWidget):
|
|||
"""
|
||||
sender = self.sender().objectName() if self.sender().objectName() else self.sender().text()
|
||||
controller = self
|
||||
Registry().execute('%s' % sender, [controller, args])
|
||||
Registry().execute('{text}'.format(text=sender), [controller, args])
|
||||
|
||||
|
||||
class InfoLabel(QtWidgets.QLabel):
|
||||
|
@ -395,7 +394,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
{'key': 'O', 'configurable': True, 'text': translate('OpenLP.SlideController', 'Go to "Other"')}
|
||||
]
|
||||
shortcuts.extend([{'key': str(number)} for number in range(10)])
|
||||
self.controller.addActions([create_action(self, 'shortcutAction_%s' % s['key'],
|
||||
self.controller.addActions([create_action(self, 'shortcutAction_{key}'.format(key=s['key']),
|
||||
text=s.get('text'),
|
||||
can_shortcuts=True,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
|
@ -417,14 +416,20 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
self.preview_widget.doubleClicked.connect(self.on_preview_double_click)
|
||||
self.toolbar.set_widget_visible(['editSong'], False)
|
||||
self.controller.addActions([self.next_item, self.previous_item])
|
||||
Registry().register_function('slidecontroller_%s_stop_loop' % self.type_prefix, self.on_stop_loop)
|
||||
Registry().register_function('slidecontroller_%s_change' % self.type_prefix, self.on_slide_change)
|
||||
Registry().register_function('slidecontroller_%s_blank' % self.type_prefix, self.on_slide_blank)
|
||||
Registry().register_function('slidecontroller_%s_unblank' % self.type_prefix, self.on_slide_unblank)
|
||||
Registry().register_function('slidecontroller_{text}_stop_loop'.format(text=self.type_prefix),
|
||||
self.on_stop_loop)
|
||||
Registry().register_function('slidecontroller_{text}_change'.format(text=self.type_prefix),
|
||||
self.on_slide_change)
|
||||
Registry().register_function('slidecontroller_{text}_blank'.format(text=self.type_prefix),
|
||||
self.on_slide_blank)
|
||||
Registry().register_function('slidecontroller_{text}_unblank'.format(text=self.type_prefix),
|
||||
self.on_slide_unblank)
|
||||
Registry().register_function('slidecontroller_update_slide_limits', self.update_slide_limits)
|
||||
getattr(self, 'slidecontroller_%s_set' % self.type_prefix).connect(self.on_slide_selected_index)
|
||||
getattr(self, 'slidecontroller_%s_next' % self.type_prefix).connect(self.on_slide_selected_next)
|
||||
getattr(self, 'slidecontroller_%s_previous' % self.type_prefix).connect(self.on_slide_selected_previous)
|
||||
getattr(self, 'slidecontroller_{text}_set'.format(text=self.type_prefix)).connect(self.on_slide_selected_index)
|
||||
getattr(self, 'slidecontroller_{text}_next'.format(text=self.type_prefix)).connect(self.on_slide_selected_next)
|
||||
# NOTE: {t} used to keep line length < maxline
|
||||
getattr(self,
|
||||
'slidecontroller_{t}_previous'.format(t=self.type_prefix)).connect(self.on_slide_selected_previous)
|
||||
|
||||
def _slide_shortcut_activated(self):
|
||||
"""
|
||||
|
@ -841,7 +846,8 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
self.service_item = copy.copy(service_item)
|
||||
if self.service_item.is_command():
|
||||
Registry().execute(
|
||||
'%s_start' % service_item.name.lower(), [self.service_item, self.is_live, self.hide_mode(), slide_no])
|
||||
'{text}_start'.format(text=service_item.name.lower()),
|
||||
[self.service_item, self.is_live, self.hide_mode(), slide_no])
|
||||
# Reset blanking if needed
|
||||
if old_item and self.is_live and (old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or
|
||||
self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay)):
|
||||
|
@ -879,8 +885,8 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
if frame['verseTag']:
|
||||
# These tags are already translated.
|
||||
verse_def = frame['verseTag']
|
||||
verse_def = '%s%s' % (verse_def[0], verse_def[1:])
|
||||
two_line_def = '%s\n%s' % (verse_def[0], verse_def[1:])
|
||||
verse_def = '{def1}{def2}'.format(def1=verse_def[0], def2=verse_def[1:])
|
||||
two_line_def = '{def1}\n{def2}'.format(def1=verse_def[0], def2=verse_def[1:])
|
||||
row = two_line_def
|
||||
if verse_def not in self.slide_list:
|
||||
self.slide_list[verse_def] = frame_number
|
||||
|
@ -915,10 +921,10 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
# close the previous, so make sure we don't close the new one.
|
||||
if old_item.is_command() and not self.service_item.is_command() or \
|
||||
old_item.is_command() and not old_item.is_media() and self.service_item.is_media():
|
||||
Registry().execute('%s_stop' % old_item.name.lower(), [old_item, self.is_live])
|
||||
Registry().execute('{name}_stop'.format(name=old_item.name.lower()), [old_item, self.is_live])
|
||||
if old_item.is_media() and not self.service_item.is_media():
|
||||
self.on_media_close()
|
||||
Registry().execute('slidecontroller_%s_started' % self.type_prefix, [self.service_item])
|
||||
Registry().execute('slidecontroller_{item}_started'.format(item=self.type_prefix), [self.service_item])
|
||||
|
||||
def on_slide_selected_index(self, message):
|
||||
"""
|
||||
|
@ -930,7 +936,8 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
if not self.service_item:
|
||||
return
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_slide' % self.service_item.name.lower(), [self.service_item, self.is_live, index])
|
||||
Registry().execute('{name}_slide'.format(name=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live, index])
|
||||
self.update_preview()
|
||||
self.selected_row = index
|
||||
else:
|
||||
|
@ -975,7 +982,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
"""
|
||||
if checked is None:
|
||||
checked = self.blank_screen.isChecked()
|
||||
self.log_debug('on_blank_display %s' % checked)
|
||||
self.log_debug('on_blank_display {text}'.format(text=checked))
|
||||
self.hide_menu.setDefaultAction(self.blank_screen)
|
||||
self.blank_screen.setChecked(checked)
|
||||
self.theme_screen.setChecked(False)
|
||||
|
@ -996,7 +1003,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
"""
|
||||
if checked is None:
|
||||
checked = self.theme_screen.isChecked()
|
||||
self.log_debug('on_theme_display %s' % checked)
|
||||
self.log_debug('on_theme_display {text}'.format(text=checked))
|
||||
self.hide_menu.setDefaultAction(self.theme_screen)
|
||||
self.blank_screen.setChecked(False)
|
||||
self.theme_screen.setChecked(checked)
|
||||
|
@ -1017,7 +1024,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
"""
|
||||
if checked is None:
|
||||
checked = self.desktop_screen.isChecked()
|
||||
self.log_debug('on_hide_display %s' % checked)
|
||||
self.log_debug('on_hide_display {text}'.format(text=checked))
|
||||
self.hide_menu.setDefaultAction(self.desktop_screen)
|
||||
self.blank_screen.setChecked(False)
|
||||
self.theme_screen.setChecked(False)
|
||||
|
@ -1035,17 +1042,18 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
Blank/Hide the display screen within a plugin if required.
|
||||
"""
|
||||
hide_mode = self.hide_mode()
|
||||
self.log_debug('blank_plugin %s ' % hide_mode)
|
||||
self.log_debug('blank_plugin {text}'.format(text=hide_mode))
|
||||
if self.service_item is not None:
|
||||
if hide_mode:
|
||||
if not self.service_item.is_command():
|
||||
Registry().execute('live_display_hide', hide_mode)
|
||||
Registry().execute('%s_blank' %
|
||||
self.service_item.name.lower(), [self.service_item, self.is_live, hide_mode])
|
||||
Registry().execute('{text}_blank'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live, hide_mode])
|
||||
else:
|
||||
if not self.service_item.is_command():
|
||||
Registry().execute('live_display_show')
|
||||
Registry().execute('%s_unblank' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_unblank'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
else:
|
||||
if hide_mode:
|
||||
Registry().execute('live_display_hide', hide_mode)
|
||||
|
@ -1056,15 +1064,17 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
"""
|
||||
Tell the plugin to hide the display screen.
|
||||
"""
|
||||
self.log_debug('hide_plugin %s ' % hide)
|
||||
self.log_debug('hide_plugin {text}'.format(text=hide))
|
||||
if self.service_item is not None:
|
||||
if hide:
|
||||
Registry().execute('live_display_hide', HideMode.Screen)
|
||||
Registry().execute('%s_hide' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_hide'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
else:
|
||||
if not self.service_item.is_command():
|
||||
Registry().execute('live_display_show')
|
||||
Registry().execute('%s_unblank' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_unblank'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
else:
|
||||
if hide:
|
||||
Registry().execute('live_display_hide', HideMode.Screen)
|
||||
|
@ -1099,8 +1109,8 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
if -1 < row < self.preview_widget.slide_count():
|
||||
if self.service_item.is_command():
|
||||
if self.is_live and not start:
|
||||
Registry().execute('%s_slide' %
|
||||
self.service_item.name.lower(), [self.service_item, self.is_live, row])
|
||||
Registry().execute('{text}_slide'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live, row])
|
||||
else:
|
||||
to_display = self.service_item.get_rendered_frame(row)
|
||||
if self.service_item.is_text():
|
||||
|
@ -1133,7 +1143,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
"""
|
||||
This updates the preview frame, for example after changing a slide or using *Blank to Theme*.
|
||||
"""
|
||||
self.log_debug('update_preview %s ' % self.screens.current['primary'])
|
||||
self.log_debug('update_preview {text} '.format(text=self.screens.current['primary']))
|
||||
if self.service_item and self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay):
|
||||
if self.is_live:
|
||||
# If live, grab screen-cap of main display now
|
||||
|
@ -1185,7 +1195,8 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
if not self.service_item:
|
||||
return
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_next' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_next'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
if self.is_live:
|
||||
self.update_preview()
|
||||
else:
|
||||
|
@ -1213,7 +1224,8 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
if not self.service_item:
|
||||
return
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_previous' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_previous'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
if self.is_live:
|
||||
self.update_preview()
|
||||
else:
|
||||
|
@ -1265,7 +1277,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
checked = self.play_slides_loop.isChecked()
|
||||
else:
|
||||
self.play_slides_loop.setChecked(checked)
|
||||
self.log_debug('on_play_slides_loop %s' % checked)
|
||||
self.log_debug('on_play_slides_loop {text}'.format(text=checked))
|
||||
if checked:
|
||||
self.play_slides_loop.setIcon(build_icon(':/media/media_stop.png'))
|
||||
self.play_slides_loop.setText(UiStrings().StopPlaySlidesInLoop)
|
||||
|
@ -1288,7 +1300,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
checked = self.play_slides_once.isChecked()
|
||||
else:
|
||||
self.play_slides_once.setChecked(checked)
|
||||
self.log_debug('on_play_slides_once %s' % checked)
|
||||
self.log_debug('on_play_slides_once {text}'.format(text=checked))
|
||||
if checked:
|
||||
self.play_slides_once.setIcon(build_icon(':/media/media_stop.png'))
|
||||
self.play_slides_once.setText(UiStrings().StopPlaySlidesToEnd)
|
||||
|
@ -1354,7 +1366,8 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
# Live and Preview have issues if we have video or presentations
|
||||
# playing in both at the same time.
|
||||
if self.service_item.is_command():
|
||||
Registry().execute('%s_stop' % self.service_item.name.lower(), [self.service_item, self.is_live])
|
||||
Registry().execute('{text}_stop'.format(text=self.service_item.name.lower()),
|
||||
[self.service_item, self.is_live])
|
||||
if self.service_item.is_media():
|
||||
self.on_media_close()
|
||||
self.on_go_live()
|
||||
|
|
|
@ -56,9 +56,9 @@ class StartTimeForm(QtWidgets.QDialog, Ui_StartTimeDialog, RegistryProperties):
|
|||
self.hour_finish_spin_box.setValue(hours)
|
||||
self.minute_finish_spin_box.setValue(minutes)
|
||||
self.second_finish_spin_box.setValue(seconds)
|
||||
self.hour_finish_label.setText('%s%s' % (str(hour), UiStrings().Hours))
|
||||
self.minute_finish_label.setText('%s%s' % (str(minutes), UiStrings().Minutes))
|
||||
self.second_finish_label.setText('%s%s' % (str(seconds), UiStrings().Seconds))
|
||||
self.hour_finish_label.setText('{val:d}{text}'.format(val=hour, text=UiStrings().Hours))
|
||||
self.minute_finish_label.setText('{val:d}{text}'.format(val=minutes, text=UiStrings().Minutes))
|
||||
self.second_finish_label.setText('{val:d}{text}'.format(val=seconds, text=UiStrings().Seconds))
|
||||
return QtWidgets.QDialog.exec(self)
|
||||
|
||||
def accept(self):
|
||||
|
|
|
@ -249,7 +249,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
|||
NOTE the font_main_override is the inverse of the check box value
|
||||
"""
|
||||
if self.update_theme_allowed:
|
||||
self.theme.font_main_override = not (value == QtCore.Qt.Checked)
|
||||
self.theme.font_main_override = (value != QtCore.Qt.Checked)
|
||||
|
||||
def on_footer_position_check_box_state_changed(self, value):
|
||||
"""
|
||||
|
@ -257,13 +257,13 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
|||
NOTE the font_footer_override is the inverse of the check box value
|
||||
"""
|
||||
if self.update_theme_allowed:
|
||||
self.theme.font_footer_override = not (value == QtCore.Qt.Checked)
|
||||
self.theme.font_footer_override = (value != QtCore.Qt.Checked)
|
||||
|
||||
def exec(self, edit=False):
|
||||
"""
|
||||
Run the wizard.
|
||||
"""
|
||||
log.debug('Editing theme %s' % self.theme.theme_name)
|
||||
log.debug('Editing theme {name}'.format(name=self.theme.theme_name))
|
||||
self.temp_background_filename = ''
|
||||
self.update_theme_allowed = False
|
||||
self.set_defaults()
|
||||
|
@ -272,7 +272,8 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
|||
self.theme_name_edit.setVisible(not edit)
|
||||
self.edit_mode = edit
|
||||
if edit:
|
||||
self.setWindowTitle(translate('OpenLP.ThemeWizard', 'Edit Theme - %s') % self.theme.theme_name)
|
||||
self.setWindowTitle(translate('OpenLP.ThemeWizard', 'Edit Theme - {name}'
|
||||
).format(name=self.theme.theme_name))
|
||||
self.next()
|
||||
else:
|
||||
self.setWindowTitle(UiStrings().NewTheme)
|
||||
|
@ -282,7 +283,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
|||
"""
|
||||
Set up the pages for Initial run through dialog
|
||||
"""
|
||||
log.debug('initializePage %s' % page_id)
|
||||
log.debug('initializePage {page}'.format(page=page_id))
|
||||
wizard_page = self.page(page_id)
|
||||
if wizard_page == self.background_page:
|
||||
self.set_background_page_values()
|
||||
|
@ -445,7 +446,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
|||
Background Image button pushed.
|
||||
"""
|
||||
images_filter = get_images_filter()
|
||||
images_filter = '%s;;%s (*.*)' % (images_filter, UiStrings().AllFiles)
|
||||
images_filter = '{name};;{text} (*.*)'.format(name=images_filter, text=UiStrings().AllFiles)
|
||||
filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(
|
||||
self, translate('OpenLP.ThemeWizard', 'Select Image'),
|
||||
self.image_file_edit.text(), images_filter)
|
||||
|
@ -463,6 +464,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
|||
"""
|
||||
Background video button pushed.
|
||||
"""
|
||||
# TODO: Check this before converting
|
||||
visible_formats = '(%s)' % '; '.join(VIDEO_EXT)
|
||||
actual_formats = '(%s)' % ' '.join(VIDEO_EXT)
|
||||
video_filter = '{trans} {visible} {actual}'.format(trans=translate('OpenLP', 'Video Files'),
|
||||
|
|
|
@ -203,7 +203,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
Change the global theme when it is changed through the Themes settings tab
|
||||
"""
|
||||
self.global_theme = Settings().value(self.settings_section + '/global theme')
|
||||
self.log_debug('change_global_from_tab %s' % self.global_theme)
|
||||
self.log_debug('change_global_from_tab {text}'.format(text=self.global_theme))
|
||||
for count in range(0, self.theme_list_widget.count()):
|
||||
# reset the old name
|
||||
item = self.theme_list_widget.item(count)
|
||||
|
@ -213,7 +213,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
self.theme_list_widget.item(count).setText(new_name)
|
||||
# Set the new name
|
||||
if self.global_theme == new_name:
|
||||
name = translate('OpenLP.ThemeManager', '%s (default)') % new_name
|
||||
name = translate('OpenLP.ThemeManager', '{text} (default)').format(text=new_name)
|
||||
self.theme_list_widget.item(count).setText(name)
|
||||
self.delete_toolbar_action.setVisible(item not in self.theme_list_widget.selectedItems())
|
||||
|
||||
|
@ -233,7 +233,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
# Set the new name
|
||||
if count == selected_row:
|
||||
self.global_theme = self.theme_list_widget.item(count).text()
|
||||
name = translate('OpenLP.ThemeManager', '%s (default)') % self.global_theme
|
||||
name = translate('OpenLP.ThemeManager', '{text} (default)').format(text=self.global_theme)
|
||||
self.theme_list_widget.item(count).setText(name)
|
||||
Settings().setValue(self.settings_section + '/global theme', self.global_theme)
|
||||
Registry().execute('theme_update_global')
|
||||
|
@ -256,6 +256,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
Renames an existing theme to a new name
|
||||
:param field:
|
||||
"""
|
||||
# TODO: Check for delayed format() conversions
|
||||
if self._validate_theme_action(translate('OpenLP.ThemeManager', 'You must select a theme to rename.'),
|
||||
translate('OpenLP.ThemeManager', 'Rename Confirmation'),
|
||||
translate('OpenLP.ThemeManager', 'Rename %s theme?'), False, False):
|
||||
|
@ -284,7 +285,8 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
item = self.theme_list_widget.currentItem()
|
||||
old_theme_name = item.data(QtCore.Qt.UserRole)
|
||||
self.file_rename_form.file_name_edit.setText(translate('OpenLP.ThemeManager',
|
||||
'Copy of %s', 'Copy of <theme name>') % old_theme_name)
|
||||
'Copy of {name}',
|
||||
'Copy of <theme name>').format(name=old_theme_name))
|
||||
if self.file_rename_form.exec(True):
|
||||
new_theme_name = self.file_rename_form.file_name_edit.text()
|
||||
if self.check_if_theme_exists(new_theme_name):
|
||||
|
@ -331,6 +333,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
Delete a theme triggered by the UI.
|
||||
:param field:
|
||||
"""
|
||||
# TODO: Verify delayed format() conversions
|
||||
if self._validate_theme_action(translate('OpenLP.ThemeManager', 'You must select a theme to delete.'),
|
||||
translate('OpenLP.ThemeManager', 'Delete Confirmation'),
|
||||
translate('OpenLP.ThemeManager', 'Delete %s theme?')):
|
||||
|
@ -351,7 +354,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
:param theme: The theme to delete.
|
||||
"""
|
||||
self.theme_list.remove(theme)
|
||||
thumb = '%s.png' % theme
|
||||
thumb = '{name}.png'.format(name=theme)
|
||||
delete_file(os.path.join(self.path, thumb))
|
||||
delete_file(os.path.join(self.thumb_path, thumb))
|
||||
try:
|
||||
|
@ -363,7 +366,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
|
||||
except OSError as os_error:
|
||||
shutil.Error = os_error
|
||||
self.log_exception('Error deleting theme %s' % theme)
|
||||
self.log_exception('Error deleting theme {name}'.format(name=theme))
|
||||
|
||||
def on_export_theme(self, field=None):
|
||||
"""
|
||||
|
@ -376,7 +379,8 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
return
|
||||
theme = item.data(QtCore.Qt.UserRole)
|
||||
path = QtWidgets.QFileDialog.getExistingDirectory(self,
|
||||
translate('OpenLP.ThemeManager', 'Save Theme - (%s)') % theme,
|
||||
translate('OpenLP.ThemeManager',
|
||||
'Save Theme - ({name})').format(name=theme),
|
||||
Settings().value(self.settings_section +
|
||||
'/last directory export'))
|
||||
self.application.set_busy_cursor()
|
||||
|
@ -409,7 +413,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
self.log_exception('Export Theme Failed')
|
||||
critical_error_message_box(translate('OpenLP.ThemeManager', 'Theme Export Failed'),
|
||||
translate('OpenLP.ThemeManager', 'The theme export failed because this error '
|
||||
'occurred: %s') % ose.strerror)
|
||||
'occurred: {err}').format(err=ose.strerror))
|
||||
if theme_zip:
|
||||
theme_zip.close()
|
||||
shutil.rmtree(theme_path, True)
|
||||
|
@ -425,7 +429,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
|
||||
Settings().value(self.settings_section + '/last directory import'),
|
||||
translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'))
|
||||
self.log_info('New Themes %s' % str(files))
|
||||
self.log_info('New Themes {name}'.format(name=str(files)))
|
||||
if not files:
|
||||
return
|
||||
self.application.set_busy_cursor()
|
||||
|
@ -472,10 +476,10 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
if os.path.exists(theme):
|
||||
text_name = os.path.splitext(name)[0]
|
||||
if text_name == self.global_theme:
|
||||
name = translate('OpenLP.ThemeManager', '%s (default)') % text_name
|
||||
name = translate('OpenLP.ThemeManager', '{name} (default)').format(name=text_name)
|
||||
else:
|
||||
name = text_name
|
||||
thumb = os.path.join(self.thumb_path, '%s.png' % text_name)
|
||||
thumb = os.path.join(self.thumb_path, '{name}.png'.format(name=text_name))
|
||||
item_name = QtWidgets.QListWidgetItem(name)
|
||||
if validate_thumb(theme, thumb):
|
||||
icon = build_icon(thumb)
|
||||
|
@ -506,7 +510,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
:param theme_name: Name of the theme to load from file
|
||||
:return: The theme object.
|
||||
"""
|
||||
self.log_debug('get theme data for theme %s' % theme_name)
|
||||
self.log_debug('get theme data for theme {name}'.format(name=theme_name))
|
||||
xml_file = os.path.join(self.path, str(theme_name), str(theme_name) + '.xml')
|
||||
xml = get_text_file_string(xml_file)
|
||||
if not xml:
|
||||
|
@ -524,8 +528,8 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
"""
|
||||
ret = QtWidgets.QMessageBox.question(self, translate('OpenLP.ThemeManager', 'Theme Already Exists'),
|
||||
translate('OpenLP.ThemeManager',
|
||||
'Theme %s already exists. Do you want to replace it?')
|
||||
.replace('%s', theme_name),
|
||||
'Theme {name} already exists. '
|
||||
'Do you want to replace it?').format(name=theme_name),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
|
@ -538,7 +542,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
:param file_name:
|
||||
:param directory:
|
||||
"""
|
||||
self.log_debug('Unzipping theme %s' % file_name)
|
||||
self.log_debug('Unzipping theme {name}'.format(name=file_name))
|
||||
theme_zip = None
|
||||
out_file = None
|
||||
file_xml = None
|
||||
|
@ -547,7 +551,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
theme_zip = zipfile.ZipFile(file_name)
|
||||
xml_file = [name for name in theme_zip.namelist() if os.path.splitext(name)[1].lower() == '.xml']
|
||||
if len(xml_file) != 1:
|
||||
self.log_error('Theme contains "%s" XML files' % len(xml_file))
|
||||
self.log_error('Theme contains "{val:d}" XML files'.format(val=len(xml_file)))
|
||||
raise ValidationError
|
||||
xml_tree = ElementTree(element=XML(theme_zip.read(xml_file[0]))).getroot()
|
||||
theme_version = xml_tree.get('version', default=None)
|
||||
|
@ -579,7 +583,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
out_file.write(theme_zip.read(name))
|
||||
out_file.close()
|
||||
except (IOError, zipfile.BadZipfile):
|
||||
self.log_exception('Importing theme from zip failed %s' % file_name)
|
||||
self.log_exception('Importing theme from zip failed {name}'.format(name=file_name))
|
||||
raise ValidationError
|
||||
except ValidationError:
|
||||
critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
|
@ -601,7 +605,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
|
||||
self.log_error('Theme file does not contain XML data %s' % file_name)
|
||||
self.log_error('Theme file does not contain XML data {name}'.format(name=file_name))
|
||||
|
||||
def check_if_theme_exists(self, theme_name):
|
||||
"""
|
||||
|
@ -682,7 +686,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
if os.path.exists(sample_path_name):
|
||||
os.unlink(sample_path_name)
|
||||
frame.save(sample_path_name, 'png')
|
||||
thumb = os.path.join(self.thumb_path, '%s.png' % name)
|
||||
thumb = os.path.join(self.thumb_path, '{name}.png'.format(name=name))
|
||||
create_thumb(sample_path_name, thumb, False)
|
||||
|
||||
def update_preview_images(self):
|
||||
|
@ -760,14 +764,17 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
|||
for plugin in self.plugin_manager.plugins:
|
||||
used_count = plugin.uses_theme(theme)
|
||||
if used_count:
|
||||
plugin_usage = "%s%s" % (plugin_usage, (translate('OpenLP.ThemeManager',
|
||||
'%(count)s time(s) by %(plugin)s') %
|
||||
{'count': used_count, 'plugin': plugin.name}))
|
||||
plugin_usage = "{plug}{text}".format(plug=plugin_usage,
|
||||
text=(translate('OpenLP.ThemeManager',
|
||||
'{count} time(s) by {plugin}'
|
||||
).format(name=used_count,
|
||||
plugin=plugin.name)))
|
||||
plugin_usage = "%s\n" % plugin_usage
|
||||
if plugin_usage:
|
||||
critical_error_message_box(translate('OpenLP.ThemeManager', 'Unable to delete theme'),
|
||||
translate('OpenLP.ThemeManager', 'Theme is currently used \n\n%s') %
|
||||
plugin_usage)
|
||||
translate('OpenLP.ThemeManager',
|
||||
'Theme is currently used \n\n{text}'
|
||||
).format(text=plugin_usage))
|
||||
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -405,8 +405,8 @@ class Ui_ThemeWizard(object):
|
|||
Translate the UI on the fly
|
||||
"""
|
||||
theme_wizard.setWindowTitle(translate('OpenLP.ThemeWizard', 'Theme Wizard'))
|
||||
self.title_label.setText('<span style="font-size:14pt; font-weight:600;">%s</span>' %
|
||||
translate('OpenLP.ThemeWizard', 'Welcome to the Theme Wizard'))
|
||||
text = translate('OpenLP.ThemeWizard', 'Welcome to the Theme Wizard')
|
||||
self.title_label.setText('<span style="font-size:14pt; font-weight:600;">{text}</span>'.format(text=text))
|
||||
self.information_label.setText(
|
||||
translate('OpenLP.ThemeWizard', 'This wizard will help you to create and edit your themes. Click the next '
|
||||
'button below to start the process by setting up your background.'))
|
||||
|
@ -435,9 +435,9 @@ class Ui_ThemeWizard(object):
|
|||
self.gradient_combo_box.setItemText(BackgroundGradientType.LeftBottom,
|
||||
translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
|
||||
self.image_color_label.setText(translate('OpenLP.ThemeWizard', 'Background color:'))
|
||||
self.image_label.setText('%s:' % UiStrings().Image)
|
||||
self.image_label.setText('{text}:'.format(text=UiStrings().Image))
|
||||
self.video_color_label.setText(translate('OpenLP.ThemeWizard', 'Background color:'))
|
||||
self.video_label.setText('%s:' % UiStrings().Video)
|
||||
self.video_label.setText('{text}:'.format(text=UiStrings().Video))
|
||||
self.main_area_page.setTitle(translate('OpenLP.ThemeWizard', 'Main Area Font Details'))
|
||||
self.main_area_page.setSubTitle(translate('OpenLP.ThemeWizard', 'Define the font and display '
|
||||
'characteristics for the Display text'))
|
||||
|
|
|
@ -88,6 +88,7 @@ JAVASCRIPT = """
|
|||
}
|
||||
}
|
||||
"""
|
||||
# TODO: Verify format() with variable templates
|
||||
CSS = """
|
||||
#alert {
|
||||
position: absolute;
|
||||
|
@ -244,6 +245,9 @@ class AlertsPlugin(Plugin):
|
|||
:param frame: The Web frame holding the page.
|
||||
"""
|
||||
align = VerticalType.Names[self.settings_tab.location]
|
||||
frame.evaluateJavaScript('update_css("%s", "%s", "%s", "%s", "%s")' %
|
||||
(align, self.settings_tab.font_face, self.settings_tab.font_size,
|
||||
self.settings_tab.font_color, self.settings_tab.background_color))
|
||||
frame.evaluateJavaScript('update_css("{align}", "{face}", "{size}", "{color}", '
|
||||
'"{background}")'.format(align=align,
|
||||
face=self.settings_tab.font_face,
|
||||
size=self.settings_tab.font_size,
|
||||
color=self.settings_tab.font_color,
|
||||
background=self.settings_tab.background_color))
|
||||
|
|
|
@ -62,7 +62,7 @@ class AlertsManager(OpenLPMixin, RegistryMixin, QtCore.QObject, RegistryProperti
|
|||
|
||||
:param text: The text to display
|
||||
"""
|
||||
self.log_debug('display alert called %s' % text)
|
||||
self.log_debug('display alert called {text}'.format(text=text))
|
||||
if text:
|
||||
self.alert_list.append(text)
|
||||
if self.timer_id != 0:
|
||||
|
|
|
@ -197,5 +197,6 @@ class AlertsTab(SettingsTab):
|
|||
font.setBold(True)
|
||||
font.setPointSize(self.font_size)
|
||||
self.font_preview.setFont(font)
|
||||
self.font_preview.setStyleSheet('background-color: %s; color: %s' % (self.background_color, self.font_color))
|
||||
self.font_preview.setStyleSheet('background-color: {back}; color: {front}'.format(back=self.background_color,
|
||||
front=self.font_color))
|
||||
self.changed = True
|
||||
|
|
|
@ -593,22 +593,27 @@ class BibleImportForm(OpenLPWizard):
|
|||
"""
|
||||
Show the file open dialog for the books CSV file.
|
||||
"""
|
||||
# TODO: Verify format() with varible template
|
||||
self.get_file_name(
|
||||
WizardStrings.OpenTypeFile % WizardStrings.CSV, self.csv_books_edit, 'last directory import', '%s (*.csv)' %
|
||||
translate('BiblesPlugin.ImportWizardForm', 'CSV File'))
|
||||
WizardStrings.OpenTypeFile % WizardStrings.CSV,
|
||||
self.csv_books_edit,
|
||||
'last directory import',
|
||||
'{name} (*.csv)'.format(name=translate('BiblesPlugin.ImportWizardForm', 'CSV File')))
|
||||
|
||||
def on_csv_verses_browse_button_clicked(self):
|
||||
"""
|
||||
Show the file open dialog for the verses CSV file.
|
||||
"""
|
||||
# TODO: Verify format() with variable template
|
||||
self.get_file_name(WizardStrings.OpenTypeFile % WizardStrings.CSV, self.csv_verses_edit,
|
||||
'last directory import', '%s (*.csv)' %
|
||||
translate('BiblesPlugin.ImportWizardForm', 'CSV File'))
|
||||
'last directory import',
|
||||
'{name} (*.csv)'.format(name=translate('BiblesPlugin.ImportWizardForm', 'CSV File')))
|
||||
|
||||
def on_open_song_browse_button_clicked(self):
|
||||
"""
|
||||
Show the file open dialog for the OpenSong file.
|
||||
"""
|
||||
# TODO: Verify format() with variable template
|
||||
self.get_file_name(WizardStrings.OpenTypeFile % WizardStrings.OS, self.open_song_file_edit,
|
||||
'last directory import')
|
||||
|
||||
|
@ -616,6 +621,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
"""
|
||||
Show the file open dialog for the Zefania file.
|
||||
"""
|
||||
# TODO: Verify format() with variable template
|
||||
self.get_file_name(WizardStrings.OpenTypeFile % WizardStrings.ZEF, self.zefania_file_edit,
|
||||
'last directory import')
|
||||
|
||||
|
@ -631,6 +637,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.web_progress_bar.setVisible(True)
|
||||
self.web_progress_bar.setValue(0)
|
||||
proxy_server = self.field('proxy_server')
|
||||
# TODO: Where does critical_error_message_box get %s string from?
|
||||
for (download_type, extractor) in ((WebDownload.Crosswalk, CWExtract(proxy_server)),
|
||||
(WebDownload.BibleGateway, BGExtract(proxy_server)),
|
||||
(WebDownload.Bibleserver, BSExtract(proxy_server))):
|
||||
|
|
|
@ -209,7 +209,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
for number, filename in enumerate(self.files):
|
||||
bible = OldBibleDB(self.media_item, path=self.path, file=filename[0])
|
||||
self.checkBox[number] = QtWidgets.QCheckBox(self.scrollAreaContents)
|
||||
self.checkBox[number].setObjectName('checkBox[%d]' % number)
|
||||
self.checkBox[number].setObjectName('checkBox[{count:d}]'.format(count=number))
|
||||
self.checkBox[number].setText(bible.get_name())
|
||||
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
|
||||
self.formLayout.addWidget(self.checkBox[number])
|
||||
|
@ -364,7 +364,10 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
name = filename[1]
|
||||
self.progress_label.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nUpgrading ...') % (number + 1, max_bibles, name))
|
||||
'Upgrading Bible {count} of {total}: "{name}"\n'
|
||||
'Upgrading ...').format(count=number + 1,
|
||||
total=max_bibles,
|
||||
name=name))
|
||||
self.new_bibles[number] = BibleDB(self.media_item, path=self.path, name=name, file=filename[0])
|
||||
self.new_bibles[number].register(self.plugin.upgrade_wizard)
|
||||
metadata = old_bible.get_metadata()
|
||||
|
@ -394,17 +397,19 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
handler = BSExtract(proxy_server)
|
||||
books = handler.get_books_from_http(meta_data['download_name'])
|
||||
if not books:
|
||||
log.error('Upgrading books from %s - download name: "%s" failed' % (
|
||||
meta_data['download_source'], meta_data['download_name']))
|
||||
log.error('Upgrading books from {uri} - '
|
||||
'download name: "{name}" failed'.format(uri=meta_data['download_source'],
|
||||
name=meta_data['download_name']))
|
||||
self.new_bibles[number].session.close()
|
||||
del self.new_bibles[number]
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Download Error'),
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'To upgrade your Web Bibles an Internet connection is required.'))
|
||||
self.increment_progress_bar(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible %s of %s: "%s"\nFailed') %
|
||||
(number + 1, max_bibles, name), self.progress_bar.maximum() - self.progress_bar.value())
|
||||
text = translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible {count} of {total}: "{name}"\n'
|
||||
'Failed').format(count=number + 1, total=max_bibles, name=name)
|
||||
self.increment_progress_bar(text, self.progress_bar.maximum() - self.progress_bar.value())
|
||||
self.success[number] = False
|
||||
continue
|
||||
bible = BiblesResourcesDB.get_webbible(
|
||||
|
@ -416,12 +421,13 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
else:
|
||||
language_id = self.new_bibles[number].get_language(name)
|
||||
if not language_id:
|
||||
log.warning('Upgrading from "%s" failed' % filename[0])
|
||||
log.warning('Upgrading from "{name}" failed'.format(name=filename[0]))
|
||||
self.new_bibles[number].session.close()
|
||||
del self.new_bibles[number]
|
||||
self.increment_progress_bar(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed') % (number + 1, max_bibles, name),
|
||||
'Upgrading Bible {count} of {total}: "{name}"\n'
|
||||
'Failed').format(count=number + 1, total=max_bibles, name=name),
|
||||
self.progress_bar.maximum() - self.progress_bar.value())
|
||||
self.success[number] = False
|
||||
continue
|
||||
|
@ -432,13 +438,15 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
break
|
||||
self.increment_progress_bar(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nUpgrading %s ...') %
|
||||
(number + 1, max_bibles, name, book))
|
||||
'Upgrading Bible {count} of {total}: "{name}"\n'
|
||||
'Upgrading {book} ...').format(count=number + 1, total=max_bibles,
|
||||
name=name, book=book))
|
||||
book_ref_id = self.new_bibles[number].\
|
||||
get_book_ref_id_by_name(book, len(books), language_id)
|
||||
if not book_ref_id:
|
||||
log.warning('Upgrading books from %s - download name: "%s" aborted by user' % (
|
||||
meta_data['download_source'], meta_data['download_name']))
|
||||
log.warning('Upgrading books from {source} - download name: "{name}" '
|
||||
'aborted by user'.format(source=meta_data['download_source'],
|
||||
name=meta_data['download_name']))
|
||||
self.new_bibles[number].session.close()
|
||||
del self.new_bibles[number]
|
||||
self.success[number] = False
|
||||
|
@ -450,7 +458,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
if oldbook:
|
||||
verses = old_bible.get_verses(oldbook['id'])
|
||||
if not verses:
|
||||
log.warning('No verses found to import for book "%s"', book)
|
||||
log.warning('No verses found to import for book "{book}"'.format(book=book))
|
||||
continue
|
||||
for verse in verses:
|
||||
if self.stop_import_flag:
|
||||
|
@ -465,12 +473,13 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
if not language_id:
|
||||
language_id = self.new_bibles[number].get_language(name)
|
||||
if not language_id:
|
||||
log.warning('Upgrading books from "%s" failed' % name)
|
||||
log.warning('Upgrading books from "{name}" failed'.format(name=name))
|
||||
self.new_bibles[number].session.close()
|
||||
del self.new_bibles[number]
|
||||
self.increment_progress_bar(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed') % (number + 1, max_bibles, name),
|
||||
'Upgrading Bible {count} of {total}: "{name}"\n'
|
||||
'Failed').format(count=number + 1, total=max_bibles, name=name),
|
||||
self.progress_bar.maximum() - self.progress_bar.value())
|
||||
self.success[number] = False
|
||||
continue
|
||||
|
@ -482,11 +491,12 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
break
|
||||
self.increment_progress_bar(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nUpgrading %s ...') %
|
||||
(number + 1, max_bibles, name, book['name']))
|
||||
'Upgrading Bible {count} of {total}: "{name}"\n'
|
||||
'Upgrading {book} ...').format(count=number + 1, total=max_bibles,
|
||||
name=name, book=book['name']))
|
||||
book_ref_id = self.new_bibles[number].get_book_ref_id_by_name(book['name'], len(books), language_id)
|
||||
if not book_ref_id:
|
||||
log.warning('Upgrading books from %s " failed - aborted by user' % name)
|
||||
log.warning('Upgrading books from {name} " failed - aborted by user'.format(name=name))
|
||||
self.new_bibles[number].session.close()
|
||||
del self.new_bibles[number]
|
||||
self.success[number] = False
|
||||
|
@ -496,7 +506,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
book_details['testament_id'])
|
||||
verses = old_bible.get_verses(book['id'])
|
||||
if not verses:
|
||||
log.warning('No verses found to import for book "%s"', book['name'])
|
||||
log.warning('No verses found to import for book "{book}"'.format(book=book['name']))
|
||||
self.new_bibles[number].delete_book(db_book)
|
||||
continue
|
||||
for verse in verses:
|
||||
|
@ -510,14 +520,16 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
if not self.success.get(number, True):
|
||||
self.increment_progress_bar(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed') % (number + 1, max_bibles, name),
|
||||
'Upgrading Bible {count} of {total}: "{name}"\n'
|
||||
'Failed').format(count=number + 1, total=max_bibles, name=name),
|
||||
self.progress_bar.maximum() - self.progress_bar.value())
|
||||
else:
|
||||
self.success[number] = True
|
||||
self.new_bibles[number].save_meta('name', name)
|
||||
self.increment_progress_bar(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nComplete') % (number + 1, max_bibles, name))
|
||||
'Upgrading Bible {count} of {total}: "{name}"\n'
|
||||
'Complete').format(count=number + 1, total=max_bibles, name=name))
|
||||
if number in self.new_bibles:
|
||||
self.new_bibles[number].session.close()
|
||||
# Close the last bible's connection if possible.
|
||||
|
@ -540,20 +552,22 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
# Copy not upgraded bible back.
|
||||
shutil.move(os.path.join(self.temp_dir, filename[0]), self.path)
|
||||
if failed_import > 0:
|
||||
failed_import_text = translate('BiblesPlugin.UpgradeWizardForm', ', %s failed') % failed_import
|
||||
failed_import_text = translate('BiblesPlugin.UpgradeWizardForm',
|
||||
', {name} failed').format(name=failed_import)
|
||||
else:
|
||||
failed_import_text = ''
|
||||
if successful_import > 0:
|
||||
if self.includeWebBible:
|
||||
self.progress_label.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible(s): %(success)d successful%(failed_text)s\nPlease note that verses '
|
||||
'from Web Bibles will be downloaded on demand and so an Internet connection is required.')
|
||||
% {'success': successful_import, 'failed_text': failed_import_text})
|
||||
'Upgrading Bible(s): {count:d} successful{failed}\nPlease note that verses '
|
||||
'from Web Bibles will be downloaded on demand and so an Internet connection is required.'
|
||||
).format(count=successful_import, failed=failed_import_text))
|
||||
else:
|
||||
self.progress_label.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible(s): %s successful%s') % (
|
||||
successful_import, failed_import_text))
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible(s): {count:d} successful{failed}').format(count=successful_import,
|
||||
failed=failed_import_text))
|
||||
else:
|
||||
self.progress_label.setText(translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade failed.'))
|
||||
# Remove temp directory.
|
||||
|
|
|
@ -103,9 +103,11 @@ class Ui_EditBibleDialog(object):
|
|||
self.book_name_edit = {}
|
||||
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[%s]' % book['abbreviation'])
|
||||
self.book_name_label[book['abbreviation']].setObjectName(
|
||||
'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[%s]' % book['abbreviation'])
|
||||
self.book_name_edit[book['abbreviation']].setObjectName(
|
||||
'book_name_edit[{name}]'.format(name=book['abbreviation']))
|
||||
self.book_name_widget_layout.addRow(
|
||||
self.book_name_label[book['abbreviation']],
|
||||
self.book_name_edit[book['abbreviation']])
|
||||
|
@ -148,4 +150,5 @@ class Ui_EditBibleDialog(object):
|
|||
self.bible_tab_widget.indexOf(self.book_name_tab),
|
||||
translate('SongsPlugin.EditBibleForm', 'Custom Book Names'))
|
||||
for book in BiblesResourcesDB.get_books():
|
||||
self.book_name_label[book['abbreviation']].setText('%s:' % str(self.book_names[book['abbreviation']]))
|
||||
self.book_name_label[book['abbreviation']].setText(
|
||||
'{text}:'.format(text=self.book_names[book['abbreviation']]))
|
||||
|
|
|
@ -39,7 +39,7 @@ class EditBibleForm(QtWidgets.QDialog, Ui_EditBibleDialog, RegistryProperties):
|
|||
"""
|
||||
Class to manage the editing of a bible
|
||||
"""
|
||||
log.info('%s EditBibleForm loaded', __name__)
|
||||
log.info('{name} EditBibleForm loaded'.format(name=__name__))
|
||||
|
||||
def __init__(self, media_item, parent, manager):
|
||||
"""
|
||||
|
@ -168,16 +168,17 @@ class EditBibleForm(QtWidgets.QDialog, Ui_EditBibleDialog, RegistryProperties):
|
|||
self.book_name_edit[abbreviation].setFocus()
|
||||
critical_error_message_box(
|
||||
UiStrings().EmptyField,
|
||||
translate('BiblesPlugin.BibleEditForm', 'You need to specify a book name for "%s".') %
|
||||
self.book_names[abbreviation])
|
||||
translate('BiblesPlugin.BibleEditForm',
|
||||
'You need to specify a book name for "{text}".').format(text=self.book_names[abbreviation]))
|
||||
return False
|
||||
elif not book_regex.match(new_book_name):
|
||||
self.book_name_edit[abbreviation].setFocus()
|
||||
critical_error_message_box(
|
||||
UiStrings().EmptyField,
|
||||
translate('BiblesPlugin.BibleEditForm',
|
||||
'The book name "%s" is not correct.\nNumbers can only be used at the beginning and must\nbe '
|
||||
'followed by one or more non-numeric characters.') % new_book_name)
|
||||
'The book name "{name}" is not correct.\n'
|
||||
'Numbers can only be used at the beginning and must\nbe '
|
||||
'followed by one or more non-numeric characters.').format(name=new_book_name))
|
||||
return False
|
||||
for abbr, book in self.books.items():
|
||||
if book:
|
||||
|
@ -187,7 +188,7 @@ class EditBibleForm(QtWidgets.QDialog, Ui_EditBibleDialog, RegistryProperties):
|
|||
self.book_name_edit[abbreviation].setFocus()
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.BibleEditForm', 'Duplicate Book Name'),
|
||||
translate('BiblesPlugin.BibleEditForm', 'The Book Name "%s" has been entered more than once.')
|
||||
% new_book_name)
|
||||
translate('BiblesPlugin.BibleEditForm',
|
||||
'The Book Name "{name}" has been entered more than once.').format(name=new_book_name))
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -86,7 +86,7 @@ class CSVBible(BibleDB):
|
|||
success = True
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.error('Importing books from "%s" failed' % self.filename)
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.filename))
|
||||
return False
|
||||
books_file = None
|
||||
book_list = {}
|
||||
|
@ -98,11 +98,11 @@ class CSVBible(BibleDB):
|
|||
for line in books_reader:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing books... %s')
|
||||
% line[2])
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible',
|
||||
'Importing books... {text}').format(text=line[2]))
|
||||
book_ref_id = self.get_book_ref_id_by_name(line[2], 67, language_id)
|
||||
if not book_ref_id:
|
||||
log.error('Importing books from "%s" failed' % self.books_file)
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.books_file))
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
self.create_book(line[2], book_ref_id, book_details['testament_id'])
|
||||
|
@ -134,9 +134,11 @@ class CSVBible(BibleDB):
|
|||
if book_ptr != line_book:
|
||||
book = self.get_book(line_book)
|
||||
book_ptr = book.name
|
||||
# TODO: Check out this conversion in translations
|
||||
self.wizard.increment_progress_bar(
|
||||
translate('BiblesPlugin.CSVBible',
|
||||
'Importing verses from %s...' % book.name, 'Importing verses from <book name>...'))
|
||||
'Importing verses from {name}...'.format(name=book.name),
|
||||
'Importing verses from <book name>...'))
|
||||
self.session.commit()
|
||||
verse_text = line[3]
|
||||
self.create_verse(book.id, line[1], line[2], verse_text)
|
||||
|
|
|
@ -185,7 +185,7 @@ class BibleDB(Manager, RegistryProperties):
|
|||
:param testament: *Defaults to 1.* The testament_reference_id from
|
||||
bibles_resources.sqlite of the testament this book belongs to.
|
||||
"""
|
||||
log.debug('BibleDB.create_book("%s", "%s")' % (name, bk_ref_id))
|
||||
log.debug('BibleDB.create_book("{name}", "{number}")'.format(name=name, number=bk_ref_id))
|
||||
book = Book.populate(name=name, book_reference_id=bk_ref_id, testament_reference_id=testament)
|
||||
self.save_object(book)
|
||||
return book
|
||||
|
@ -196,7 +196,7 @@ class BibleDB(Manager, RegistryProperties):
|
|||
|
||||
:param book: The book object
|
||||
"""
|
||||
log.debug('BibleDB.update_book("%s")' % book.name)
|
||||
log.debug('BibleDB.update_book("{name}")'.format(name=book.name))
|
||||
return self.save_object(book)
|
||||
|
||||
def delete_book(self, db_book):
|
||||
|
@ -205,7 +205,7 @@ class BibleDB(Manager, RegistryProperties):
|
|||
|
||||
:param db_book: The book object.
|
||||
"""
|
||||
log.debug('BibleDB.delete_book("%s")' % db_book.name)
|
||||
log.debug('BibleDB.delete_book("{name}")'.format(name=db_book.name))
|
||||
if self.delete_object(Book, db_book.id):
|
||||
return True
|
||||
return False
|
||||
|
@ -219,7 +219,7 @@ class BibleDB(Manager, RegistryProperties):
|
|||
:param text_list: A dict of the verses to be inserted. The key is the verse number, and the value is the
|
||||
verse text.
|
||||
"""
|
||||
log.debug('BibleDBcreate_chapter("%s", "%s")' % (book_id, chapter))
|
||||
log.debug('BibleDBcreate_chapter("{number}", "{chapter}")'.format(number=book_id, chapter=chapter))
|
||||
# Text list has book and chapter as first two elements of the array.
|
||||
for verse_number, verse_text in text_list.items():
|
||||
verse = Verse.populate(
|
||||
|
@ -266,7 +266,7 @@ class BibleDB(Manager, RegistryProperties):
|
|||
"""
|
||||
if not isinstance(value, str):
|
||||
value = str(value)
|
||||
log.debug('BibleDB.save_meta("%s/%s")' % (key, value))
|
||||
log.debug('BibleDB.save_meta("{key}/{val}")'.format(key=key, val=value))
|
||||
meta = self.get_object(BibleMeta, key)
|
||||
if meta:
|
||||
meta.value = value
|
||||
|
@ -280,7 +280,7 @@ class BibleDB(Manager, RegistryProperties):
|
|||
|
||||
:param book: The name of the book to return.
|
||||
"""
|
||||
log.debug('BibleDB.get_book("%s")' % book)
|
||||
log.debug('BibleDB.get_book("{book}")'.format(book=book))
|
||||
return self.get_object_filtered(Book, Book.name.like(book + '%'))
|
||||
|
||||
def get_books(self):
|
||||
|
@ -297,11 +297,11 @@ class BibleDB(Manager, RegistryProperties):
|
|||
|
||||
:param ref_id: The reference id of the book to return.
|
||||
"""
|
||||
log.debug('BibleDB.get_book_by_book_ref_id("%s")' % ref_id)
|
||||
log.debug('BibleDB.get_book_by_book_ref_id("{ref}")'.format(ref=ref_id))
|
||||
return self.get_object_filtered(Book, Book.book_reference_id.like(ref_id))
|
||||
|
||||
def get_book_ref_id_by_name(self, book, maxbooks, language_id=None):
|
||||
log.debug('BibleDB.get_book_ref_id_by_name:("%s", "%s")' % (book, language_id))
|
||||
log.debug('BibleDB.get_book_ref_id_by_name:("{book}", "{lang}")'.format(book=book, lang=language_id))
|
||||
book_id = None
|
||||
if BiblesResourcesDB.get_book(book, True):
|
||||
book_temp = BiblesResourcesDB.get_book(book, True)
|
||||
|
@ -327,13 +327,14 @@ class BibleDB(Manager, RegistryProperties):
|
|||
:param book: The name of the book, according to the selected language.
|
||||
:param language_selection: The language selection the user has chosen in the settings section of the Bible.
|
||||
"""
|
||||
log.debug('get_book_ref_id_by_localised_name("%s", "%s")' % (book, language_selection))
|
||||
log.debug('get_book_ref_id_by_localised_name("{book}", "{lang}")'.format(book=book, lang=language_selection))
|
||||
from openlp.plugins.bibles.lib import LanguageSelection, BibleStrings
|
||||
book_names = BibleStrings().BookNames
|
||||
# escape reserved characters
|
||||
book_escaped = book
|
||||
for character in RESERVED_CHARACTERS:
|
||||
book_escaped = book_escaped.replace(character, '\\' + character)
|
||||
# TODO: Verify regex patters before using format()
|
||||
regex_book = re.compile('\s*%s\s*' % '\s*'.join(
|
||||
book_escaped.split()), re.UNICODE | re.IGNORECASE)
|
||||
if language_selection == LanguageSelection.Bible:
|
||||
|
@ -374,14 +375,14 @@ class BibleDB(Manager, RegistryProperties):
|
|||
[('35', 1, 1, 1), ('35', 2, 2, 3)]
|
||||
:param show_error:
|
||||
"""
|
||||
log.debug('BibleDB.get_verses("%s")' % reference_list)
|
||||
log.debug('BibleDB.get_verses("{ref}")'.format(ref=reference_list))
|
||||
verse_list = []
|
||||
book_error = False
|
||||
for book_id, chapter, start_verse, end_verse in reference_list:
|
||||
db_book = self.get_book_by_book_ref_id(book_id)
|
||||
if db_book:
|
||||
book_id = db_book.book_reference_id
|
||||
log.debug('Book name corrected to "%s"' % db_book.name)
|
||||
log.debug('Book name corrected to "{book}"'.format(book=db_book.name))
|
||||
if end_verse == -1:
|
||||
end_verse = self.get_verse_count(book_id, chapter)
|
||||
verses = self.session.query(Verse) \
|
||||
|
@ -393,7 +394,7 @@ class BibleDB(Manager, RegistryProperties):
|
|||
.all()
|
||||
verse_list.extend(verses)
|
||||
else:
|
||||
log.debug('OpenLP failed to find book with id "%s"' % book_id)
|
||||
log.debug('OpenLP failed to find book with id "{book}"'.format(book=book_id))
|
||||
book_error = True
|
||||
if book_error and show_error:
|
||||
critical_error_message_box(
|
||||
|
@ -412,8 +413,9 @@ class BibleDB(Manager, RegistryProperties):
|
|||
contains spaces, it will split apart and AND'd on the list of
|
||||
values.
|
||||
"""
|
||||
log.debug('BibleDB.verse_search("%s")' % text)
|
||||
log.debug('BibleDB.verse_search("{text}")'.format(text=text))
|
||||
verses = self.session.query(Verse)
|
||||
# TODO: Find out what this is doing before converting to format()
|
||||
if text.find(',') > -1:
|
||||
keywords = ['%%%s%%' % keyword.strip() for keyword in text.split(',')]
|
||||
or_clause = [Verse.text.like(keyword) for keyword in keywords]
|
||||
|
@ -431,7 +433,7 @@ class BibleDB(Manager, RegistryProperties):
|
|||
|
||||
:param book: The book object to get the chapter count for.
|
||||
"""
|
||||
log.debug('BibleDB.get_chapter_count("%s")' % book.name)
|
||||
log.debug('BibleDB.get_chapter_count("{book}")'.format(book=book.name))
|
||||
count = self.session.query(func.max(Verse.chapter)).join(Book).filter(
|
||||
Book.book_reference_id == book.book_reference_id).scalar()
|
||||
if not count:
|
||||
|
@ -445,7 +447,7 @@ class BibleDB(Manager, RegistryProperties):
|
|||
:param book_ref_id: The book reference id.
|
||||
:param chapter: The chapter to get the verse count for.
|
||||
"""
|
||||
log.debug('BibleDB.get_verse_count("%s", "%s")' % (book_ref_id, chapter))
|
||||
log.debug('BibleDB.get_verse_count("{ref}", "{chapter}")'.format(ref=book_ref_id, chapter=chapter))
|
||||
count = self.session.query(func.max(Verse.verse)).join(Book) \
|
||||
.filter(Book.book_reference_id == book_ref_id) \
|
||||
.filter(Verse.chapter == chapter) \
|
||||
|
@ -551,7 +553,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
:param name: The name or abbreviation of the book.
|
||||
:param lower: True if the comparison should be only lowercase
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_book("%s")' % name)
|
||||
log.debug('BiblesResourcesDB.get_book("{name}")'.format(name=name))
|
||||
if not isinstance(name, str):
|
||||
name = str(name)
|
||||
if lower:
|
||||
|
@ -580,7 +582,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
|
||||
:param string: The string to search for in the book names or abbreviations.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_book_like("%s")' % string)
|
||||
log.debug('BiblesResourcesDB.get_book_like("{text}")'.format(text=string))
|
||||
if not isinstance(string, str):
|
||||
name = str(string)
|
||||
books = BiblesResourcesDB.run_sql(
|
||||
|
@ -605,7 +607,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
|
||||
:param book_id: The id of the book.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_book_by_id("%s")' % book_id)
|
||||
log.debug('BiblesResourcesDB.get_book_by_id("{book}")'.format(book=book_id))
|
||||
if not isinstance(book_id, int):
|
||||
book_id = int(book_id)
|
||||
books = BiblesResourcesDB.run_sql(
|
||||
|
@ -629,7 +631,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
:param book_ref_id: The id of a book.
|
||||
:param chapter: The chapter number.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_chapter("%s", "%s")' % (book_ref_id, chapter))
|
||||
log.debug('BiblesResourcesDB.get_chapter("{book}", "{ref}")'.format(book=book_ref_id, ref=chapter))
|
||||
if not isinstance(chapter, int):
|
||||
chapter = int(chapter)
|
||||
chapters = BiblesResourcesDB.run_sql(
|
||||
|
@ -652,7 +654,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
|
||||
:param book_ref_id: The id of the book.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_chapter_count("%s")' % book_ref_id)
|
||||
log.debug('BiblesResourcesDB.get_chapter_count("{ref}")'.format(ref=book_ref_id))
|
||||
details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
if details:
|
||||
return details['chapters']
|
||||
|
@ -666,7 +668,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
:param book_ref_id: The id of the book.
|
||||
:param chapter: The number of the chapter.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_verse_count("%s", "%s")' % (book_ref_id, chapter))
|
||||
log.debug('BiblesResourcesDB.get_verse_count("{ref}", "{chapter}")'.format(ref=book_ref_id, chapter=chapter))
|
||||
details = BiblesResourcesDB.get_chapter(book_ref_id, chapter)
|
||||
if details:
|
||||
return details['verse_count']
|
||||
|
@ -679,7 +681,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
|
||||
:param source: The name or abbreviation of the book.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_download_source("%s")' % source)
|
||||
log.debug('BiblesResourcesDB.get_download_source("{source}")'.format(source=source))
|
||||
if not isinstance(source, str):
|
||||
source = str(source)
|
||||
source = source.title()
|
||||
|
@ -700,7 +702,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
|
||||
:param source: The source of the web_bible.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_webbibles("%s")' % source)
|
||||
log.debug('BiblesResourcesDB.get_webbibles("{source}")'.format(source=source))
|
||||
if not isinstance(source, str):
|
||||
source = str(source)
|
||||
source = BiblesResourcesDB.get_download_source(source)
|
||||
|
@ -725,7 +727,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
:param abbreviation: The abbreviation of the web_bible.
|
||||
:param source: The source of the web_bible.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_webbibles("%s", "%s")' % (abbreviation, source))
|
||||
log.debug('BiblesResourcesDB.get_webbibles("{text}", "{source}")'.format(text=abbreviation, source=source))
|
||||
if not isinstance(abbreviation, str):
|
||||
abbreviation = str(abbreviation)
|
||||
if not isinstance(source, str):
|
||||
|
@ -753,7 +755,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
:param name: The name to search the id.
|
||||
:param language_id: The language_id for which language should be searched
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_alternative_book_name("%s", "%s")' % (name, language_id))
|
||||
log.debug('BiblesResourcesDB.get_alternative_book_name("{name}", "{lang}")'.format(name=name, lang=language_id))
|
||||
if language_id:
|
||||
books = BiblesResourcesDB.run_sql(
|
||||
'SELECT book_reference_id, name FROM alternative_book_names WHERE language_id = ? ORDER BY id',
|
||||
|
@ -772,7 +774,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
|||
|
||||
:param name: The name or abbreviation of the language.
|
||||
"""
|
||||
log.debug('BiblesResourcesDB.get_language("%s")' % name)
|
||||
log.debug('BiblesResourcesDB.get_language("{name}")'.format(name=name))
|
||||
if not isinstance(name, str):
|
||||
name = str(name)
|
||||
language = BiblesResourcesDB.run_sql(
|
||||
|
@ -868,7 +870,7 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager):
|
|||
:param name: The name to search the id.
|
||||
:param language_id: The language_id for which language should be searched
|
||||
"""
|
||||
log.debug('AlternativeBookNamesDB.get_book_reference_id("%s", "%s")' % (name, language_id))
|
||||
log.debug('AlternativeBookNamesDB.get_book_reference_id("{name}", "{ref}")'.format(name=name, ref=language_id))
|
||||
if language_id:
|
||||
books = AlternativeBookNamesDB.run_sql(
|
||||
'SELECT book_reference_id, name FROM alternative_book_names WHERE language_id = ?', (language_id, ))
|
||||
|
@ -889,8 +891,8 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager):
|
|||
:param book_reference_id: The book_reference_id of the book.
|
||||
:param language_id: The language to which the alternative book name belong.
|
||||
"""
|
||||
log.debug('AlternativeBookNamesDB.create_alternative_book_name("%s", "%s", "%s")' %
|
||||
(name, book_reference_id, language_id))
|
||||
log.debug('AlternativeBookNamesDB.create_alternative_book_name("{name}", '
|
||||
'"{ref}", "{lang}")'.format(name=name, ref=book_reference_id, lang=language_id))
|
||||
return AlternativeBookNamesDB.run_sql(
|
||||
'INSERT INTO alternative_book_names(book_reference_id, language_id, name) '
|
||||
'VALUES (?, ?, ?)', (book_reference_id, language_id, name), True)
|
||||
|
|
|
@ -90,7 +90,7 @@ class BGExtract(RegistryProperties):
|
|||
Extract verses from BibleGateway
|
||||
"""
|
||||
def __init__(self, proxy_url=None):
|
||||
log.debug('BGExtract.init("%s")', proxy_url)
|
||||
log.debug('BGExtract.init("{url}")'.format(url=proxy_url))
|
||||
self.proxy_url = proxy_url
|
||||
socket.setdefaulttimeout(30)
|
||||
|
||||
|
@ -188,7 +188,7 @@ class BGExtract(RegistryProperties):
|
|||
if len(verse_parts) > 1:
|
||||
verse = int(verse_parts[0])
|
||||
except TypeError:
|
||||
log.warning('Illegal verse number: %s', str(verse))
|
||||
log.warning('Illegal verse number: {verse:d}'.format(verse=verse))
|
||||
verses.append((verse, text))
|
||||
verse_list = {}
|
||||
for verse, text in verses[::-1]:
|
||||
|
@ -221,7 +221,7 @@ class BGExtract(RegistryProperties):
|
|||
if len(verse_parts) > 1:
|
||||
clean_verse_num = int(verse_parts[0])
|
||||
except TypeError:
|
||||
log.warning('Illegal verse number: %s', str(raw_verse_num))
|
||||
log.warning('Illegal verse number: {verse:d}'.format(verse=raw_verse_num))
|
||||
if clean_verse_num:
|
||||
verse_text = raw_verse_num.next_element
|
||||
part = raw_verse_num.next_element.next_element
|
||||
|
@ -244,11 +244,15 @@ class BGExtract(RegistryProperties):
|
|||
:param book_name: Name of the Book.
|
||||
:param chapter: Chapter number.
|
||||
"""
|
||||
log.debug('BGExtract.get_bible_chapter("%s", "%s", "%s")', version, book_name, chapter)
|
||||
log.debug('BGExtract.get_bible_chapter("{version}", "{name}", "{chapter}")'.format(version=version,
|
||||
name=book_name,
|
||||
chapter=chapter))
|
||||
url_book_name = urllib.parse.quote(book_name.encode("utf-8"))
|
||||
url_params = 'search=%s+%s&version=%s' % (url_book_name, chapter, version)
|
||||
url_params = 'search={name}+{chapter}&version={version}'.format(name=url_book_name,
|
||||
chapter=chapter,
|
||||
version=version)
|
||||
soup = get_soup_for_bible_ref(
|
||||
'http://legacy.biblegateway.com/passage/?%s' % url_params,
|
||||
'http://legacy.biblegateway.com/passage/?{url}'.format(url=url_params),
|
||||
pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='')
|
||||
if not soup:
|
||||
return None
|
||||
|
@ -257,7 +261,7 @@ class BGExtract(RegistryProperties):
|
|||
return None
|
||||
self._clean_soup(div)
|
||||
span_list = div.find_all('span', 'text')
|
||||
log.debug('Span list: %s', span_list)
|
||||
log.debug('Span list: {span}'.format(span=span_list))
|
||||
if not span_list:
|
||||
# If we don't get any spans then we must have the old HTML format
|
||||
verse_list = self._extract_verses_old(div)
|
||||
|
@ -275,9 +279,9 @@ class BGExtract(RegistryProperties):
|
|||
|
||||
:param version: The version of the Bible like NIV for New International Version
|
||||
"""
|
||||
log.debug('BGExtract.get_books_from_http("%s")', version)
|
||||
url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '%s' % version})
|
||||
reference_url = 'http://legacy.biblegateway.com/versions/?%s#books' % url_params
|
||||
log.debug('BGExtract.get_books_from_http("{version}")'.format(version=version))
|
||||
url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '{version}'.format(version=version)})
|
||||
reference_url = 'http://legacy.biblegateway.com/versions/?{url}#books'.format(url=url_params)
|
||||
page = get_web_page(reference_url)
|
||||
if not page:
|
||||
send_error_message('download')
|
||||
|
@ -353,7 +357,7 @@ class BSExtract(RegistryProperties):
|
|||
Extract verses from Bibleserver.com
|
||||
"""
|
||||
def __init__(self, proxy_url=None):
|
||||
log.debug('BSExtract.init("%s")', proxy_url)
|
||||
log.debug('BSExtract.init("{url}")'.format(url=proxy_url))
|
||||
self.proxy_url = proxy_url
|
||||
socket.setdefaulttimeout(30)
|
||||
|
||||
|
@ -365,10 +369,14 @@ class BSExtract(RegistryProperties):
|
|||
:param book_name: Text name of bible book e.g. Genesis, 1. John, 1John or Offenbarung
|
||||
:param chapter: Chapter number
|
||||
"""
|
||||
log.debug('BSExtract.get_bible_chapter("%s", "%s", "%s")', version, book_name, chapter)
|
||||
log.debug('BSExtract.get_bible_chapter("{version}", "{book}", "{chapter}")'.format(version=version,
|
||||
book=book_name,
|
||||
chapter=chapter))
|
||||
url_version = urllib.parse.quote(version.encode("utf-8"))
|
||||
url_book_name = urllib.parse.quote(book_name.encode("utf-8"))
|
||||
chapter_url = 'http://m.bibleserver.com/text/%s/%s%d' % (url_version, url_book_name, chapter)
|
||||
chapter_url = 'http://m.bibleserver.com/text/{version}/{name}{chapter:d}'.format(version=url_version,
|
||||
name=url_book_name,
|
||||
chapter=chapter)
|
||||
header = ('Accept-Language', 'en')
|
||||
soup = get_soup_for_bible_ref(chapter_url, header)
|
||||
if not soup:
|
||||
|
@ -393,9 +401,9 @@ class BSExtract(RegistryProperties):
|
|||
|
||||
:param version: The version of the Bible like NIV for New International Version
|
||||
"""
|
||||
log.debug('BSExtract.get_books_from_http("%s")', version)
|
||||
log.debug('BSExtract.get_books_from_http("{version}")'.format(version=version))
|
||||
url_version = urllib.parse.quote(version.encode("utf-8"))
|
||||
chapter_url = 'http://m.bibleserver.com/overlay/selectBook?translation=%s' % url_version
|
||||
chapter_url = 'http://m.bibleserver.com/overlay/selectBook?translation={version}'.format(version=url_version)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
|
@ -450,7 +458,7 @@ class CWExtract(RegistryProperties):
|
|||
Extract verses from CrossWalk/BibleStudyTools
|
||||
"""
|
||||
def __init__(self, proxy_url=None):
|
||||
log.debug('CWExtract.init("%s")', proxy_url)
|
||||
log.debug('CWExtract.init("{url}")'.format(url=proxy_url))
|
||||
self.proxy_url = proxy_url
|
||||
socket.setdefaulttimeout(30)
|
||||
|
||||
|
@ -462,11 +470,15 @@ class CWExtract(RegistryProperties):
|
|||
:param book_name: Text name of in english e.g. 'gen' for Genesis
|
||||
:param chapter: Chapter number
|
||||
"""
|
||||
log.debug('CWExtract.get_bible_chapter("%s", "%s", "%s")', version, book_name, chapter)
|
||||
log.debug('CWExtract.get_bible_chapter("{version}", "{book}", "{chapter}")'.format(version=version,
|
||||
book=book_name,
|
||||
chapter=chapter))
|
||||
url_book_name = book_name.replace(' ', '-')
|
||||
url_book_name = url_book_name.lower()
|
||||
url_book_name = urllib.parse.quote(url_book_name.encode("utf-8"))
|
||||
chapter_url = 'http://www.biblestudytools.com/%s/%s/%s.html' % (version, url_book_name, chapter)
|
||||
chapter_url = 'http://www.biblestudytools.com/{version}/{book}/{chapter}.html'.format(version=version,
|
||||
book=url_book_name,
|
||||
chapter=chapter)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
|
@ -499,8 +511,8 @@ class CWExtract(RegistryProperties):
|
|||
|
||||
:param version: The version of the bible like NIV for New International Version
|
||||
"""
|
||||
log.debug('CWExtract.get_books_from_http("%s")', version)
|
||||
chapter_url = 'http://www.biblestudytools.com/%s/' % version
|
||||
log.debug('CWExtract.get_books_from_http("{version}")'.format(version=version))
|
||||
chapter_url = 'http://www.biblestudytools.com/{version}/'.format(version=version)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
|
@ -559,7 +571,7 @@ class CWExtract(RegistryProperties):
|
|||
|
||||
|
||||
class HTTPBible(BibleDB, RegistryProperties):
|
||||
log.info('%s HTTPBible loaded', __name__)
|
||||
log.info('{name} HTTPBible loaded'.format(name=__name__))
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
"""
|
||||
|
@ -615,8 +627,8 @@ class HTTPBible(BibleDB, RegistryProperties):
|
|||
handler = BSExtract(self.proxy_server)
|
||||
books = handler.get_books_from_http(self.download_name)
|
||||
if not books:
|
||||
log.error('Importing books from %s - download name: "%s" failed' %
|
||||
(self.download_source, self.download_name))
|
||||
log.error('Importing books from {source} - download name: "{name}" '
|
||||
'failed'.format(source=self.download_source, name=self.download_name))
|
||||
return False
|
||||
self.wizard.progress_bar.setMaximum(len(books) + 2)
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.HTTPBible', 'Registering Language...'))
|
||||
|
@ -625,21 +637,24 @@ class HTTPBible(BibleDB, RegistryProperties):
|
|||
else:
|
||||
self.language_id = self.get_language(bible_name)
|
||||
if not self.language_id:
|
||||
log.error('Importing books from %s failed' % self.filename)
|
||||
log.error('Importing books from {name} failed'.format(name=self.filename))
|
||||
return False
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
self.wizard.increment_progress_bar(translate(
|
||||
'BiblesPlugin.HTTPBible', 'Importing %s...', 'Importing <book name>...') % book)
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.HTTPBible',
|
||||
'Importing {book}...',
|
||||
'Importing <book name>...').format(book=book))
|
||||
book_ref_id = self.get_book_ref_id_by_name(book, len(books), self.language_id)
|
||||
if not book_ref_id:
|
||||
log.error('Importing books from %s - download name: "%s" failed' %
|
||||
(self.download_source, self.download_name))
|
||||
log.error('Importing books from {source} - download name: "{name}" '
|
||||
'failed'.format(source=self.download_source, name=self.download_name))
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
log.debug('Book details: Name:%s; id:%s; testament_id:%s',
|
||||
book, book_ref_id, book_details['testament_id'])
|
||||
log.debug('Book details: Name:{book}; id:{ref}; '
|
||||
'testament_id:{detail}'.format(book=book,
|
||||
ref=book_ref_id,
|
||||
detail=book_details['testament_id']))
|
||||
self.create_book(book, book_ref_id, book_details['testament_id'])
|
||||
if self.stop_import_flag:
|
||||
return False
|
||||
|
@ -664,7 +679,7 @@ class HTTPBible(BibleDB, RegistryProperties):
|
|||
|
||||
[('35', 1, 1, 1), ('35', 2, 2, 3)]
|
||||
"""
|
||||
log.debug('HTTPBible.get_verses("%s")', reference_list)
|
||||
log.debug('HTTPBible.get_verses("{ref}")'.format(ref=reference_list))
|
||||
for reference in reference_list:
|
||||
book_id = reference[0]
|
||||
db_book = self.get_book_by_book_ref_id(book_id)
|
||||
|
@ -698,8 +713,8 @@ class HTTPBible(BibleDB, RegistryProperties):
|
|||
"""
|
||||
Receive the request and call the relevant handler methods.
|
||||
"""
|
||||
log.debug('HTTPBible.get_chapter("%s", "%s")', book, chapter)
|
||||
log.debug('source = %s', self.download_source)
|
||||
log.debug('HTTPBible.get_chapter("{book}", "{chapter}")'.format(book=book, chapter=chapter))
|
||||
log.debug('source = {source}'.format(source=self.download_source))
|
||||
if self.download_source.lower() == 'crosswalk':
|
||||
handler = CWExtract(self.proxy_server)
|
||||
elif self.download_source.lower() == 'biblegateway':
|
||||
|
@ -712,7 +727,7 @@ class HTTPBible(BibleDB, RegistryProperties):
|
|||
"""
|
||||
Return the list of books.
|
||||
"""
|
||||
log.debug('HTTPBible.get_books("%s")', Book.name)
|
||||
log.debug('HTTPBible.get_books("{name}")'.format(name=Book.name))
|
||||
return self.get_all_objects(Book, order_by_ref=Book.id)
|
||||
|
||||
def get_chapter_count(self, book):
|
||||
|
@ -721,7 +736,7 @@ class HTTPBible(BibleDB, RegistryProperties):
|
|||
|
||||
:param book: The book object to get the chapter count for.
|
||||
"""
|
||||
log.debug('HTTPBible.get_chapter_count("%s")', book.name)
|
||||
log.debug('HTTPBible.get_chapter_count("{name}")'.format(name=book.name))
|
||||
return BiblesResourcesDB.get_chapter_count(book.book_reference_id)
|
||||
|
||||
def get_verse_count(self, book_id, chapter):
|
||||
|
@ -731,7 +746,7 @@ class HTTPBible(BibleDB, RegistryProperties):
|
|||
:param book_id: The name of the book.
|
||||
:param chapter: The chapter whose verses are being counted.
|
||||
"""
|
||||
log.debug('HTTPBible.get_verse_count("%s", %s)', book_id, chapter)
|
||||
log.debug('HTTPBible.get_verse_count("{ref}", {chapter})'.format(ref=book_id, chapter=chapter))
|
||||
return BiblesResourcesDB.get_verse_count(book_id, chapter)
|
||||
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ class BibleManager(RegistryProperties):
|
|||
files = AppLocation.get_files(self.settings_section, self.suffix)
|
||||
if 'alternative_book_names.sqlite' in files:
|
||||
files.remove('alternative_book_names.sqlite')
|
||||
log.debug('Bible Files %s', files)
|
||||
log.debug('Bible Files {text}'.format(text=files))
|
||||
self.db_cache = {}
|
||||
self.old_bible_databases = []
|
||||
for filename in files:
|
||||
|
@ -135,7 +135,7 @@ class BibleManager(RegistryProperties):
|
|||
bible.session.close()
|
||||
delete_file(os.path.join(self.path, filename))
|
||||
continue
|
||||
log.debug('Bible Name: "%s"', name)
|
||||
log.debug('Bible Name: "{name}"'.format(name=name))
|
||||
self.db_cache[name] = bible
|
||||
# Look to see if lazy load bible exists and get create getter.
|
||||
source = self.db_cache[name].get_object(BibleMeta, 'download_source')
|
||||
|
@ -177,7 +177,7 @@ class BibleManager(RegistryProperties):
|
|||
|
||||
:param name: The name of the bible.
|
||||
"""
|
||||
log.debug('BibleManager.delete_bible("%s")', name)
|
||||
log.debug('BibleManager.delete_bible("{name}")'.format(name=name))
|
||||
bible = self.db_cache[name]
|
||||
bible.session.close()
|
||||
bible.session = None
|
||||
|
@ -196,7 +196,7 @@ class BibleManager(RegistryProperties):
|
|||
|
||||
:param bible: Unicode. The Bible to get the list of books from.
|
||||
"""
|
||||
log.debug('BibleManager.get_books("%s")', bible)
|
||||
log.debug('BibleManager.get_books("{bible}")'.format(bible=bible))
|
||||
return [
|
||||
{
|
||||
'name': book.name,
|
||||
|
@ -213,7 +213,7 @@ class BibleManager(RegistryProperties):
|
|||
:param bible: Unicode. The Bible to get the list of books from.
|
||||
:param id: Unicode. The book_reference_id to get the book for.
|
||||
"""
|
||||
log.debug('BibleManager.get_book_by_id("%s", "%s")', bible, id)
|
||||
log.debug('BibleManager.get_book_by_id("{bible}", "{ref}")'.format(bible=bible, ref=id))
|
||||
return self.db_cache[bible].get_book_by_book_ref_id(id)
|
||||
|
||||
def get_chapter_count(self, bible, book):
|
||||
|
@ -223,14 +223,16 @@ class BibleManager(RegistryProperties):
|
|||
:param bible: Unicode. The Bible to get the list of books from.
|
||||
:param book: The book object to get the chapter count for.
|
||||
"""
|
||||
log.debug('BibleManager.get_book_chapter_count ("%s", "%s")', bible, book.name)
|
||||
log.debug('BibleManager.get_book_chapter_count ("{bible}", "{name}")'.format(bible=bible, name=book.name))
|
||||
return self.db_cache[bible].get_chapter_count(book)
|
||||
|
||||
def get_verse_count(self, bible, book, chapter):
|
||||
"""
|
||||
Returns all the number of verses for a given book and chapterMaxBibleBookVerses.
|
||||
"""
|
||||
log.debug('BibleManager.get_verse_count("%s", "%s", %s)', bible, book, chapter)
|
||||
log.debug('BibleManager.get_verse_count("{bible}", "{book}", {chapter})'.format(bible=bible,
|
||||
book=book,
|
||||
chapter=chapter))
|
||||
language_selection = self.get_language_selection(bible)
|
||||
book_ref_id = self.db_cache[bible].get_book_ref_id_by_localised_name(book, language_selection)
|
||||
return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
|
||||
|
@ -240,7 +242,8 @@ class BibleManager(RegistryProperties):
|
|||
Returns all the number of verses for a given
|
||||
book_ref_id and chapterMaxBibleBookVerses.
|
||||
"""
|
||||
log.debug('BibleManager.get_verse_count_by_book_ref_id("%s", "%s", "%s")', bible, book_ref_id, chapter)
|
||||
log.debug('BibleManager.get_verse_count_by_book_ref_id("{bible}", '
|
||||
'"{book}", "{chapter}")'.format(bible=bible, book=book_ref_id, chapter=chapter))
|
||||
return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
|
||||
|
||||
def get_verses(self, bible, verse_text, book_ref_id=False, show_error=True):
|
||||
|
@ -264,7 +267,7 @@ class BibleManager(RegistryProperties):
|
|||
For second bible this is necessary.
|
||||
:param show_error:
|
||||
"""
|
||||
log.debug('BibleManager.get_verses("%s", "%s")', bible, verse_text)
|
||||
log.debug('BibleManager.get_verses("{bible}", "{verse}")'.format(bible=bible, verse=verse_text))
|
||||
if not bible:
|
||||
if show_error:
|
||||
self.main_window.information_message(
|
||||
|
@ -308,7 +311,7 @@ class BibleManager(RegistryProperties):
|
|||
|
||||
:param bible: Unicode. The Bible to get the language selection from.
|
||||
"""
|
||||
log.debug('BibleManager.get_language_selection("%s")', bible)
|
||||
log.debug('BibleManager.get_language_selection("{bible}")'.format(bible=bible))
|
||||
language_selection = self.get_meta_data(bible, 'book_name_language')
|
||||
if not language_selection or language_selection.value == "None" or language_selection.value == "-1":
|
||||
# If None is returned, it's not the singleton object but a
|
||||
|
@ -330,7 +333,7 @@ class BibleManager(RegistryProperties):
|
|||
:param second_bible: The second bible (unicode). We do not search in this bible.
|
||||
:param text: The text to search for (unicode).
|
||||
"""
|
||||
log.debug('BibleManager.verse_search("%s", "%s")', bible, text)
|
||||
log.debug('BibleManager.verse_search("{bible}", "{text}")'.format(bible=bible, text=text))
|
||||
if not bible:
|
||||
self.main_window.information_message(
|
||||
translate('BiblesPlugin.BibleManager', 'No Bibles Available'),
|
||||
|
@ -365,7 +368,10 @@ class BibleManager(RegistryProperties):
|
|||
"""
|
||||
Saves the bibles meta data.
|
||||
"""
|
||||
log.debug('save_meta data %s, %s, %s, %s', bible, version, copyright, permissions)
|
||||
log.debug('save_meta data {bible}, {version}, {copyright}, {perms}'.format(bible=bible,
|
||||
version=version,
|
||||
copyright=copyright,
|
||||
perms=permissions))
|
||||
self.db_cache[bible].save_meta('name', version)
|
||||
self.db_cache[bible].save_meta('copyright', copyright)
|
||||
self.db_cache[bible].save_meta('permissions', permissions)
|
||||
|
@ -375,14 +381,14 @@ class BibleManager(RegistryProperties):
|
|||
"""
|
||||
Returns the meta data for a given key.
|
||||
"""
|
||||
log.debug('get_meta %s,%s', bible, key)
|
||||
log.debug('get_meta {bible},{key}'.format(bible=bible, key=key))
|
||||
return self.db_cache[bible].get_object(BibleMeta, key)
|
||||
|
||||
def update_book(self, bible, book):
|
||||
"""
|
||||
Update a book of the bible.
|
||||
"""
|
||||
log.debug('BibleManager.update_book("%s", "%s")', bible, book.name)
|
||||
log.debug('BibleManager.update_book("{bible}", "{name}")'.format(bible=bible, name=book.name))
|
||||
self.db_cache[bible].update_book(book)
|
||||
|
||||
def exists(self, name):
|
||||
|
@ -392,7 +398,7 @@ class BibleManager(RegistryProperties):
|
|||
if not isinstance(name, str):
|
||||
name = str(name)
|
||||
for bible in list(self.db_cache.keys()):
|
||||
log.debug('Bible from cache in is_new_bible %s', bible)
|
||||
log.debug('Bible from cache in is_new_bible {bible}'.format(bible=bible))
|
||||
if not isinstance(bible, str):
|
||||
bible = str(bible)
|
||||
if bible == name:
|
||||
|
|
|
@ -280,7 +280,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
def retranslateUi(self):
|
||||
log.debug('retranslateUi')
|
||||
self.quick_search_label.setText(translate('BiblesPlugin.MediaItem', 'Find:'))
|
||||
self.quickVersionLabel.setText('%s:' % UiStrings().Version)
|
||||
self.quickVersionLabel.setText('{version}:'.format(version=UiStrings().Version))
|
||||
self.quickSecondLabel.setText(translate('BiblesPlugin.MediaItem', 'Second:'))
|
||||
self.quickStyleLabel.setText(UiStrings().LayoutStyle)
|
||||
self.quickStyleComboBox.setItemText(LayoutStyle.VersePerSlide, UiStrings().VersePerSlide)
|
||||
|
@ -294,7 +294,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
self.advanced_verse_label.setText(translate('BiblesPlugin.MediaItem', 'Verse:'))
|
||||
self.advanced_from_label.setText(translate('BiblesPlugin.MediaItem', 'From:'))
|
||||
self.advanced_to_label.setText(translate('BiblesPlugin.MediaItem', 'To:'))
|
||||
self.advancedVersionLabel.setText('%s:' % UiStrings().Version)
|
||||
self.advancedVersionLabel.setText('{version}:'.format(version=UiStrings().Version))
|
||||
self.advancedSecondLabel.setText(translate('BiblesPlugin.MediaItem', 'Second:'))
|
||||
self.advancedStyleLabel.setText(UiStrings().LayoutStyle)
|
||||
self.advancedStyleComboBox.setItemText(LayoutStyle.VersePerSlide, UiStrings().VersePerSlide)
|
||||
|
@ -316,7 +316,8 @@ class BibleMediaItem(MediaManagerItem):
|
|||
translate('BiblesPlugin.MediaItem', 'Text Search'),
|
||||
translate('BiblesPlugin.MediaItem', 'Search Text...'))
|
||||
])
|
||||
self.quick_search_edit.set_current_search_type(Settings().value('%s/last search type' % self.settings_section))
|
||||
text = self.settings_section
|
||||
self.quick_search_edit.set_current_search_type(Settings().value('{text}/last search type'.format(text=text)))
|
||||
self.config_update()
|
||||
log.debug('bible manager initialise complete')
|
||||
|
||||
|
@ -364,7 +365,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
:param bible: The bible to initialise (unicode).
|
||||
:param last_book_id: The "book reference id" of the book which is chosen at the moment. (int)
|
||||
"""
|
||||
log.debug('initialise_advanced_bible %s, %s', bible, last_book_id)
|
||||
log.debug('initialise_advanced_bible {bible}, {ref}'.format(bible=bible, ref=last_book_id))
|
||||
book_data = self.plugin.manager.get_books(bible)
|
||||
second_bible = self.advancedSecondComboBox.currentText()
|
||||
if second_bible != '':
|
||||
|
@ -406,7 +407,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
self.initialise_chapter_verse(bible, first_book['name'], first_book['book_reference_id'])
|
||||
|
||||
def initialise_chapter_verse(self, bible, book, book_ref_id):
|
||||
log.debug('initialise_chapter_verse %s, %s, %s', bible, book, book_ref_id)
|
||||
log.debug('initialise_chapter_verse {bible}, {book}, {ref}'.format(bible=bible, book=book, ref=book_ref_id))
|
||||
book = self.plugin.manager.get_book_by_id(bible, book_ref_id)
|
||||
self.chapter_count = self.plugin.manager.get_chapter_count(bible, book)
|
||||
verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(bible, book_ref_id, 1)
|
||||
|
@ -427,9 +428,11 @@ class BibleMediaItem(MediaManagerItem):
|
|||
"""
|
||||
log.debug('update_auto_completer')
|
||||
# Save the current search type to the configuration.
|
||||
Settings().setValue('%s/last search type' % self.settings_section, self.quick_search_edit.current_search_type())
|
||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||
self.quick_search_edit.current_search_type())
|
||||
# Save the current bible to the configuration.
|
||||
Settings().setValue(self.settings_section + '/quick bible', self.quickVersionComboBox.currentText())
|
||||
Settings().setValue('{section}/quick bible'.format(section=self.settings_section),
|
||||
self.quickVersionComboBox.currentText())
|
||||
books = []
|
||||
# We have to do a 'Reference Search'.
|
||||
if self.quick_search_edit.current_search_type() == BibleSearch.Reference:
|
||||
|
@ -502,9 +505,10 @@ class BibleMediaItem(MediaManagerItem):
|
|||
if bible:
|
||||
if QtWidgets.QMessageBox.question(
|
||||
self, UiStrings().ConfirmDelete,
|
||||
translate('BiblesPlugin.MediaItem', 'Are you sure you want to completely delete "%s" Bible from '
|
||||
'OpenLP?\n\nYou will need to re-import this Bible to use it '
|
||||
'again.') % bible,
|
||||
translate('BiblesPlugin.MediaItem',
|
||||
'Are you sure you want to completely delete "{bible}" Bible '
|
||||
'from OpenLP?\n\nYou will need to re-import this Bible to use it '
|
||||
'again.').format(bible=bible),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.No:
|
||||
return
|
||||
|
@ -606,7 +610,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
:param combo: The combo box itself (QComboBox).
|
||||
:param restore: If True, then the combo's currentText will be restored after adjusting (if possible).
|
||||
"""
|
||||
log.debug('adjust_combo_box %s, %s, %s', combo, range_from, range_to)
|
||||
log.debug('adjust_combo_box {box}, {start}, {end}'.format(box=combo, start=range_from, end=range_to))
|
||||
if restore:
|
||||
old_text = combo.currentText()
|
||||
combo.clear()
|
||||
|
@ -633,7 +637,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
range_separator = get_reference_separator('sep_r_display')
|
||||
verse_range = chapter_from + verse_separator + verse_from + range_separator + chapter_to + \
|
||||
verse_separator + verse_to
|
||||
verse_text = '%s %s' % (book, verse_range)
|
||||
verse_text = '{book} {verse}'.format(book=book, verse=verse_range)
|
||||
self.application.set_busy_cursor()
|
||||
self.search_results = self.plugin.manager.get_verses(bible, verse_text, book_ref_id)
|
||||
if second_bible:
|
||||
|
@ -678,8 +682,8 @@ class BibleMediaItem(MediaManagerItem):
|
|||
for verse in self.search_results:
|
||||
db_book = bibles[second_bible].get_book_by_book_ref_id(verse.book.book_reference_id)
|
||||
if not db_book:
|
||||
log.debug('Passage "%s %d:%d" not found in Second Bible' %
|
||||
(verse.book.name, verse.chapter, verse.verse))
|
||||
log.debug('Passage "{name} {chapter:d}:{verse:d}" not found in '
|
||||
'Second Bible'.format(name=verse.book.name, chapter=verse.chapter, verse=verse.verse))
|
||||
passage_not_found = True
|
||||
count += 1
|
||||
continue
|
||||
|
@ -688,9 +692,10 @@ class BibleMediaItem(MediaManagerItem):
|
|||
if passage_not_found:
|
||||
QtWidgets.QMessageBox.information(
|
||||
self, translate('BiblesPlugin.MediaItem', 'Information'),
|
||||
translate('BiblesPlugin.MediaItem', 'The second Bible does not contain all the verses '
|
||||
'that are in the main Bible. Only verses found in both Bibles will be shown. %d '
|
||||
'verses have not been included in the results.') % count,
|
||||
translate('BiblesPlugin.MediaItem',
|
||||
'The second Bible does not contain all the verses that are in the main Bible. '
|
||||
'Only verses found in both Bibles will be shown. {count:d} verses have not been '
|
||||
'included in the results.').format(count=count),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
self.search_results = new_search_results
|
||||
self.second_search_results = bibles[second_bible].get_verses(text)
|
||||
|
@ -767,10 +772,19 @@ class BibleMediaItem(MediaManagerItem):
|
|||
except TypeError:
|
||||
log.exception('The second_search_results does not have this book.')
|
||||
break
|
||||
bible_text = '%s %d%s%d (%s, %s)' % (book, verse.chapter, verse_separator, verse.verse, version,
|
||||
second_version)
|
||||
bible_text = ('{book} {chapter:d}{sep}{verse:d} '
|
||||
'({version1}, {version2})').format(book=book,
|
||||
chapter=verse.chapter,
|
||||
sep=verse_separator,
|
||||
verse=verse.verse,
|
||||
version1=version,
|
||||
version2=second_version)
|
||||
else:
|
||||
bible_text = '%s %d%s%d (%s)' % (book, verse.chapter, verse_separator, verse.verse, version)
|
||||
bible_text = '{book} {chapter:d}{sep}{verse:d} ({version})'.format(book=book,
|
||||
chapter=verse.chapter,
|
||||
sep=verse_separator,
|
||||
verse=verse.verse,
|
||||
version=version)
|
||||
bible_verse = QtWidgets.QListWidgetItem(bible_text)
|
||||
bible_verse.setData(QtCore.Qt.UserRole, data)
|
||||
items.append(bible_verse)
|
||||
|
@ -817,20 +831,22 @@ class BibleMediaItem(MediaManagerItem):
|
|||
verses.add(book, chapter, verse, version, copyright, permissions)
|
||||
verse_text = self.format_verse(old_chapter, chapter, verse)
|
||||
if second_bible:
|
||||
bible_text = '%s%s\n\n%s %s' % (verse_text, text, verse_text, second_text)
|
||||
bible_text = '{verse}{text1}\n\n{verse} {text2}'.format(verse=verse_text,
|
||||
text1=text,
|
||||
text2=second_text)
|
||||
raw_slides.append(bible_text.rstrip())
|
||||
bible_text = ''
|
||||
# If we are 'Verse Per Slide' then create a new slide.
|
||||
elif self.settings.layout_style == LayoutStyle.VersePerSlide:
|
||||
bible_text = '%s%s' % (verse_text, text)
|
||||
bible_text = '{verse}{text}'.format(verse=verse_text, text=text)
|
||||
raw_slides.append(bible_text.rstrip())
|
||||
bible_text = ''
|
||||
# If we are 'Verse Per Line' then force a new line.
|
||||
elif self.settings.layout_style == LayoutStyle.VersePerLine:
|
||||
bible_text = '%s%s%s\n' % (bible_text, verse_text, text)
|
||||
bible_text = '{bible}{verse}{text}\n'.format(bible=bible_text, verse=verse_text, text=text)
|
||||
# We have to be 'Continuous'.
|
||||
else:
|
||||
bible_text = '%s %s%s\n' % (bible_text, verse_text, text)
|
||||
bible_text = '{bible} {verse}{text}\n'.format(bible=bible_text, verse=verse_text, text=text)
|
||||
bible_text = bible_text.strip(' ')
|
||||
if not old_item:
|
||||
start_item = bitem
|
||||
|
@ -857,7 +873,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
service_item.add_capability(ItemCapabilities.CanWordSplit)
|
||||
service_item.add_capability(ItemCapabilities.CanEditTitle)
|
||||
# Service Item: Title
|
||||
service_item.title = '%s %s' % (verses.format_verses(), verses.format_versions())
|
||||
service_item.title = '{verse} {version}'.format(verse=verses.format_verses(), version=verses.format_versions())
|
||||
# Service Item: Theme
|
||||
if not self.settings.bible_theme:
|
||||
service_item.theme = None
|
||||
|
@ -885,7 +901,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
start_bible = self._decode_qt_object(start_bitem, 'bible')
|
||||
start_second_bible = self._decode_qt_object(start_bitem, 'second_bible')
|
||||
if start_second_bible:
|
||||
bibles = '%s, %s' % (start_bible, start_second_bible)
|
||||
bibles = '{bible1}, {bible2}'.format(bible1=start_bible, bible2=start_second_bible)
|
||||
else:
|
||||
bibles = start_bible
|
||||
if start_chapter == old_chapter:
|
||||
|
@ -896,7 +912,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
else:
|
||||
verse_range = start_chapter + verse_separator + start_verse + \
|
||||
range_separator + old_chapter + verse_separator + old_verse
|
||||
return '%s %s (%s)' % (start_book, verse_range, bibles)
|
||||
return '{book} {verse} ({bible})'.format(book=start_book, verse=verse_range, bible=bibles)
|
||||
|
||||
def check_title(self, bitem, old_bitem):
|
||||
"""
|
||||
|
@ -949,12 +965,12 @@ class BibleMediaItem(MediaManagerItem):
|
|||
else:
|
||||
verse_text = str(verse)
|
||||
if self.settings.display_style == DisplayStyle.Round:
|
||||
return '{su}(%s){/su} ' % verse_text
|
||||
return '{{su}}({verse}){{/su}} '.format(verse=verse_text)
|
||||
if self.settings.display_style == DisplayStyle.Curly:
|
||||
return '{su}{%s}{/su} ' % verse_text
|
||||
return '{{su}}{{{verse}}}{{/su}} '.format(verse=verse_text)
|
||||
if self.settings.display_style == DisplayStyle.Square:
|
||||
return '{su}[%s]{/su} ' % verse_text
|
||||
return '{su}%s{/su} ' % verse_text
|
||||
return '{{su}}[{verse}]{{/su}} '.format(verse=verse_text)
|
||||
return '{{su}}{verse}{{/su}} '.format(verse=verse_text)
|
||||
|
||||
def search(self, string, showError):
|
||||
"""
|
||||
|
|
|
@ -63,7 +63,7 @@ class OpenSongBible(BibleDB):
|
|||
"""
|
||||
Loads a Bible from file.
|
||||
"""
|
||||
log.debug('Starting OpenSong import from "%s"' % self.filename)
|
||||
log.debug('Starting OpenSong import from "{name}"'.format(name=self.filename))
|
||||
if not isinstance(self.filename, str):
|
||||
self.filename = str(self.filename, 'utf8')
|
||||
import_file = None
|
||||
|
@ -84,14 +84,14 @@ class OpenSongBible(BibleDB):
|
|||
# No language info in the opensong format, so ask the user
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.error('Importing books from "%s" failed' % self.filename)
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.filename))
|
||||
return False
|
||||
for book in bible.b:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
book_ref_id = self.get_book_ref_id_by_name(str(book.attrib['n']), len(bible.b), language_id)
|
||||
if not book_ref_id:
|
||||
log.error('Importing books from "%s" failed' % self.filename)
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.filename))
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.create_book(book.attrib['n'], book_ref_id, book_details['testament_id'])
|
||||
|
@ -117,14 +117,14 @@ class OpenSongBible(BibleDB):
|
|||
if len(verse_parts) > 1:
|
||||
number = int(verse_parts[0])
|
||||
except TypeError:
|
||||
log.warning('Illegal verse number: %s', str(verse.attrib['n']))
|
||||
log.warning('Illegal verse number: {verse:d}'.format(verse=verse.attrib['n']))
|
||||
verse_number = number
|
||||
else:
|
||||
verse_number += 1
|
||||
self.create_verse(db_book.id, chapter_number, verse_number, self.get_text(verse))
|
||||
self.wizard.increment_progress_bar(
|
||||
translate('BiblesPlugin.Opensong', 'Importing %(bookname)s %(chapter)s...') %
|
||||
{'bookname': db_book.name, 'chapter': chapter_number})
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.Opensong',
|
||||
'Importing {name} {chapter}...'
|
||||
).format(name=db_book.name, chapter=chapter_number))
|
||||
self.session.commit()
|
||||
self.application.process_events()
|
||||
except etree.XMLSyntaxError as inst:
|
||||
|
|
|
@ -49,7 +49,7 @@ class OSISBible(BibleDB):
|
|||
"""
|
||||
Loads a Bible from file.
|
||||
"""
|
||||
log.debug('Starting OSIS import from "%s"' % self.filename)
|
||||
log.debug('Starting OSIS import from "{name}"'.format(name=self.filename))
|
||||
if not isinstance(self.filename, str):
|
||||
self.filename = str(self.filename, 'utf8')
|
||||
import_file = None
|
||||
|
@ -69,7 +69,7 @@ class OSISBible(BibleDB):
|
|||
if not language_id:
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.error('Importing books from "%s" failed' % self.filename)
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.filename))
|
||||
return False
|
||||
self.save_meta('language_id', language_id)
|
||||
num_books = int(osis_bible_tree.xpath("count(//ns:div[@type='book'])", namespaces=namespace))
|
||||
|
@ -127,9 +127,7 @@ class OSISBible(BibleDB):
|
|||
etree.strip_tags(book, ('{http://www.bibletechnologies.net/2003/OSIS/namespace}div'))
|
||||
book_ref_id = self.get_book_ref_id_by_name(book.get('osisID'), num_books, language_id)
|
||||
if not book_ref_id:
|
||||
book_ref_id = self.get_book_ref_id_by_localised_name(book.get('osisID'))
|
||||
if not book_ref_id:
|
||||
log.error('Importing books from "%s" failed' % self.filename)
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.filename))
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.create_book(book_details['name'], book_ref_id, book_details['testament_id'])
|
||||
|
@ -187,7 +185,8 @@ class OSISBible(BibleDB):
|
|||
trace_error_handler(log)
|
||||
success = False
|
||||
critical_error_message_box(message=translate('BiblesPlugin.OsisImport',
|
||||
'The file is not a valid OSIS-XML file: \n%s' % e.msg))
|
||||
'The file is not a valid OSIS-XML file:'
|
||||
'\n{text}').format(text=e.msg))
|
||||
finally:
|
||||
if import_file:
|
||||
import_file.close()
|
||||
|
|
|
@ -51,7 +51,7 @@ class SwordBible(BibleDB):
|
|||
"""
|
||||
Loads a Bible from SWORD module.
|
||||
"""
|
||||
log.debug('Starting SWORD import from "%s"' % self.sword_key)
|
||||
log.debug('Starting SWORD import from "{key}"'.format(key=self.sword_key))
|
||||
success = True
|
||||
try:
|
||||
pysword_modules = modules.SwordModules(self.sword_path)
|
||||
|
@ -84,14 +84,14 @@ class SwordBible(BibleDB):
|
|||
verse_number += 1
|
||||
self.create_verse(db_book.id, chapter_number, verse_number, verse)
|
||||
self.wizard.increment_progress_bar(
|
||||
translate('BiblesPlugin.Sword', 'Importing %s...') % db_book.name)
|
||||
translate('BiblesPlugin.Sword', 'Importing {name}...').format(name=db_book.name))
|
||||
self.session.commit()
|
||||
self.application.process_events()
|
||||
except Exception as e:
|
||||
critical_error_message_box(
|
||||
message=translate('BiblesPlugin.SwordImport', 'An unexpected error happened while importing the SWORD '
|
||||
'bible, please report this to the OpenLP developers.\n'
|
||||
'%s' % e))
|
||||
'{error}').format(error=e))
|
||||
log.exception(str(e))
|
||||
success = False
|
||||
if self.stop_import_flag:
|
||||
|
|
|
@ -101,7 +101,7 @@ def upgrade_1(session, metadata):
|
|||
metadata_table.c.key == 'download source'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('download source: %s', value_count)
|
||||
log.debug('download source: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='download_source',
|
||||
|
@ -121,7 +121,7 @@ def upgrade_1(session, metadata):
|
|||
metadata_table.c.key == 'download name'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('download name: %s', value_count)
|
||||
log.debug('download name: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='download_name',
|
||||
|
@ -141,7 +141,7 @@ def upgrade_1(session, metadata):
|
|||
metadata_table.c.key == 'proxy server'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('proxy server: %s', value_count)
|
||||
log.debug('proxy server: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='proxy_server',
|
||||
|
@ -161,7 +161,7 @@ def upgrade_1(session, metadata):
|
|||
metadata_table.c.key == 'proxy username'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('proxy username: %s', value_count)
|
||||
log.debug('proxy username: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='proxy_username',
|
||||
|
@ -181,7 +181,7 @@ def upgrade_1(session, metadata):
|
|||
metadata_table.c.key == 'proxy password'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('proxy password: %s', value_count)
|
||||
log.debug('proxy password: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='proxy_password',
|
||||
|
|
|
@ -61,23 +61,29 @@ class VerseReferenceList(object):
|
|||
result = ''
|
||||
for index, verse in enumerate(self.verse_list):
|
||||
if index == 0:
|
||||
result = '%s %s%s%s' % (verse['book'], verse['chapter'], verse_sep, verse['start'])
|
||||
result = '{book} {chapter}{sep}{verse}'.format(book=verse['book'],
|
||||
chapter=verse['chapter'],
|
||||
sep=verse_sep,
|
||||
verse=verse['start'])
|
||||
if verse['start'] != verse['end']:
|
||||
result = '%s%s%s' % (result, range_sep, verse['end'])
|
||||
result = '{result}{sep}{end}'.format(result=result, sep=range_sep, end=verse['end'])
|
||||
continue
|
||||
prev = index - 1
|
||||
if self.verse_list[prev]['version'] != verse['version']:
|
||||
result = '%s (%s)' % (result, self.verse_list[prev]['version'])
|
||||
result += '%s ' % list_sep
|
||||
result = '{result} ({version})'.format(result=result, version=self.verse_list[prev]['version'])
|
||||
result += '{sep} '.format(sep=list_sep)
|
||||
if self.verse_list[prev]['book'] != verse['book']:
|
||||
result = '%s%s %s%s' % (result, verse['book'], verse['chapter'], verse_sep)
|
||||
result = '{result}{book} {chapter}{sep}'.format(result=result,
|
||||
book=verse['book'],
|
||||
chapter=verse['chapter'],
|
||||
sep=verse_sep)
|
||||
elif self.verse_list[prev]['chapter'] != verse['chapter']:
|
||||
result = '%s%s%s' % (result, verse['chapter'], verse_sep)
|
||||
result = '{result}{chapter}{sep}'.format(result=result, chapter=verse['chapter'], sep=verse_sep)
|
||||
result += str(verse['start'])
|
||||
if verse['start'] != verse['end']:
|
||||
result = '%s%s%s' % (result, range_sep, verse['end'])
|
||||
result = '{result}{sep}{end}'.format(result=result, sep=range_sep, end=verse['end'])
|
||||
if len(self.version_list) > 1:
|
||||
result = '%s (%s)' % (result, verse['version'])
|
||||
result = '{result} ({version})'.format(result=result, version=verse['version'])
|
||||
return result
|
||||
|
||||
def format_versions(self, copyright=True, permission=True):
|
||||
|
|
|
@ -48,7 +48,7 @@ class ZefaniaBible(BibleDB):
|
|||
"""
|
||||
Loads a Bible from file.
|
||||
"""
|
||||
log.debug('Starting Zefania import from "%s"' % self.filename)
|
||||
log.debug('Starting Zefania import from "{name}"'.format(name=self.filename))
|
||||
if not isinstance(self.filename, str):
|
||||
self.filename = str(self.filename, 'utf8')
|
||||
import_file = None
|
||||
|
@ -67,7 +67,7 @@ class ZefaniaBible(BibleDB):
|
|||
if not language_id:
|
||||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
log.error('Importing books from "%s" failed' % self.filename)
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.filename))
|
||||
return False
|
||||
self.save_meta('language_id', language_id)
|
||||
num_books = int(zefania_bible_tree.xpath('count(//BIBLEBOOK)'))
|
||||
|
@ -86,13 +86,11 @@ class ZefaniaBible(BibleDB):
|
|||
continue
|
||||
if bname:
|
||||
book_ref_id = self.get_book_ref_id_by_name(bname, num_books, language_id)
|
||||
if not book_ref_id:
|
||||
book_ref_id = self.get_book_ref_id_by_localised_name(bname)
|
||||
else:
|
||||
log.debug('Could not find a name, will use number, basically a guess.')
|
||||
book_ref_id = int(bnumber)
|
||||
if not book_ref_id:
|
||||
log.error('Importing books from "%s" failed' % self.filename)
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.filename))
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.create_book(book_details['name'], book_ref_id, book_details['testament_id'])
|
||||
|
@ -104,8 +102,9 @@ class ZefaniaBible(BibleDB):
|
|||
verse_number = VERS.get("vnumber")
|
||||
self.create_verse(db_book.id, chapter_number, verse_number, VERS.text.replace('<BR/>', '\n'))
|
||||
self.wizard.increment_progress_bar(
|
||||
translate('BiblesPlugin.Zefnia', 'Importing %(bookname)s %(chapter)s...') %
|
||||
{'bookname': db_book.name, 'chapter': chapter_number})
|
||||
translate('BiblesPlugin.Zefnia',
|
||||
'Importing {book} {chapter}...').format(book=db_book.name,
|
||||
chapter=chapter_number))
|
||||
self.session.commit()
|
||||
self.application.process_events()
|
||||
except Exception as e:
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common import UiStrings, translate
|
||||
from openlp.core.lib import SpellTextEdit, build_icon
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button, create_button_box
|
||||
from openlp.core.ui.lib import SpellTextEdit
|
||||
|
||||
|
||||
class Ui_CustomSlideEditDialog(object):
|
||||
|
|
|
@ -128,7 +128,7 @@ class CustomXMLParser(object):
|
|||
try:
|
||||
self.custom_xml = objectify.fromstring(xml)
|
||||
except etree.XMLSyntaxError:
|
||||
log.exception('Invalid xml %s', xml)
|
||||
log.exception('Invalid xml {xml}'.format(xml=xml))
|
||||
|
||||
def get_verses(self):
|
||||
"""
|
||||
|
|
|
@ -94,7 +94,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||
"""
|
||||
|
||||
"""
|
||||
self.search_text_label.setText('%s:' % UiStrings().Search)
|
||||
self.search_text_label.setText('{text}:'.format(text=UiStrings().Search))
|
||||
self.search_text_button.setText(UiStrings().Search)
|
||||
|
||||
def initialise(self):
|
||||
|
@ -105,7 +105,8 @@ class CustomMediaItem(MediaManagerItem):
|
|||
[(CustomSearch.Titles, ':/songs/song_search_title.png', translate('SongsPlugin.MediaItem', 'Titles'),
|
||||
translate('SongsPlugin.MediaItem', 'Search Titles...')),
|
||||
(CustomSearch.Themes, ':/slides/slide_theme.png', UiStrings().Themes, UiStrings().SearchThemes)])
|
||||
self.search_text_edit.set_current_search_type(Settings().value('%s/last search type' % self.settings_section))
|
||||
text = '{section}/last search type'.format(section=self.settings_section)
|
||||
self.search_text_edit.set_current_search_type(Settings().value(text))
|
||||
self.load_list(self.plugin.db_manager.get_all_objects(CustomSlide, order_by_ref=CustomSlide.title))
|
||||
self.config_update()
|
||||
|
||||
|
@ -190,7 +191,8 @@ class CustomMediaItem(MediaManagerItem):
|
|||
if QtWidgets.QMessageBox.question(
|
||||
self, UiStrings().ConfirmDelete,
|
||||
translate('CustomPlugin.MediaItem',
|
||||
'Are you sure you want to delete the "%d" selected custom slide(s)?') % len(items),
|
||||
'Are you sure you want to delete the "{items:d}" '
|
||||
'selected custom slide(s)?').format(items=len(items)),
|
||||
QtWidgets.QMessageBox.StandardButtons(
|
||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.No:
|
||||
|
@ -249,10 +251,11 @@ class CustomMediaItem(MediaManagerItem):
|
|||
Search the plugin database
|
||||
"""
|
||||
# Save the current search type to the configuration.
|
||||
Settings().setValue('%s/last search type' % self.settings_section, self.search_text_edit.current_search_type())
|
||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||
self.search_text_edit.current_search_type())
|
||||
# Reload the list considering the new search type.
|
||||
search_type = self.search_text_edit.current_search_type()
|
||||
search_keywords = '%' + self.whitespace.sub(' ', self.search_text_edit.displayText()) + '%'
|
||||
search_keywords = '%{search}%'.format(search=self.whitespace.sub(' ', self.search_text_edit.displayText()))
|
||||
if search_type == CustomSearch.Titles:
|
||||
log.debug('Titles Search')
|
||||
search_results = self.plugin.db_manager.get_all_objects(CustomSlide,
|
||||
|
@ -347,7 +350,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||
:param string: The search string
|
||||
:param show_error: The error string to be show.
|
||||
"""
|
||||
search = '%' + string.lower() + '%'
|
||||
search = '%{search}%'.forma(search=string.lower())
|
||||
search_results = self.plugin.db_manager.get_all_objects(CustomSlide,
|
||||
or_(func.lower(CustomSlide.title).like(search),
|
||||
func.lower(CustomSlide.text).like(search)),
|
||||
|
|
|
@ -74,7 +74,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
def retranslateUi(self):
|
||||
self.on_new_prompt = translate('ImagePlugin.MediaItem', 'Select Image(s)')
|
||||
file_formats = get_images_filter()
|
||||
self.on_new_file_masks = '%s;;%s (*)' % (file_formats, UiStrings().AllFiles)
|
||||
self.on_new_file_masks = '{formats};;{files} (*)'.format(formats=file_formats, files=UiStrings().AllFiles)
|
||||
self.add_group_action.setText(UiStrings().AddGroupDot)
|
||||
self.add_group_action.setToolTip(UiStrings().AddGroupDot)
|
||||
self.replace_action.setText(UiStrings().ReplaceBG)
|
||||
|
@ -113,7 +113,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
self.list_view = TreeWidgetWithDnD(self, self.plugin.name)
|
||||
self.list_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
self.list_view.setAlternatingRowColors(True)
|
||||
self.list_view.setObjectName('%sTreeView' % self.plugin.name)
|
||||
self.list_view.setObjectName('{name}TreeView'.format(name=self.plugin.name))
|
||||
# Add to pageLayout
|
||||
self.page_layout.addWidget(self.list_view)
|
||||
# define and add the context menu
|
||||
|
@ -127,21 +127,21 @@ class ImageMediaItem(MediaManagerItem):
|
|||
create_widget_action(self.list_view, separator=True)
|
||||
create_widget_action(
|
||||
self.list_view,
|
||||
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()),
|
||||
'listView{name}{preview}Item'.format(name=self.plugin.name.title(), preview=StringContent.Preview.title()),
|
||||
text=self.plugin.get_string(StringContent.Preview)['title'],
|
||||
icon=':/general/general_preview.png',
|
||||
can_shortcuts=True,
|
||||
triggers=self.on_preview_click)
|
||||
create_widget_action(
|
||||
self.list_view,
|
||||
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Live.title()),
|
||||
'listView{name}{live}Item'.format(name=self.plugin.name.title(), live=StringContent.Live.title()),
|
||||
text=self.plugin.get_string(StringContent.Live)['title'],
|
||||
icon=':/general/general_live.png',
|
||||
can_shortcuts=True,
|
||||
triggers=self.on_live_click)
|
||||
create_widget_action(
|
||||
self.list_view,
|
||||
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Service.title()),
|
||||
'listView{name}{service}Item'.format(name=self.plugin.name.title(), service=StringContent.Service.title()),
|
||||
can_shortcuts=True,
|
||||
text=self.plugin.get_string(StringContent.Service)['title'],
|
||||
icon=':/general/general_add.png',
|
||||
|
@ -157,7 +157,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
if self.has_delete_icon:
|
||||
create_widget_action(
|
||||
self.list_view,
|
||||
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
|
||||
'listView{name}{delete}Item'.format(name=self.plugin.name.title(), delete=StringContent.Delete.title()),
|
||||
text=self.plugin.get_string(StringContent.Delete)['title'],
|
||||
icon=':/general/general_delete.png',
|
||||
can_shortcuts=True, triggers=self.on_delete_click)
|
||||
|
@ -245,8 +245,8 @@ class ImageMediaItem(MediaManagerItem):
|
|||
self.list_view.parent(),
|
||||
translate('ImagePlugin.MediaItem', 'Remove group'),
|
||||
translate('ImagePlugin.MediaItem',
|
||||
'Are you sure you want to remove "%s" and everything in it?') %
|
||||
item_data.group_name,
|
||||
'Are you sure you want to remove "{name}" and everything in it?'
|
||||
).format(name=item_data.group_name),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No)
|
||||
) == QtWidgets.QMessageBox.Yes:
|
||||
|
@ -355,7 +355,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
# characters.
|
||||
images.sort(key=lambda image_object: get_locale_key(os.path.split(str(image_object.filename))[1]))
|
||||
for image_file in images:
|
||||
log.debug('Loading image: %s', image_file.filename)
|
||||
log.debug('Loading image: {name}'.format(name=image_file.filename))
|
||||
filename = os.path.split(image_file.filename)[1]
|
||||
thumb = self.generate_thumbnail_path(image_file)
|
||||
if not os.path.exists(image_file.filename):
|
||||
|
@ -481,7 +481,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
for filename in images_list:
|
||||
if not isinstance(filename, str):
|
||||
continue
|
||||
log.debug('Adding new image: %s', filename)
|
||||
log.debug('Adding new image: {name}'.format(name=filename))
|
||||
image_file = ImageFilenames()
|
||||
image_file.group_id = group_id
|
||||
image_file.filename = str(filename)
|
||||
|
@ -589,14 +589,15 @@ class ImageMediaItem(MediaManagerItem):
|
|||
if not remote:
|
||||
critical_error_message_box(
|
||||
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
|
||||
translate('ImagePlugin.MediaItem', 'The following image(s) no longer exist: %s')
|
||||
% '\n'.join(missing_items_file_names))
|
||||
translate('ImagePlugin.MediaItem', 'The following image(s) no longer exist: {names}'
|
||||
).format(names='\n'.join(missing_items_file_names)))
|
||||
return False
|
||||
# We have missing as well as existing images. We ask what to do.
|
||||
elif missing_items_file_names and QtWidgets.QMessageBox.question(
|
||||
self, translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
|
||||
translate('ImagePlugin.MediaItem', 'The following image(s) no longer exist: %s\n'
|
||||
'Do you want to add the other images anyway?') % '\n'.join(missing_items_file_names),
|
||||
translate('ImagePlugin.MediaItem', 'The following image(s) no longer exist: {names}\n'
|
||||
'Do you want to add the other images anyway?'
|
||||
).format(names='\n'.join(missing_items_file_names)),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes)) == \
|
||||
QtWidgets.QMessageBox.No:
|
||||
return False
|
||||
|
@ -688,7 +689,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
critical_error_message_box(
|
||||
UiStrings().LiveBGError,
|
||||
translate('ImagePlugin.MediaItem', 'There was a problem replacing your background, '
|
||||
'the image file "%s" no longer exists.') % filename)
|
||||
'the image file "{name}" no longer exists.').format(name=filename))
|
||||
|
||||
def search(self, string, show_error=True):
|
||||
"""
|
||||
|
|
|
@ -46,7 +46,7 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
"""
|
||||
Class to manage the clip selection
|
||||
"""
|
||||
log.info('%s MediaClipSelectorForm loaded', __name__)
|
||||
log.info('{name} MediaClipSelectorForm loaded'.format(name=__name__))
|
||||
|
||||
def __init__(self, media_item, parent, manager):
|
||||
"""
|
||||
|
@ -265,7 +265,8 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
# Enable audio track combobox if anything is in it
|
||||
if len(titles) > 0:
|
||||
self.titles_combo_box.setDisabled(False)
|
||||
log.debug('load_disc_button end - vlc_media_player state: %s' % self.vlc_media_player.get_state())
|
||||
log.debug('load_disc_button end - '
|
||||
'vlc_media_player state: {state}'.format(state=self.vlc_media_player.get_state()))
|
||||
|
||||
@QtCore.pyqtSlot(bool)
|
||||
def on_play_button_clicked(self, clicked):
|
||||
|
@ -374,7 +375,7 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
|
||||
:param index: The index of the newly chosen title track.
|
||||
"""
|
||||
log.debug('in on_titles_combo_box_changed, index: %d', index)
|
||||
log.debug('in on_titles_combo_box_changed, index: {index:d}'.format(index=index))
|
||||
vlc = get_vlc()
|
||||
if not self.vlc_media_player:
|
||||
log.error('vlc_media_player was None')
|
||||
|
@ -407,7 +408,7 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
self.vlc_media_player.audio_set_mute(True)
|
||||
# Get audio tracks
|
||||
audio_tracks = self.vlc_media_player.audio_get_track_description()
|
||||
log.debug('number of audio tracks: %d' % len(audio_tracks))
|
||||
log.debug('number of audio tracks: {tracks:d}'.format(tracks=len(audio_tracks)))
|
||||
# Clear the audio track combobox, insert new tracks
|
||||
self.audio_tracks_combobox.clear()
|
||||
for audio_track in audio_tracks:
|
||||
|
@ -433,14 +434,14 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
self.toggle_disable_player(False)
|
||||
# Set media length info
|
||||
self.playback_length = self.vlc_media_player.get_length()
|
||||
log.debug('playback_length: %d ms' % self.playback_length)
|
||||
log.debug('playback_length: {length:d} ms'.format(length=self.playback_length))
|
||||
# if length is 0, wait a bit, maybe vlc will change its mind...
|
||||
loop_count = 0
|
||||
while self.playback_length == 0 and loop_count < 20:
|
||||
sleep(0.1)
|
||||
self.playback_length = self.vlc_media_player.get_length()
|
||||
loop_count += 1
|
||||
log.debug('in loop, playback_length: %d ms' % self.playback_length)
|
||||
log.debug('in loop, playback_length: {length:d} ms'.format(length=self.playback_length))
|
||||
self.position_slider.setMaximum(self.playback_length)
|
||||
# setup start and end time
|
||||
rounded_vlc_ms_length = int(round(self.playback_length / 100.0) * 100.0)
|
||||
|
@ -455,7 +456,8 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
sleep(0.1)
|
||||
self.vlc_media_player.set_pause(1)
|
||||
loop_count += 1
|
||||
log.debug('titles_combo_box end - vlc_media_player state: %s' % self.vlc_media_player.get_state())
|
||||
log.debug('titles_combo_box end - '
|
||||
'vlc_media_player state: {state}'.format(state=self.vlc_media_player.get_state()))
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
@QtCore.pyqtSlot(int)
|
||||
|
@ -468,7 +470,8 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
if not self.vlc_media_player:
|
||||
return
|
||||
audio_track = self.audio_tracks_combobox.itemData(index)
|
||||
log.debug('in on_audio_tracks_combobox_currentIndexChanged, index: %d audio_track: %s' % (index, audio_track))
|
||||
log.debug('in on_audio_tracks_combobox_currentIndexChanged, '
|
||||
'index: {index:d} audio_track: {tracks}'.format(index=index, tracks=audio_track))
|
||||
if audio_track and int(audio_track) > 0:
|
||||
self.vlc_media_player.audio_set_track(int(audio_track))
|
||||
|
||||
|
@ -566,7 +569,9 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
translate('MediaPlugin.MediaClipSelectorForm',
|
||||
'The CD was not loaded correctly, please re-load and try again.'))
|
||||
return
|
||||
optical = 'optical:%d:-1:-1:%d:%d:' % (title, start_time_ms, end_time_ms)
|
||||
optical = 'optical:{title:d}:-1:-1:{start:d}:{end:d}:'.format(title=title,
|
||||
start=start_time_ms,
|
||||
end=end_time_ms)
|
||||
else:
|
||||
audio_track = self.audio_tracks_combobox.itemData(self.audio_tracks_combobox.currentIndex())
|
||||
subtitle_track = self.subtitle_tracks_combobox.itemData(self.subtitle_tracks_combobox.currentIndex())
|
||||
|
@ -577,7 +582,11 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
translate('MediaPlugin.MediaClipSelectorForm',
|
||||
'The DVD was not loaded correctly, please re-load and try again.'))
|
||||
return
|
||||
optical = 'optical:%d:%d:%d:%d:%d:' % (title, audio_track, subtitle_track, start_time_ms, end_time_ms)
|
||||
optical = 'optical:{title:d}:{audio:d}:{sub:d}:{start:d}:{end:d}:'.format(title=title,
|
||||
audio=audio_track,
|
||||
sub=subtitle_track,
|
||||
start=start_time_ms,
|
||||
end=end_time_ms)
|
||||
# Ask for an alternative name for the mediaclip
|
||||
while True:
|
||||
new_optical_name, ok = QtWidgets.QInputDialog.getText(self, translate('MediaPlugin.MediaClipSelectorForm',
|
||||
|
@ -634,10 +643,10 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
# use win api to find optical drives
|
||||
fso = Dispatch('scripting.filesystemobject')
|
||||
for drive in fso.Drives:
|
||||
log.debug('Drive %s has type %d' % (drive.DriveLetter, drive.DriveType))
|
||||
log.debug('Drive {drive} has type {types:d}'.format(drive=drive.DriveLetter, types=drive.DriveType))
|
||||
# if type is 4, it is a cd-rom drive
|
||||
if drive.DriveType == 4:
|
||||
self.media_path_combobox.addItem('%s:\\' % drive.DriveLetter)
|
||||
self.media_path_combobox.addItem('{drive}:\\'.format(drive=drive.DriveLetter))
|
||||
elif is_linux():
|
||||
# Get disc devices from dbus and find the ones that are optical
|
||||
bus = dbus.SystemBus()
|
||||
|
|
|
@ -51,7 +51,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
"""
|
||||
media_go_live = QtCore.pyqtSignal(list)
|
||||
media_add_to_service = QtCore.pyqtSignal(list)
|
||||
log.info('%s MediaMediaItem loaded', __name__)
|
||||
log.info('{name} MediaMediaItem loaded'.format(name=__name__))
|
||||
|
||||
def __init__(self, parent, plugin):
|
||||
self.setup()
|
||||
|
@ -232,7 +232,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
critical_error_message_box(UiStrings().LiveBGError,
|
||||
translate('MediaPlugin.MediaItem',
|
||||
'There was a problem replacing your background, '
|
||||
'the media file "%s" no longer exists.') % filename)
|
||||
'the media file "{name}" no longer exists.').format(name=filename))
|
||||
|
||||
def generate_slide_data(self, service_item, item=None, xml_version=False, remote=False,
|
||||
context=ServiceItemContext.Service):
|
||||
|
@ -258,7 +258,8 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
# Optical disc is no longer present
|
||||
critical_error_message_box(
|
||||
translate('MediaPlugin.MediaItem', 'Missing Media File'),
|
||||
translate('MediaPlugin.MediaItem', 'The optical disc %s is no longer available.') % name)
|
||||
translate('MediaPlugin.MediaItem',
|
||||
'The optical disc {name} is no longer available.').format(name=name))
|
||||
return False
|
||||
service_item.processor = self.display_type_combo_box.currentText()
|
||||
service_item.add_from_command(filename, name, CLAPPERBOARD)
|
||||
|
@ -275,7 +276,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
# File is no longer present
|
||||
critical_error_message_box(
|
||||
translate('MediaPlugin.MediaItem', 'Missing Media File'),
|
||||
translate('MediaPlugin.MediaItem', 'The file %s no longer exists.') % filename)
|
||||
translate('MediaPlugin.MediaItem', 'The file {name} no longer exists.').format(name=filename))
|
||||
return False
|
||||
(path, name) = os.path.split(filename)
|
||||
service_item.title = name
|
||||
|
@ -308,9 +309,11 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
Rebuild the tab in the media manager when changes are made in the settings.
|
||||
"""
|
||||
self.populate_display_types()
|
||||
self.on_new_file_masks = translate('MediaPlugin.MediaItem', 'Videos (%s);;Audio (%s);;%s (*)') % (
|
||||
' '.join(self.media_controller.video_extensions_list),
|
||||
' '.join(self.media_controller.audio_extensions_list), UiStrings().AllFiles)
|
||||
self.on_new_file_masks = translate('MediaPlugin.MediaItem',
|
||||
'Videos ({video});;Audio ({audio});;{files} '
|
||||
'(*)').format(video=' '.join(self.media_controller.video_extensions_list),
|
||||
audio=' '.join(self.media_controller.audio_extensions_list),
|
||||
files=UiStrings().AllFiles)
|
||||
|
||||
def populate_display_types(self):
|
||||
"""
|
||||
|
@ -365,7 +368,9 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
item_name = QtWidgets.QListWidgetItem(clip_name)
|
||||
item_name.setIcon(self.optical_icon)
|
||||
item_name.setData(QtCore.Qt.UserRole, track)
|
||||
item_name.setToolTip('%s@%s-%s' % (file_name, format_milliseconds(start), format_milliseconds(end)))
|
||||
item_name.setToolTip('{name}@{start}-{end}'.format(name=file_name,
|
||||
start=format_milliseconds(start),
|
||||
end=format_milliseconds(end)))
|
||||
elif not os.path.exists(track):
|
||||
# File doesn't exist, mark as error.
|
||||
file_name = os.path.split(str(track))[1]
|
||||
|
@ -377,7 +382,8 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
# Normal media file handling.
|
||||
file_name = os.path.split(str(track))[1]
|
||||
item_name = QtWidgets.QListWidgetItem(file_name)
|
||||
if '*.%s' % (file_name.split('.')[-1].lower()) in self.media_controller.audio_extensions_list:
|
||||
search = file_name.split('.')[-1].lower()
|
||||
if '*.{text}'.format(text=search) in self.media_controller.audio_extensions_list:
|
||||
item_name.setIcon(self.audio_icon)
|
||||
else:
|
||||
item_name.setIcon(self.video_icon)
|
||||
|
|
|
@ -49,7 +49,7 @@ class MediaPlugin(Plugin):
|
|||
"""
|
||||
The media plugin adds the ability to playback audio and video content.
|
||||
"""
|
||||
log.info('%s MediaPlugin loaded', __name__)
|
||||
log.info('{name} MediaPlugin loaded'.format(name=__name__))
|
||||
|
||||
def __init__(self):
|
||||
super(MediaPlugin, self).__init__('media', __default_settings__, MediaMediaItem)
|
||||
|
|
|
@ -236,7 +236,7 @@ class ImpressDocument(PresentationDocument):
|
|||
try:
|
||||
self.document = desktop.loadComponentFromURL(url, '_blank', 0, properties)
|
||||
except:
|
||||
log.warning('Failed to load presentation %s' % url)
|
||||
log.warning('Failed to load presentation {url}'.format(url=url))
|
||||
return False
|
||||
self.presentation = self.document.getPresentation()
|
||||
self.presentation.Display = ScreenList().current['number'] + 1
|
||||
|
@ -269,16 +269,16 @@ class ImpressDocument(PresentationDocument):
|
|||
for index in range(pages.getCount()):
|
||||
page = pages.getByIndex(index)
|
||||
doc.getCurrentController().setCurrentPage(page)
|
||||
url_path = '%s/%s.png' % (thumb_dir_url, str(index + 1))
|
||||
url_path = '{path}/{name}.png'.format(path=thumb_dir_url, name=str(index + 1))
|
||||
path = os.path.join(self.get_temp_folder(), str(index + 1) + '.png')
|
||||
try:
|
||||
doc.storeToURL(url_path, properties)
|
||||
self.convert_thumbnail(path, index + 1)
|
||||
delete_file(path)
|
||||
except ErrorCodeIOException as exception:
|
||||
log.exception('ERROR! ErrorCodeIOException %d' % exception.ErrCode)
|
||||
log.exception('ERROR! ErrorCodeIOException {error:d}'.format(error=exception.ErrCode))
|
||||
except:
|
||||
log.exception('%s - Unable to store openoffice preview' % path)
|
||||
log.exception('{path} - Unable to store openoffice preview'.format(path=path))
|
||||
|
||||
def create_property(self, name, value):
|
||||
"""
|
||||
|
|
|
@ -88,9 +88,10 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
file_types = self.controllers[controller].supports + self.controllers[controller].also_supports
|
||||
for file_type in file_types:
|
||||
if file_type not in file_type_string:
|
||||
file_type_string += '*.%s ' % file_type
|
||||
file_type_string += '*.{text} '.format(text=file_type)
|
||||
self.service_manager.supported_suffixes(file_type)
|
||||
self.on_new_file_masks = translate('PresentationPlugin.MediaItem', 'Presentations (%s)') % file_type_string
|
||||
self.on_new_file_masks = translate('PresentationPlugin.MediaItem',
|
||||
'Presentations ({text})').format(text=file_type_string)
|
||||
|
||||
def required_icons(self):
|
||||
"""
|
||||
|
@ -306,13 +307,13 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
os.path.join(doc.get_temp_folder(), 'mainslide001.png')):
|
||||
doc.load_presentation()
|
||||
i = 1
|
||||
image = os.path.join(doc.get_temp_folder(), 'mainslide%03d.png' % i)
|
||||
image = os.path.join(doc.get_temp_folder(), 'mainslide{number:0>3d}.png'.format(number=i))
|
||||
thumbnail = os.path.join(doc.get_thumbnail_folder(), 'slide%d.png' % i)
|
||||
while os.path.isfile(image):
|
||||
service_item.add_from_image(image, name, thumbnail=thumbnail)
|
||||
i += 1
|
||||
image = os.path.join(doc.get_temp_folder(), 'mainslide%03d.png' % i)
|
||||
thumbnail = os.path.join(doc.get_thumbnail_folder(), 'slide%d.png' % i)
|
||||
image = os.path.join(doc.get_temp_folder(), 'mainslide{number:0>3d}.png'.format(number=i))
|
||||
thumbnail = os.path.join(doc.get_thumbnail_folder(), 'slide{number:d}.png'.format(number=i))
|
||||
service_item.add_capability(ItemCapabilities.HasThumbnails)
|
||||
doc.close_presentation()
|
||||
return True
|
||||
|
@ -321,7 +322,8 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
if not remote:
|
||||
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
'The presentation %s no longer exists.') % filename)
|
||||
'The presentation {name} no longer exists.'
|
||||
).format(name=filename))
|
||||
return False
|
||||
else:
|
||||
service_item.processor = self.display_type_combo_box.currentText()
|
||||
|
@ -367,15 +369,16 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
critical_error_message_box(translate('PresentationPlugin.MediaItem',
|
||||
'Missing Presentation'),
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
'The presentation %s is incomplete, please reload.')
|
||||
% filename)
|
||||
'The presentation {name} is incomplete, '
|
||||
'please reload.').format(name=filename))
|
||||
return False
|
||||
else:
|
||||
# File is no longer present
|
||||
if not remote:
|
||||
critical_error_message_box(translate('PresentationPlugin.MediaItem', 'Missing Presentation'),
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
'The presentation %s no longer exists.') % filename)
|
||||
'The presentation {name} no longer exists.'
|
||||
).format(name=filename))
|
||||
return False
|
||||
|
||||
def find_controller_by_type(self, filename):
|
||||
|
|
|
@ -28,7 +28,7 @@ from PyQt5 import QtCore
|
|||
|
||||
from openlp.core.common import Registry
|
||||
from openlp.core.ui import HideMode
|
||||
from openlp.core.lib import ServiceItemContext, ServiceItem
|
||||
from openlp.core.lib import ServiceItemContext
|
||||
from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -48,14 +48,14 @@ class Controller(object):
|
|||
self.is_live = live
|
||||
self.doc = None
|
||||
self.hide_mode = None
|
||||
log.info('%s controller loaded' % live)
|
||||
log.info('{name} controller loaded'.format(name=live))
|
||||
|
||||
def add_handler(self, controller, file, hide_mode, slide_no):
|
||||
"""
|
||||
Add a handler, which is an instance of a presentation and slidecontroller combination. If the slidecontroller
|
||||
has a display then load the presentation.
|
||||
"""
|
||||
log.debug('Live = %s, add_handler %s' % (self.is_live, file))
|
||||
log.debug('Live = {live}, add_handler {handler}'.format(live=self.is_live, handler=file))
|
||||
self.controller = controller
|
||||
if self.doc is not None:
|
||||
self.shutdown()
|
||||
|
@ -67,7 +67,7 @@ class Controller(object):
|
|||
return
|
||||
self.doc.slidenumber = slide_no
|
||||
self.hide_mode = hide_mode
|
||||
log.debug('add_handler, slide_number: %d' % slide_no)
|
||||
log.debug('add_handler, slide_number: {slide:d}'.format(slide=slide_no))
|
||||
if self.is_live:
|
||||
if hide_mode == HideMode.Screen:
|
||||
Registry().execute('live_display_hide', HideMode.Screen)
|
||||
|
@ -87,14 +87,14 @@ class Controller(object):
|
|||
"""
|
||||
Active the presentation, and show it on the screen. Use the last slide number.
|
||||
"""
|
||||
log.debug('Live = %s, activate' % self.is_live)
|
||||
log.debug('Live = {live}, activate'.format(live=self.is_live))
|
||||
if not self.doc:
|
||||
return False
|
||||
if self.doc.is_active():
|
||||
return True
|
||||
if not self.doc.is_loaded():
|
||||
if not self.doc.load_presentation():
|
||||
log.warning('Failed to activate %s' % self.doc.file_path)
|
||||
log.warning('Failed to activate {path}'.format(path=self.doc.file_path))
|
||||
return False
|
||||
if self.is_live:
|
||||
self.doc.start_presentation()
|
||||
|
@ -105,14 +105,14 @@ class Controller(object):
|
|||
if self.doc.is_active():
|
||||
return True
|
||||
else:
|
||||
log.warning('Failed to activate %s' % self.doc.file_path)
|
||||
log.warning('Failed to activate {path}'.format(path=self.doc.file_path))
|
||||
return False
|
||||
|
||||
def slide(self, slide):
|
||||
"""
|
||||
Go to a specific slide
|
||||
"""
|
||||
log.debug('Live = %s, slide' % self.is_live)
|
||||
log.debug('Live = {live}, slide'.format(live=self.is_live))
|
||||
if not self.doc:
|
||||
return
|
||||
if not self.is_live:
|
||||
|
@ -130,7 +130,7 @@ class Controller(object):
|
|||
"""
|
||||
Based on the handler passed at startup triggers the first slide.
|
||||
"""
|
||||
log.debug('Live = %s, first' % self.is_live)
|
||||
log.debug('Live = {live}, first'.format(live=self.is_live))
|
||||
if not self.doc:
|
||||
return
|
||||
if not self.is_live:
|
||||
|
@ -148,7 +148,7 @@ class Controller(object):
|
|||
"""
|
||||
Based on the handler passed at startup triggers the last slide.
|
||||
"""
|
||||
log.debug('Live = %s, last' % self.is_live)
|
||||
log.debug('Live = {live}, last'.format(live=self.is_live))
|
||||
if not self.doc:
|
||||
return
|
||||
if not self.is_live:
|
||||
|
@ -166,7 +166,7 @@ class Controller(object):
|
|||
"""
|
||||
Based on the handler passed at startup triggers the next slide event.
|
||||
"""
|
||||
log.debug('Live = %s, next' % self.is_live)
|
||||
log.debug('Live = {live}, next'.format(live=self.is_live))
|
||||
if not self.doc:
|
||||
return
|
||||
if not self.is_live:
|
||||
|
@ -191,7 +191,7 @@ class Controller(object):
|
|||
"""
|
||||
Based on the handler passed at startup triggers the previous slide event.
|
||||
"""
|
||||
log.debug('Live = %s, previous' % self.is_live)
|
||||
log.debug('Live = {live}, previous'.formta(live=self.is_live))
|
||||
if not self.doc:
|
||||
return
|
||||
if not self.is_live:
|
||||
|
@ -212,7 +212,7 @@ class Controller(object):
|
|||
"""
|
||||
Based on the handler passed at startup triggers slide show to shut down.
|
||||
"""
|
||||
log.debug('Live = %s, shutdown' % self.is_live)
|
||||
log.debug('Live = {live}, shutdown'.format(live=self.is_live))
|
||||
if not self.doc:
|
||||
return
|
||||
self.doc.close_presentation()
|
||||
|
@ -222,7 +222,7 @@ class Controller(object):
|
|||
"""
|
||||
Instruct the controller to blank the presentation.
|
||||
"""
|
||||
log.debug('Live = %s, blank' % self.is_live)
|
||||
log.debug('Live = {live}, blank'.format(live=self.is_live))
|
||||
self.hide_mode = hide_mode
|
||||
if not self.doc:
|
||||
return
|
||||
|
@ -243,7 +243,7 @@ class Controller(object):
|
|||
"""
|
||||
Instruct the controller to stop and hide the presentation.
|
||||
"""
|
||||
log.debug('Live = %s, stop' % self.is_live)
|
||||
log.debug('Live = {live}, stop'.format(live=self.is_live))
|
||||
# The document has not been loaded yet, so don't do anything. This can happen when going live with a
|
||||
# presentation while blanked to desktop.
|
||||
if not self.doc:
|
||||
|
@ -266,7 +266,7 @@ class Controller(object):
|
|||
"""
|
||||
Instruct the controller to unblank the presentation.
|
||||
"""
|
||||
log.debug('Live = %s, unblank' % self.is_live)
|
||||
log.debug('Live = {live}, unblank'.format(live=self.is_live))
|
||||
self.hide_mode = None
|
||||
if not self.doc:
|
||||
return
|
||||
|
@ -321,7 +321,7 @@ class MessageListener(object):
|
|||
"""
|
||||
Start of new presentation. Save the handler as any new presentations start here
|
||||
"""
|
||||
log.debug('Startup called with message %s' % message)
|
||||
log.debug('Startup called with message {text}'.format(text=message))
|
||||
is_live = message[1]
|
||||
item = message[0]
|
||||
hide_mode = message[2]
|
||||
|
@ -332,7 +332,7 @@ class MessageListener(object):
|
|||
# the conversion has already been done at this point.
|
||||
file_type = os.path.splitext(file.lower())[1][1:]
|
||||
if file_type in PDF_CONTROLLER_FILETYPES:
|
||||
log.debug('Converting from pdf/xps/oxps to images for serviceitem with file %s', file)
|
||||
log.debug('Converting from pdf/xps/oxps to images for serviceitem with file {name}'.format(name=file))
|
||||
# Create a copy of the original item, and then clear the original item so it can be filled with images
|
||||
item_cpy = copy.copy(item)
|
||||
item.__init__(None)
|
||||
|
|
|
@ -80,14 +80,14 @@ class PdfController(PresentationController):
|
|||
found_mutool = re.search('usage: mutool.*', decoded_line, re.IGNORECASE)
|
||||
if found_mutool:
|
||||
# Test that mutool contains mudraw
|
||||
if re.search('draw\s+--\s+convert document.*', runlog.decode(), re.IGNORECASE | re.MULTILINE):
|
||||
if re.search(r'draw\s+--\s+convert document.*', runlog.decode(), re.IGNORECASE | re.MULTILINE):
|
||||
program_type = 'mutool'
|
||||
break
|
||||
found_gs = re.search('GPL Ghostscript.*', decoded_line, re.IGNORECASE)
|
||||
if found_gs:
|
||||
program_type = 'gs'
|
||||
break
|
||||
log.debug('in check_binary, found: %s', program_type)
|
||||
log.debug('in check_binary, found: {text}'.format(text=program_type))
|
||||
return program_type
|
||||
|
||||
def check_available(self):
|
||||
|
@ -215,8 +215,8 @@ class PdfDocument(PresentationDocument):
|
|||
height = 0.0
|
||||
for line in runlog.splitlines():
|
||||
try:
|
||||
width = float(re.search('.*Size: x: (\d+\.?\d*), y: \d+.*', line.decode()).group(1))
|
||||
height = float(re.search('.*Size: x: \d+\.?\d*, y: (\d+\.?\d*).*', line.decode()).group(1))
|
||||
width = float(re.search(r'.*Size: x: (\d+\.?\d*), y: \d+.*', line.decode()).group(1))
|
||||
height = float(re.search(r'.*Size: x: \d+\.?\d*, y: (\d+\.?\d*).*', line.decode()).group(1))
|
||||
break
|
||||
except AttributeError:
|
||||
continue
|
||||
|
@ -255,11 +255,13 @@ class PdfDocument(PresentationDocument):
|
|||
os.makedirs(self.get_temp_folder())
|
||||
if self.controller.mudrawbin:
|
||||
log.debug('loading presentation using mudraw')
|
||||
# TODO: Find out where the string conversion actually happens
|
||||
runlog = check_output([self.controller.mudrawbin, '-w', str(size.width()), '-h', str(size.height()),
|
||||
'-o', os.path.join(self.get_temp_folder(), 'mainslide%03d.png'), self.file_path],
|
||||
startupinfo=self.startupinfo)
|
||||
elif self.controller.mutoolbin:
|
||||
log.debug('loading presentation using mutool')
|
||||
# TODO: Find out where the string convertsion actually happens
|
||||
runlog = check_output([self.controller.mutoolbin, 'draw', '-w', str(size.width()), '-h',
|
||||
str(size.height()),
|
||||
'-o', os.path.join(self.get_temp_folder(), 'mainslide%03d.png'), self.file_path],
|
||||
|
@ -267,6 +269,7 @@ class PdfDocument(PresentationDocument):
|
|||
elif self.controller.gsbin:
|
||||
log.debug('loading presentation using gs')
|
||||
resolution = self.gs_get_resolution(size)
|
||||
# TODO: Find out where the string conversion actually happens
|
||||
runlog = check_output([self.controller.gsbin, '-dSAFER', '-dNOPAUSE', '-dBATCH', '-sDEVICE=png16m',
|
||||
'-r' + str(resolution), '-dTextAlphaBits=4', '-dGraphicsAlphaBits=4',
|
||||
'-sOutputFile=' + os.path.join(self.get_temp_folder(), 'mainslide%03d.png'),
|
||||
|
|
|
@ -179,7 +179,7 @@ class PowerpointDocument(PresentationDocument):
|
|||
if not self.presentation.Slides(num + 1).SlideShowTransition.Hidden:
|
||||
self.index_map[key] = num + 1
|
||||
self.presentation.Slides(num + 1).Export(
|
||||
os.path.join(self.get_thumbnail_folder(), 'slide%d.png' % (key)), 'png', 320, 240)
|
||||
os.path.join(self.get_thumbnail_folder(), 'slide{key:d}.png'.format(key=key)), 'png', 320, 240)
|
||||
key += 1
|
||||
self.slide_count = key - 1
|
||||
|
||||
|
@ -345,8 +345,9 @@ class PowerpointDocument(PresentationDocument):
|
|||
# Find the presentation window and save the handle for later
|
||||
self.presentation_hwnd = None
|
||||
if ppt_window:
|
||||
log.debug('main display size: y=%d, height=%d, x=%d, width=%d'
|
||||
% (size.y(), size.height(), size.x(), size.width()))
|
||||
log.debug('main display size: y={y:d}, height={height:d}, '
|
||||
'x={x:d}, width={width:d}'.format(y=size.y(), height=size.height(),
|
||||
x=size.x(), width=size.width()))
|
||||
win32gui.EnumWindows(self._window_enum_callback, size)
|
||||
# Make sure powerpoint doesn't steal focus, unless we're on a single screen setup
|
||||
if len(ScreenList().screen_list) > 1:
|
||||
|
@ -361,10 +362,18 @@ class PowerpointDocument(PresentationDocument):
|
|||
# it is the powerpoint presentation window.
|
||||
(left, top, right, bottom) = win32gui.GetWindowRect(hwnd)
|
||||
window_title = win32gui.GetWindowText(hwnd)
|
||||
log.debug('window size: left=%d, top=%d, right=%d, width=%d' % (left, top, right, bottom))
|
||||
log.debug('compare size: %d and %d, %d and %d, %d and %d, %d and %d'
|
||||
% (size.y(), top, size.height(), (bottom - top), size.x(), left, size.width(), (right - left)))
|
||||
log.debug('window title: %s' % window_title)
|
||||
log.debug('window size: left={left:d}, top={top:d}, '
|
||||
'right={right:d}, bottom={bottom:d}'.format(left=left, top=top, right=right, bottom=bottom))
|
||||
log.debug('compare size: {y:d} and {top:d}, {height:d} and {vertical:d}, '
|
||||
'{x:d} and {left}, {width:d} and {horizontal:d}'.format(y=size.y(),
|
||||
top=top,
|
||||
height=size.height(),
|
||||
vertical=(bottom - top),
|
||||
x=size.x(),
|
||||
left=left,
|
||||
width=size.width(),
|
||||
horizontal=(right - left)))
|
||||
log.debug('window title: {title}'.format(title=window_title))
|
||||
filename_root, filename_ext = os.path.splitext(os.path.basename(self.file_path))
|
||||
if size.y() == top and size.height() == (bottom - top) and size.x() == left and \
|
||||
size.width() == (right - left) and filename_root in window_title:
|
||||
|
@ -416,8 +425,8 @@ class PowerpointDocument(PresentationDocument):
|
|||
and self.get_slide_number() == slide_no:
|
||||
click_index = self.presentation.SlideShowWindow.View.GetClickIndex()
|
||||
click_count = self.presentation.SlideShowWindow.View.GetClickCount()
|
||||
log.debug('We are already on this slide - go to next effect if any left, idx: %d, count: %d'
|
||||
% (click_index, click_count))
|
||||
log.debug('We are already on this slide - go to next effect if any left, idx: '
|
||||
'{index:d}, count: {count:d}'.format(index=click_index, count=click_count))
|
||||
if click_index < click_count:
|
||||
self.next_step()
|
||||
else:
|
||||
|
|
|
@ -148,7 +148,7 @@ class PptviewDocument(PresentationDocument):
|
|||
return
|
||||
log.debug('create_thumbnails proceeding')
|
||||
for idx in range(self.get_slide_count()):
|
||||
path = '%s\\slide%s.bmp' % (self.get_temp_folder(), str(idx + 1))
|
||||
path = '{folder}\\slide{index}.bmp'.format(folder=self.get_temp_folder(), index=str(idx + 1))
|
||||
self.convert_thumbnail(path, idx + 1)
|
||||
|
||||
def create_titles_and_notes(self):
|
||||
|
@ -181,13 +181,13 @@ class PptviewDocument(PresentationDocument):
|
|||
index = -1
|
||||
list_to_add = None
|
||||
# check if it is a slide
|
||||
match = re.search("slides/slide(.+)\.xml", zip_info.filename)
|
||||
match = re.search(r'slides/slide(.+)\.xml', zip_info.filename)
|
||||
if match:
|
||||
index = int(match.group(1)) - 1
|
||||
node_type = 'ctrTitle'
|
||||
list_to_add = titles
|
||||
# or a note
|
||||
match = re.search("notesSlides/notesSlide(.+)\.xml", zip_info.filename)
|
||||
match = re.search(r'notesSlides/notesSlide(.+)\.xml', zip_info.filename)
|
||||
if match:
|
||||
index = int(match.group(1)) - 1
|
||||
node_type = 'body'
|
||||
|
|
|
@ -278,7 +278,7 @@ class PresentationDocument(object):
|
|||
prefix = 'live'
|
||||
else:
|
||||
prefix = 'preview'
|
||||
Registry().execute('slidecontroller_%s_change' % prefix, self.slide_number - 1)
|
||||
Registry().execute('slidecontroller_{prefix}_change'.format(prefix=prefix), self.slide_number - 1)
|
||||
|
||||
def get_slide_text(self, slide_no):
|
||||
"""
|
||||
|
@ -312,7 +312,7 @@ class PresentationDocument(object):
|
|||
log.exception('Failed to open/read existing titles file')
|
||||
titles = []
|
||||
for slide_no, title in enumerate(titles, 1):
|
||||
notes_file = os.path.join(self.get_thumbnail_folder(), 'slideNotes%d.txt' % slide_no)
|
||||
notes_file = os.path.join(self.get_thumbnail_folder(), 'slideNotes{number:d}.txt'.format(number=slide_no))
|
||||
note = ''
|
||||
if os.path.exists(notes_file):
|
||||
try:
|
||||
|
@ -335,7 +335,8 @@ class PresentationDocument(object):
|
|||
fo.writelines(titles)
|
||||
if notes:
|
||||
for slide_no, note in enumerate(notes, 1):
|
||||
notes_file = os.path.join(self.get_thumbnail_folder(), 'slideNotes%d.txt' % slide_no)
|
||||
notes_file = os.path.join(self.get_thumbnail_folder(),
|
||||
'slideNotes{number:d}.txt'.format(number=slide_no))
|
||||
with open(notes_file, mode='wt', encoding='utf-8') as fn:
|
||||
fn.write(note)
|
||||
|
||||
|
|
|
@ -137,7 +137,8 @@ class PresentationTab(SettingsTab):
|
|||
if checkbox.isEnabled():
|
||||
checkbox.setText(controller.name)
|
||||
else:
|
||||
checkbox.setText(translate('PresentationPlugin.PresentationTab', '%s (unavailable)') % controller.name)
|
||||
checkbox.setText(translate('PresentationPlugin.PresentationTab',
|
||||
'{name} (unavailable)').format(name=controller.name))
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
|
|
|
@ -124,15 +124,15 @@ class PresentationPlugin(Plugin):
|
|||
log.debug('check_pre_conditions')
|
||||
controller_dir = os.path.join(AppLocation.get_directory(AppLocation.PluginsDir), 'presentations', 'lib')
|
||||
for filename in os.listdir(controller_dir):
|
||||
if filename.endswith('controller.py') and not filename == 'presentationcontroller.py':
|
||||
if filename.endswith('controller.py') and filename != 'presentationcontroller.py':
|
||||
path = os.path.join(controller_dir, filename)
|
||||
if os.path.isfile(path):
|
||||
module_name = 'openlp.plugins.presentations.lib.' + os.path.splitext(filename)[0]
|
||||
log.debug('Importing controller %s', module_name)
|
||||
log.debug('Importing controller {name}'.format(name=module_name))
|
||||
try:
|
||||
__import__(module_name, globals(), locals(), [])
|
||||
except ImportError:
|
||||
log.warning('Failed to import %s on path %s', module_name, path)
|
||||
log.warning('Failed to import {name} on path {path}'.format(name=module_name, path=path))
|
||||
controller_classes = PresentationController.__subclasses__()
|
||||
for controller_class in controller_classes:
|
||||
controller = controller_class(self)
|
||||
|
|
|
@ -141,7 +141,8 @@ class HttpRouter(RegistryProperties):
|
|||
"""
|
||||
Initialise the router stack and any other variables.
|
||||
"""
|
||||
auth_code = "%s:%s" % (Settings().value('remotes/user id'), Settings().value('remotes/password'))
|
||||
auth_code = "{user}:{password}".format(user=Settings().value('remotes/user id'),
|
||||
password=Settings().value('remotes/password'))
|
||||
try:
|
||||
self.auth = base64.b64encode(auth_code)
|
||||
except TypeError:
|
||||
|
@ -189,7 +190,7 @@ class HttpRouter(RegistryProperties):
|
|||
if self.headers['Authorization'] is None:
|
||||
self.do_authorisation()
|
||||
self.wfile.write(bytes('no auth header received', 'UTF-8'))
|
||||
elif self.headers['Authorization'] == 'Basic %s' % self.auth:
|
||||
elif self.headers['Authorization'] == 'Basic {auth}'.format(auth=self.auth):
|
||||
self.do_http_success()
|
||||
self.call_function(function, *args)
|
||||
else:
|
||||
|
@ -221,13 +222,17 @@ class HttpRouter(RegistryProperties):
|
|||
self.request_data = None
|
||||
url_path_split = urlparse(url_path)
|
||||
url_query = parse_qs(url_path_split.query)
|
||||
# GET
|
||||
if 'data' in url_query.keys():
|
||||
self.request_data = url_query['data'][0]
|
||||
# Get data from HTTP request
|
||||
if self.command == 'GET':
|
||||
if 'data' in url_query.keys():
|
||||
self.request_data = url_query['data'][0]
|
||||
elif self.command == 'POST':
|
||||
content_len = int(self.headers['content-length'])
|
||||
self.request_data = self.rfile.read(content_len).decode("utf-8")
|
||||
for route, func in self.routes:
|
||||
match = re.match(route, url_path_split.path)
|
||||
if match:
|
||||
log.debug('Route "%s" matched "%s"', route, url_path)
|
||||
log.debug('Route "{route}" matched "{path}"'.format(route=route, path=url_path))
|
||||
args = []
|
||||
for param in match.groups():
|
||||
args.append(param)
|
||||
|
@ -314,9 +319,9 @@ class HttpRouter(RegistryProperties):
|
|||
remote = translate('RemotePlugin.Mobile', 'Remote')
|
||||
stage = translate('RemotePlugin.Mobile', 'Stage')
|
||||
self.template_vars = {
|
||||
'app_title': "OpenLP | %s" % remote,
|
||||
'stage_title': "OpenLP | %s" % stage,
|
||||
'live_title': "OpenLP | %s" % UiStrings().Live,
|
||||
'app_title': "OpenLP | {remote}".format(remote=remote),
|
||||
'stage_title': "OpenLP | {stage}".format(stage=stage),
|
||||
'live_title': "OpenLP | {live}".format(live=UiStrings().Live),
|
||||
'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
|
||||
'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
|
||||
'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
|
||||
|
@ -349,7 +354,7 @@ class HttpRouter(RegistryProperties):
|
|||
:param file_name: file name with path
|
||||
:return:
|
||||
"""
|
||||
log.debug('serve file request %s' % file_name)
|
||||
log.debug('serve file request {name}'.format(name=file_name))
|
||||
parts = file_name.split('/')
|
||||
if len(parts) == 1:
|
||||
file_name = os.path.join(parts[0], 'stage.html')
|
||||
|
@ -376,10 +381,10 @@ class HttpRouter(RegistryProperties):
|
|||
content = Template(filename=path, input_encoding='utf-8', output_encoding='utf-8').render(**variables)
|
||||
else:
|
||||
file_handle = open(path, 'rb')
|
||||
log.debug('Opened %s' % path)
|
||||
log.debug('Opened {path}'.format(path=path))
|
||||
content = file_handle.read()
|
||||
except IOError:
|
||||
log.exception('Failed to open %s' % path)
|
||||
log.exception('Failed to open {path}'.format(path=path))
|
||||
return self.do_not_found()
|
||||
finally:
|
||||
if file_handle:
|
||||
|
@ -397,13 +402,11 @@ class HttpRouter(RegistryProperties):
|
|||
Ultimately for i18n, this could first look for xx/file.html before falling back to file.html.
|
||||
where xx is the language, e.g. 'en'
|
||||
"""
|
||||
log.debug('serve file request %s' % file_name)
|
||||
log.debug('serve file request {name}'.format(name=file_name))
|
||||
if not file_name:
|
||||
file_name = 'index.html'
|
||||
elif file_name == 'stage':
|
||||
file_name = 'stage.html'
|
||||
elif file_name == 'main':
|
||||
file_name = 'main.html'
|
||||
if '.' not in file_name:
|
||||
file_name += '.html'
|
||||
if file_name.startswith('/'):
|
||||
file_name = file_name[1:]
|
||||
path = os.path.normpath(os.path.join(self.html_dir, file_name))
|
||||
|
@ -430,7 +433,9 @@ class HttpRouter(RegistryProperties):
|
|||
:param dimensions: image size
|
||||
:param controller_name: controller to be called
|
||||
"""
|
||||
log.debug('serve thumbnail %s/thumbnails%s/%s' % (controller_name, dimensions, file_name))
|
||||
log.debug('serve thumbnail {cname}/thumbnails{dim}/{fname}'.format(cname=controller_name,
|
||||
dim=dimensions,
|
||||
fname=file_name))
|
||||
supported_controllers = ['presentations', 'images']
|
||||
# -1 means use the default dimension in ImageManager
|
||||
width = -1
|
||||
|
@ -536,7 +541,7 @@ class HttpRouter(RegistryProperties):
|
|||
|
||||
:param var: variable - not used
|
||||
"""
|
||||
log.debug("controller_text var = %s" % var)
|
||||
log.debug("controller_text var = {var}".format(var=var))
|
||||
current_item = self.live_controller.service_item
|
||||
data = []
|
||||
if current_item:
|
||||
|
@ -591,7 +596,8 @@ class HttpRouter(RegistryProperties):
|
|||
:param display_type: This is the type of slide controller, either ``preview`` or ``live``.
|
||||
:param action: The action to perform.
|
||||
"""
|
||||
event = getattr(self.live_controller, 'slidecontroller_%s_%s' % (display_type, action))
|
||||
event = getattr(self.live_controller, 'slidecontroller_{display}_{action}'.format(display=display_type,
|
||||
action=action))
|
||||
if self.request_data:
|
||||
try:
|
||||
data = json.loads(self.request_data)['request']['id']
|
||||
|
@ -620,7 +626,7 @@ class HttpRouter(RegistryProperties):
|
|||
|
||||
:param action: The action to perform.
|
||||
"""
|
||||
event = getattr(self.service_manager, 'servicemanager_%s_item' % action)
|
||||
event = getattr(self.service_manager, 'servicemanager_{action}_item'.format(action=action))
|
||||
if self.request_data:
|
||||
try:
|
||||
data = int(json.loads(self.request_data)['request']['id'])
|
||||
|
@ -677,7 +683,7 @@ class HttpRouter(RegistryProperties):
|
|||
return self.do_http_error()
|
||||
plugin = self.plugin_manager.get_plugin_by_name(plugin_name)
|
||||
if plugin.status == PluginStatus.Active and plugin.media_item:
|
||||
getattr(plugin.media_item, '%s_go_live' % plugin_name).emit([request_id, True])
|
||||
getattr(plugin.media_item, '{name}_go_live'.format(name=plugin_name)).emit([request_id, True])
|
||||
return self.do_http_success()
|
||||
|
||||
def add_to_service(self, plugin_name):
|
||||
|
@ -693,5 +699,5 @@ class HttpRouter(RegistryProperties):
|
|||
plugin = self.plugin_manager.get_plugin_by_name(plugin_name)
|
||||
if plugin.status == PluginStatus.Active and plugin.media_item:
|
||||
item_id = plugin.media_item.create_item_from_id(request_id)
|
||||
getattr(plugin.media_item, '%s_add_to_service' % plugin_name).emit([item_id, True])
|
||||
getattr(plugin.media_item, '{name}_add_to_service'.format(name=plugin_name)).emit([item_id, True])
|
||||
self.do_http_success()
|
||||
|
|
|
@ -136,11 +136,13 @@ class OpenLPServer(RegistryProperties):
|
|||
while loop < 4:
|
||||
try:
|
||||
self.httpd = server_class((address, port), CustomHandler)
|
||||
log.debug("Server started for class %s %s %d" % (server_class, address, port))
|
||||
log.debug("Server started for class {name} {address} {port:d}".format(name=server_class,
|
||||
address=address,
|
||||
port=port))
|
||||
break
|
||||
except OSError:
|
||||
log.debug("failed to start http server thread state %d %s" %
|
||||
(loop, self.http_thread.isRunning()))
|
||||
log.debug("failed to start http server thread state "
|
||||
"{loop:d} {running}".format(loop=loop, running=self.http_thread.isRunning()))
|
||||
loop += 1
|
||||
time.sleep(0.1)
|
||||
except:
|
||||
|
@ -167,7 +169,6 @@ class HTTPSServer(HTTPServer):
|
|||
local_data = AppLocation.get_directory(AppLocation.DataDir)
|
||||
self.socket = ssl.SSLSocket(
|
||||
sock=socket.socket(self.address_family, self.socket_type),
|
||||
ssl_version=ssl.PROTOCOL_TLSv1_2,
|
||||
certfile=os.path.join(local_data, 'remotes', 'openlp.crt'),
|
||||
keyfile=os.path.join(local_data, 'remotes', 'openlp.key'),
|
||||
server_side=True)
|
||||
|
|
|
@ -192,14 +192,14 @@ class RemoteTab(SettingsTab):
|
|||
'Show thumbnails of non-text slides in remote and stage view.'))
|
||||
self.android_app_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'Android App'))
|
||||
self.android_qr_description_label.setText(
|
||||
translate('RemotePlugin.RemoteTab', 'Scan the QR code or click <a href="%s">download</a> to install the '
|
||||
'Android app from Google Play.') %
|
||||
'https://play.google.com/store/apps/details?id=org.openlp.android2')
|
||||
translate('RemotePlugin.RemoteTab',
|
||||
'Scan the QR code or click <a href="{qr}">download</a> to install the Android app from Google '
|
||||
'Play.').format(qr='https://play.google.com/store/apps/details?id=org.openlp.android2'))
|
||||
self.ios_app_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'iOS App'))
|
||||
self.ios_qr_description_label.setText(
|
||||
translate('RemotePlugin.RemoteTab', 'Scan the QR code or click <a href="%s">download</a> to install the '
|
||||
'iOS app from the App Store.') %
|
||||
'https://itunes.apple.com/app/id1096218725')
|
||||
translate('RemotePlugin.RemoteTab',
|
||||
'Scan the QR code or click <a href="{qr}">download</a> to install the iOS app from the App '
|
||||
'Store.').format(qr='https://itunes.apple.com/app/id1096218725'))
|
||||
self.https_settings_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'HTTPS Server'))
|
||||
self.https_error_label.setText(
|
||||
translate('RemotePlugin.RemoteTab', 'Could not find an SSL certificate. The HTTPS server will not be '
|
||||
|
@ -217,18 +217,18 @@ class RemoteTab(SettingsTab):
|
|||
Update the display based on the data input on the screen
|
||||
"""
|
||||
ip_address = self.get_ip_address(self.address_edit.text())
|
||||
http_url = 'http://%s:%s/' % (ip_address, self.port_spin_box.value())
|
||||
https_url = 'https://%s:%s/' % (ip_address, self.https_port_spin_box.value())
|
||||
self.remote_url.setText('<a href="%s">%s</a>' % (http_url, http_url))
|
||||
self.remote_https_url.setText('<a href="%s">%s</a>' % (https_url, https_url))
|
||||
http_url = 'http://{url}:{text}/'.format(url=ip_address, text=self.port_spin_box.value())
|
||||
https_url = 'https://{url}:{text}/'.format(url=ip_address, text=self.https_port_spin_box.value())
|
||||
self.remote_url.setText('<a href="{url}">{url}</a>'.format(url=http_url))
|
||||
self.remote_https_url.setText('<a href="{url}">{url}</a>'.format(url=https_url))
|
||||
http_url_temp = http_url + 'stage'
|
||||
https_url_temp = https_url + 'stage'
|
||||
self.stage_url.setText('<a href="%s">%s</a>' % (http_url_temp, http_url_temp))
|
||||
self.stage_https_url.setText('<a href="%s">%s</a>' % (https_url_temp, https_url_temp))
|
||||
self.stage_url.setText('<a href="{url}">{url}</a>'.format(url=http_url_temp))
|
||||
self.stage_https_url.setText('<a href="{url}">{url}</a>'.format(url=https_url_temp))
|
||||
http_url_temp = http_url + 'main'
|
||||
https_url_temp = https_url + 'main'
|
||||
self.live_url.setText('<a href="%s">%s</a>' % (http_url_temp, http_url_temp))
|
||||
self.live_https_url.setText('<a href="%s">%s</a>' % (https_url_temp, https_url_temp))
|
||||
self.live_url.setText('<a href="{url}">{url}</a>'.format(url=http_url_temp))
|
||||
self.live_https_url.setText('<a href="{url}">{url}</a>'.format(url=https_url_temp))
|
||||
|
||||
def get_ip_address(self, ip_address):
|
||||
"""
|
||||
|
|
|
@ -130,6 +130,7 @@ class DuplicateSongRemovalForm(OpenLPWizard, RegistryProperties):
|
|||
Song wizard localisation.
|
||||
"""
|
||||
self.setWindowTitle(translate('Wizard', 'Wizard'))
|
||||
# TODO: Check format() using template strings
|
||||
self.title_label.setText(WizardStrings.HeaderStyle % translate('OpenLP.Ui',
|
||||
'Welcome to the Duplicate Song Removal Wizard'))
|
||||
self.information_label.setText(
|
||||
|
@ -148,8 +149,8 @@ class DuplicateSongRemovalForm(OpenLPWizard, RegistryProperties):
|
|||
Set the wizard review page header text.
|
||||
"""
|
||||
self.review_page.setTitle(
|
||||
translate('Wizard', 'Review duplicate songs (%s/%s)') %
|
||||
(self.review_current_count, self.review_total_count))
|
||||
translate('Wizard', 'Review duplicate songs ({current}/{total})').format(current=self.review_current_count,
|
||||
total=self.review_total_count))
|
||||
|
||||
def custom_page_changed(self, page_id):
|
||||
"""
|
||||
|
|
|
@ -50,7 +50,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
"""
|
||||
Class to manage the editing of a song
|
||||
"""
|
||||
log.info('%s EditSongForm loaded', __name__)
|
||||
log.info('{name} EditSongForm loaded'.format(name=__name__))
|
||||
|
||||
def __init__(self, media_item, parent, manager):
|
||||
"""
|
||||
|
@ -185,20 +185,23 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
verse = verse.data(QtCore.Qt.UserRole)
|
||||
if verse not in verse_names:
|
||||
verses.append(verse)
|
||||
verse_names.append('%s%s' % (VerseType.translated_tag(verse[0]), verse[1:]))
|
||||
verse_names.append('{verse1}{verse2}'.format(verse1=VerseType.translated_tag(verse[0]),
|
||||
verse2=verse[1:]))
|
||||
for count, item in enumerate(order):
|
||||
if item not in verses:
|
||||
invalid_verses.append(order_names[count])
|
||||
if invalid_verses:
|
||||
valid = create_separated_list(verse_names)
|
||||
if len(invalid_verses) > 1:
|
||||
msg = translate('SongsPlugin.EditSongForm', 'There are no verses corresponding to "%(invalid)s". '
|
||||
'Valid entries are %(valid)s.\nPlease enter the verses separated by spaces.') % \
|
||||
{'invalid': ', '.join(invalid_verses), 'valid': valid}
|
||||
msg = translate('SongsPlugin.EditSongForm',
|
||||
'There are no verses corresponding to "{invalid}". Valid entries are {valid}.\n'
|
||||
'Please enter the verses separated by spaces.'
|
||||
).format(invalid=', '.join(invalid_verses), valid=valid)
|
||||
else:
|
||||
msg = translate('SongsPlugin.EditSongForm', 'There is no verse corresponding to "%(invalid)s".'
|
||||
'Valid entries are %(valid)s.\nPlease enter the verses separated by spaces.') % \
|
||||
{'invalid': invalid_verses[0], 'valid': valid}
|
||||
msg = translate('SongsPlugin.EditSongForm',
|
||||
'There is no verse corresponding to "{invalid}". Valid entries are {valid}.\n'
|
||||
'Please enter the verses separated by spaces.').format(invalid=invalid_verses[0],
|
||||
valid=valid)
|
||||
critical_error_message_box(title=translate('SongsPlugin.EditSongForm', 'Invalid Verse Order'),
|
||||
message=msg)
|
||||
return len(invalid_verses) == 0
|
||||
|
@ -242,23 +245,24 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
field = item.data(QtCore.Qt.UserRole)
|
||||
verse_tags.append(field)
|
||||
if not self._validate_tags(tags):
|
||||
misplaced_tags.append('%s %s' % (VerseType.translated_name(field[0]), field[1:]))
|
||||
misplaced_tags.append('{field1} {field2}'.format(field1=VerseType.translated_name(field[0]),
|
||||
field2=field[1:]))
|
||||
if misplaced_tags:
|
||||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.EditSongForm',
|
||||
'There are misplaced formatting tags in the following verses:\n\n%s\n\n'
|
||||
'Please correct these tags before continuing.' % ', '.join(misplaced_tags)))
|
||||
'There are misplaced formatting tags in the following verses:\n\n{tag}\n\n'
|
||||
'Please correct these tags before continuing.').format(tag=', '.join(misplaced_tags)))
|
||||
return False
|
||||
for tag in verse_tags:
|
||||
if verse_tags.count(tag) > 26:
|
||||
# lp#1310523: OpenLyrics allows only a-z variants of one verse:
|
||||
# http://openlyrics.info/dataformat.html#verse-name
|
||||
critical_error_message_box(message=translate(
|
||||
'SongsPlugin.EditSongForm', 'You have %(count)s verses named %(name)s %(number)s. '
|
||||
'You can have at most 26 verses with the same name' %
|
||||
{'count': verse_tags.count(tag),
|
||||
'name': VerseType.translated_name(tag[0]),
|
||||
'number': tag[1:]}))
|
||||
'SongsPlugin.EditSongForm',
|
||||
'You have {count} verses named {name} {number}. You can have at most '
|
||||
'26 verses with the same name').format(count=verse_tags.count(tag),
|
||||
name=VerseType.translated_name(tag[0]),
|
||||
number=tag[1:]))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
@ -313,7 +317,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
self.song.verse_order = re.sub('([' + verse.upper() + verse.lower() + '])(\W|$)',
|
||||
r'\g<1>1\2', self.song.verse_order)
|
||||
except:
|
||||
log.exception('Problem processing song Lyrics \n%s', sxml.dump_xml())
|
||||
log.exception('Problem processing song Lyrics \n{xml}'.forma(xml=sxml.dump_xml()))
|
||||
raise
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
|
@ -492,7 +496,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
verse[0]['type'] = VerseType.tags[index]
|
||||
if verse[0]['label'] == '':
|
||||
verse[0]['label'] = '1'
|
||||
verse_def = '%s%s' % (verse[0]['type'], verse[0]['label'])
|
||||
verse_def = '{verse}{label}'.format(verse=verse[0]['type'], label=verse[0]['label'])
|
||||
item = QtWidgets.QTableWidgetItem(verse[1])
|
||||
item.setData(QtCore.Qt.UserRole, verse_def)
|
||||
self.verse_list_widget.setItem(count, 0, item)
|
||||
|
@ -501,7 +505,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
for count, verse in enumerate(verses):
|
||||
self.verse_list_widget.setRowCount(self.verse_list_widget.rowCount() + 1)
|
||||
item = QtWidgets.QTableWidgetItem(verse)
|
||||
verse_def = '%s%s' % (VerseType.tags[VerseType.Verse], str(count + 1))
|
||||
verse_def = '{verse}{count:d}'.format(verse=VerseType.tags[VerseType.Verse], count=(count + 1))
|
||||
item.setData(QtCore.Qt.UserRole, verse_def)
|
||||
self.verse_list_widget.setItem(count, 0, item)
|
||||
if self.song.verse_order:
|
||||
|
@ -514,7 +518,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
if verse_index is None:
|
||||
verse_index = VerseType.from_tag(verse_def[0])
|
||||
verse_tag = VerseType.translated_tags[verse_index].upper()
|
||||
translated.append('%s%s' % (verse_tag, verse_def[1:]))
|
||||
translated.append('{tag}{verse}'.format(tag=verse_tag, verse=verse_def[1:]))
|
||||
self.verse_order_edit.setText(' '.join(translated))
|
||||
else:
|
||||
self.verse_order_edit.setText('')
|
||||
|
@ -554,7 +558,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
item = self.verse_list_widget.item(row, 0)
|
||||
verse_def = item.data(QtCore.Qt.UserRole)
|
||||
verse_tag = VerseType.translated_tag(verse_def[0])
|
||||
row_def = '%s%s' % (verse_tag, verse_def[1:])
|
||||
row_def = '{tag}{verse}'.format(tag=verse_tag, verse=verse_def[1:])
|
||||
row_label.append(row_def)
|
||||
self.verse_list_widget.setVerticalHeaderLabels(row_label)
|
||||
self.verse_list_widget.resizeRowsToContents()
|
||||
|
@ -742,7 +746,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
self.verse_form.set_verse('', True)
|
||||
if self.verse_form.exec():
|
||||
after_text, verse_tag, verse_num = self.verse_form.get_verse()
|
||||
verse_def = '%s%s' % (verse_tag, verse_num)
|
||||
verse_def = '{tag}{number}'.format(tag=verse_tag, number=verse_num)
|
||||
item = QtWidgets.QTableWidgetItem(after_text)
|
||||
item.setData(QtCore.Qt.UserRole, verse_def)
|
||||
item.setText(after_text)
|
||||
|
@ -760,7 +764,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
self.verse_form.set_verse(temp_text, True, verse_id)
|
||||
if self.verse_form.exec():
|
||||
after_text, verse_tag, verse_num = self.verse_form.get_verse()
|
||||
verse_def = '%s%s' % (verse_tag, verse_num)
|
||||
verse_def = '{tag}{number}'.format(tag=verse_tag, number=verse_num)
|
||||
item.setData(QtCore.Qt.UserRole, verse_def)
|
||||
item.setText(after_text)
|
||||
# number of lines has changed, repaint the list moving the data
|
||||
|
@ -793,7 +797,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
field = item.data(QtCore.Qt.UserRole)
|
||||
verse_tag = VerseType.translated_name(field[0])
|
||||
verse_num = field[1:]
|
||||
verse_list += '---[%s:%s]---\n' % (verse_tag, verse_num)
|
||||
verse_list += '---[{tag}:{number}]---\n'.format(tag=verse_tag, number=verse_num)
|
||||
verse_list += item.text()
|
||||
verse_list += '\n'
|
||||
self.verse_form.set_verse(verse_list)
|
||||
|
@ -828,7 +832,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
verse_num = match.group(1)
|
||||
else:
|
||||
verse_num = '1'
|
||||
verse_def = '%s%s' % (verse_tag, verse_num)
|
||||
verse_def = '{tag}{number}'.format(tag=verse_tag, number=verse_num)
|
||||
else:
|
||||
if parts.endswith('\n'):
|
||||
parts = parts.rstrip('\n')
|
||||
|
@ -919,7 +923,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
"""
|
||||
Loads file(s) from the filesystem.
|
||||
"""
|
||||
filters = '%s (*)' % UiStrings().AllFiles
|
||||
filters = '{text} (*)'.format(text=UiStrings().AllFiles)
|
||||
file_names = FileDialog.getOpenFileNames(self, translate('SongsPlugin.EditSongForm', 'Open File(s)'), '',
|
||||
filters)
|
||||
for filename in file_names:
|
||||
|
@ -1027,7 +1031,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
for item in order_text.split():
|
||||
verse_tag = VerseType.tags[VerseType.from_translated_tag(item[0])]
|
||||
verse_num = item[1:].lower()
|
||||
order.append('%s%s' % (verse_tag, verse_num))
|
||||
order.append('{tag}{number}'.format(tag=verse_tag, number=verse_num))
|
||||
self.song.verse_order = ' '.join(order)
|
||||
self.song.ccli_number = self.ccli_number_edit.text()
|
||||
theme_name = self.theme_combo_box.currentText()
|
||||
|
@ -1082,12 +1086,12 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
try:
|
||||
os.remove(audio)
|
||||
except:
|
||||
log.exception('Could not remove file: %s', audio)
|
||||
log.exception('Could not remove file: {audio}'.format(audio=audio))
|
||||
if not files:
|
||||
try:
|
||||
os.rmdir(save_path)
|
||||
except OSError:
|
||||
log.exception('Could not remove directory: %s', save_path)
|
||||
log.exception('Could not remove directory: {path}'.format(path=save_path))
|
||||
clean_song(self.manager, self.song)
|
||||
self.manager.save_object(self.song)
|
||||
self.media_item.auto_select_id = self.song.id
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.lib import SpellTextEdit, build_icon, translate
|
||||
from openlp.core.ui.lib import SpellTextEdit
|
||||
from openlp.core.lib import build_icon, translate
|
||||
from openlp.core.lib.ui import UiStrings, create_button_box
|
||||
from openlp.plugins.songs.lib import VerseType
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
|
|||
if self.verse_text_edit.textCursor().columnNumber() != 0:
|
||||
self.verse_text_edit.insertPlainText('\n')
|
||||
verse_tag = VerseType.translated_name(verse_tag)
|
||||
self.verse_text_edit.insertPlainText('---[%s:%s]---\n' % (verse_tag, verse_num))
|
||||
self.verse_text_edit.insertPlainText('---[{tag}:{number}]---\n'.format(tag=verse_tag, number=verse_num))
|
||||
self.verse_text_edit.setFocus()
|
||||
|
||||
def on_split_button_clicked(self):
|
||||
|
@ -107,7 +107,7 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
|
|||
self.verse_type_combo_box.currentIndex()]
|
||||
if not text:
|
||||
return
|
||||
position = text.rfind('---[%s' % verse_name, 0, position)
|
||||
position = text.rfind('---[{verse}'.format(verse=verse_name), 0, position)
|
||||
if position == -1:
|
||||
self.verse_number_box.setValue(1)
|
||||
return
|
||||
|
@ -124,7 +124,7 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
|
|||
verse_num = 1
|
||||
self.verse_number_box.setValue(verse_num)
|
||||
|
||||
def set_verse(self, text, single=False, tag='%s1' % VerseType.tags[VerseType.Verse]):
|
||||
def set_verse(self, text, single=False, tag='{verse}1'.format(verse=VerseType.tags[VerseType.Verse])):
|
||||
"""
|
||||
Save the verse
|
||||
|
||||
|
@ -142,7 +142,7 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
|
|||
self.insert_button.setVisible(False)
|
||||
else:
|
||||
if not text:
|
||||
text = '---[%s:1]---\n' % VerseType.translated_names[VerseType.Verse]
|
||||
text = '---[{tag}:1]---\n'.format(tag=VerseType.translated_names[VerseType.Verse])
|
||||
self.verse_type_combo_box.setCurrentIndex(0)
|
||||
self.verse_number_box.setValue(1)
|
||||
self.insert_button.setVisible(True)
|
||||
|
@ -167,5 +167,5 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
|
|||
"""
|
||||
text = self.verse_text_edit.toPlainText()
|
||||
if not text.startswith('---['):
|
||||
text = '---[%s:1]---\n%s' % (VerseType.translated_names[VerseType.Verse], text)
|
||||
text = '---[{tag}:1]---\n{text}'.format(tag=VerseType.translated_names[VerseType.Verse], text=text)
|
||||
return text
|
||||
|
|
|
@ -34,7 +34,7 @@ class MediaFilesForm(QtWidgets.QDialog, Ui_MediaFilesDialog):
|
|||
"""
|
||||
Class to show a list of files from the
|
||||
"""
|
||||
log.info('%s MediaFilesForm loaded', __name__)
|
||||
log.info('{name} MediaFilesForm loaded'.format(name=__name__))
|
||||
|
||||
def __init__(self, parent):
|
||||
super(MediaFilesForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
|
||||
|
|
|
@ -143,6 +143,7 @@ class SongExportForm(OpenLPWizard):
|
|||
Song wizard localisation.
|
||||
"""
|
||||
self.setWindowTitle(translate('SongsPlugin.ExportWizardForm', 'Song Export Wizard'))
|
||||
# TODO: Verify format() with template variables
|
||||
self.title_label.setText(WizardStrings.HeaderStyle %
|
||||
translate('OpenLP.Ui', 'Welcome to the Song Export Wizard'))
|
||||
self.information_label.setText(
|
||||
|
@ -151,7 +152,7 @@ class SongExportForm(OpenLPWizard):
|
|||
self.available_songs_page.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
|
||||
self.available_songs_page.setSubTitle(translate('SongsPlugin.ExportWizardForm',
|
||||
'Check the songs you want to export.'))
|
||||
self.search_label.setText('%s:' % UiStrings().Search)
|
||||
self.search_label.setText('{text}:'.format(text=UiStrings().Search))
|
||||
self.uncheck_button.setText(translate('SongsPlugin.ExportWizardForm', 'Uncheck All'))
|
||||
self.check_button.setText(translate('SongsPlugin.ExportWizardForm', 'Check All'))
|
||||
self.export_song_page.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Directory'))
|
||||
|
@ -223,7 +224,7 @@ class SongExportForm(OpenLPWizard):
|
|||
if song.temporary:
|
||||
continue
|
||||
authors = create_separated_list([author.display_name for author in song.authors])
|
||||
title = '%s (%s)' % (str(song.title), authors)
|
||||
title = '{title} ({author})'.format(title=song.title, author=authors)
|
||||
item = QtWidgets.QListWidgetItem(title)
|
||||
item.setData(QtCore.Qt.UserRole, song)
|
||||
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
|
||||
|
@ -257,7 +258,7 @@ class SongExportForm(OpenLPWizard):
|
|||
self.progress_label.setText(translate('SongsPlugin.SongExportForm', 'Your song export failed.'))
|
||||
except OSError as ose:
|
||||
self.progress_label.setText(translate('SongsPlugin.SongExportForm', 'Your song export failed because this '
|
||||
'error occurred: %s') % ose.strerror)
|
||||
'error occurred: {error}').format(error=ose.strerror))
|
||||
|
||||
def on_search_line_edit_changed(self, text):
|
||||
"""
|
||||
|
|
|
@ -132,6 +132,7 @@ class SongImportForm(OpenLPWizard, RegistryProperties):
|
|||
Song wizard localisation.
|
||||
"""
|
||||
self.setWindowTitle(translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard'))
|
||||
# TODO: Verify format() with template variables
|
||||
self.title_label.setText(WizardStrings.HeaderStyle % translate('OpenLP.Ui',
|
||||
'Welcome to the Song Import Wizard'))
|
||||
self.information_label.setText(
|
||||
|
@ -236,7 +237,7 @@ class SongImportForm(OpenLPWizard, RegistryProperties):
|
|||
"""
|
||||
if filters:
|
||||
filters += ';;'
|
||||
filters += '%s (*)' % UiStrings().AllFiles
|
||||
filters += '{text} (*)'.format(text=UiStrings().AllFiles)
|
||||
file_names = FileDialog.getOpenFileNames(
|
||||
self, title,
|
||||
Settings().value(self.plugin.settings_section + '/last directory import'), filters)
|
||||
|
@ -271,9 +272,11 @@ class SongImportForm(OpenLPWizard, RegistryProperties):
|
|||
select_mode, format_name, ext_filter = SongFormat.get(this_format, 'selectMode', 'name', 'filter')
|
||||
file_path_edit = self.format_widgets[this_format]['file_path_edit']
|
||||
if select_mode == SongFormatSelect.SingleFile:
|
||||
# TODO: Verify format() with template variables
|
||||
self.get_file_name(
|
||||
WizardStrings.OpenTypeFile % format_name, file_path_edit, 'last directory import', ext_filter)
|
||||
elif select_mode == SongFormatSelect.SingleFolder:
|
||||
# TODO: Verify format() with template variables
|
||||
self.get_folder(WizardStrings.OpenTypeFolder % format_name, file_path_edit, 'last directory import')
|
||||
|
||||
def on_add_button_clicked(self):
|
||||
|
@ -283,6 +286,7 @@ class SongImportForm(OpenLPWizard, RegistryProperties):
|
|||
this_format = self.current_format
|
||||
select_mode, format_name, ext_filter, custom_title = \
|
||||
SongFormat.get(this_format, 'selectMode', 'name', 'filter', 'getFilesTitle')
|
||||
# TODO: Verify format() with template variables
|
||||
title = custom_title if custom_title else WizardStrings.OpenTypeFile % format_name
|
||||
if select_mode == SongFormatSelect.MultipleFiles:
|
||||
self.get_files(title, self.format_widgets[this_format]['file_list_widget'], ext_filter)
|
||||
|
|
|
@ -164,7 +164,8 @@ class SongMaintenanceForm(QtWidgets.QDialog, Ui_SongMaintenanceDialog, RegistryP
|
|||
books = self.manager.get_all_objects(Book)
|
||||
books.sort(key=get_book_key)
|
||||
for book in books:
|
||||
book_name = QtWidgets.QListWidgetItem('%s (%s)' % (book.name, book.publisher))
|
||||
book_name = QtWidgets.QListWidgetItem('{name} ({publisher})'.format(name=book.name,
|
||||
publisher=book.publisher))
|
||||
book_name.setData(QtCore.Qt.UserRole, book.id)
|
||||
self.song_books_list_widget.addItem(book_name)
|
||||
|
||||
|
@ -310,11 +311,12 @@ class SongMaintenanceForm(QtWidgets.QDialog, Ui_SongMaintenanceDialog, RegistryP
|
|||
else:
|
||||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
|
||||
elif critical_error_message_box(message=translate(
|
||||
'SongsPlugin.SongMaintenanceForm', 'The author %s already exists. Would you like to make songs with '
|
||||
'author %s use the existing author %s?') %
|
||||
(author.display_name, temp_display_name, author.display_name), parent=self, question=True) == \
|
||||
QtWidgets.QMessageBox.Yes:
|
||||
elif critical_error_message_box(
|
||||
message=translate(
|
||||
'SongsPlugin.SongMaintenanceForm',
|
||||
'The author {original} already exists. Would you like to make songs with author {new} use the '
|
||||
'existing author {original}?').format(original=author.display_name, new=temp_display_name),
|
||||
parent=self, question=True) == QtWidgets.QMessageBox.Yes:
|
||||
self._merge_objects(author, self.merge_authors, self.reset_authors)
|
||||
else:
|
||||
# We restore the author's old first and last name as well as
|
||||
|
@ -346,9 +348,10 @@ class SongMaintenanceForm(QtWidgets.QDialog, Ui_SongMaintenanceDialog, RegistryP
|
|||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
|
||||
elif critical_error_message_box(
|
||||
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||
'The topic %s already exists. Would you like to make songs with topic %s use the '
|
||||
'existing topic %s?') % (topic.name, temp_name, topic.name),
|
||||
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||
'The topic {original} already exists. Would you like to make songs with '
|
||||
'topic {new} use the existing topic {original}?').format(original=topic.name,
|
||||
new=temp_name),
|
||||
parent=self, question=True) == QtWidgets.QMessageBox.Yes:
|
||||
self._merge_objects(topic, self.merge_topics, self.reset_topics)
|
||||
else:
|
||||
|
@ -384,9 +387,10 @@ class SongMaintenanceForm(QtWidgets.QDialog, Ui_SongMaintenanceDialog, RegistryP
|
|||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
|
||||
elif critical_error_message_box(
|
||||
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||
'The book %s already exists. Would you like to make '
|
||||
'songs with book %s use the existing book %s?') % (book.name, temp_name, book.name),
|
||||
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||
'The book {original} already exists. Would you like to make songs with '
|
||||
'book {new} use the existing book {original}?').format(original=book.name,
|
||||
new=temp_name),
|
||||
parent=self, question=True) == QtWidgets.QMessageBox.Yes:
|
||||
self._merge_objects(book, self.merge_song_books, self.reset_song_books)
|
||||
else:
|
||||
|
|
|
@ -242,7 +242,8 @@ class Ui_SongSelectDialog(object):
|
|||
self.search_label.setText(translate('SongsPlugin.SongSelectForm', 'Search Text:'))
|
||||
self.search_button.setText(translate('SongsPlugin.SongSelectForm', 'Search'))
|
||||
self.stop_button.setText(translate('SongsPlugin.SongSelectForm', 'Stop'))
|
||||
self.result_count_label.setText(translate('SongsPlugin.SongSelectForm', 'Found %s song(s)') % 0)
|
||||
self.result_count_label.setText(translate('SongsPlugin.SongSelectForm',
|
||||
'Found {count:d} song(s)').format(count=0))
|
||||
self.logout_button.setText(translate('SongsPlugin.SongSelectForm', 'Logout'))
|
||||
self.view_button.setText(translate('SongsPlugin.SongSelectForm', 'View'))
|
||||
self.title_label.setText(translate('SongsPlugin.SongSelectForm', 'Title:'))
|
||||
|
|
|
@ -305,7 +305,8 @@ class SongSelectForm(QtWidgets.QDialog, Ui_SongSelectDialog):
|
|||
self.search_progress_bar.setValue(0)
|
||||
self.set_progress_visible(True)
|
||||
self.search_results_widget.clear()
|
||||
self.result_count_label.setText(translate('SongsPlugin.SongSelectForm', 'Found %s song(s)') % self.song_count)
|
||||
self.result_count_label.setText(translate('SongsPlugin.SongSelectForm',
|
||||
'Found {count:d} song(s)').format(count=self.song_count))
|
||||
self.application.process_events()
|
||||
self.song_count = 0
|
||||
search_history = self.search_combobox.getItems()
|
||||
|
@ -343,7 +344,8 @@ class SongSelectForm(QtWidgets.QDialog, Ui_SongSelectDialog):
|
|||
:param song:
|
||||
"""
|
||||
self.song_count += 1
|
||||
self.result_count_label.setText(translate('SongsPlugin.SongSelectForm', 'Found %s song(s)') % self.song_count)
|
||||
self.result_count_label.setText(translate('SongsPlugin.SongSelectForm',
|
||||
'Found {count:d} song(s)').format(count=self.song_count))
|
||||
item_title = song['title'] + ' (' + ', '.join(song['authors']) + ')'
|
||||
song_item = QtWidgets.QListWidgetItem(item_title, self.search_results_widget)
|
||||
song_item.setData(QtCore.Qt.UserRole, song)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue