forked from openlp/openlp
Fix traceback where OpenSong importer crashed if non-numbers were in the CCLI field.
Fix some broken tests that was not being used due to naming. When setting the verseorder to uppercase, remember the cursor position. Fixes bug 1536411. Disable OpenGL on linux (too). Fixes bug 1535332. Disable OpenGL on windows to make webkit player work. Made workaround for windows display not updating, and disabled OpenGL on Windows, fixes bug 1531319. Fix playback of linked audio. Fixes bug 1533280. bzr-revno: 2610 Fixes: https://launchpad.net/bugs/1533280, https://launchpad.net/bugs/1535332, https://launchpad.net/bugs/1536411
This commit is contained in:
commit
70db5acba9
@ -122,8 +122,8 @@ class UiStrings(object):
|
||||
self.Projectors = translate('OpenLP.Ui', 'Projectors', 'Plural')
|
||||
self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
|
||||
self.ReplaceLiveBG = translate('OpenLP.Ui', 'Replace live background.')
|
||||
self.ReplaceLiveBGDisabled = translate('OpenLP.Ui', 'Replace live background is not available on this '
|
||||
'platform in this version of OpenLP.')
|
||||
self.ReplaceLiveBGDisabled = translate('OpenLP.Ui', 'Replace live background is not available when the WebKit '
|
||||
'player is disabled.')
|
||||
self.ResetBG = translate('OpenLP.Ui', 'Reset Background')
|
||||
self.ResetLiveBG = translate('OpenLP.Ui', 'Reset live background.')
|
||||
self.Seconds = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds')
|
||||
|
@ -20,6 +20,7 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
import re
|
||||
|
||||
from PyQt5 import QtGui, QtCore, QtWebKitWidgets
|
||||
|
||||
@ -441,7 +442,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
|
||||
previous_raw = line + line_end
|
||||
continue
|
||||
# Figure out how many words of the line will fit on screen as the line will not fit as a whole.
|
||||
raw_words = Renderer.words_split(line)
|
||||
raw_words = words_split(line)
|
||||
html_words = list(map(expand_tags, raw_words))
|
||||
previous_html, previous_raw = \
|
||||
self._binary_chop(formatted, previous_html, previous_raw, html_words, raw_words, ' ', line_end)
|
||||
@ -528,8 +529,7 @@ def words_split(line):
|
||||
:param line: Line to be split
|
||||
"""
|
||||
# this parse we are to be wordy
|
||||
line = line.replace('\n', ' ')
|
||||
return line.split(' ')
|
||||
return re.split('\s+', line)
|
||||
|
||||
|
||||
def get_start_tags(raw_text):
|
||||
|
@ -86,12 +86,6 @@ class Display(QtWidgets.QGraphicsView):
|
||||
super(Display, self).__init__()
|
||||
self.controller = parent
|
||||
self.screen = {}
|
||||
# FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with
|
||||
# OpenGL. Only white blank screen is shown on the 2nd monitor all the
|
||||
# time. We need to investigate more how to use OpenGL properly on Mac OS
|
||||
# X.
|
||||
if not is_macosx() and not is_win():
|
||||
self.setViewport(QtOpenGL.QGLWidget())
|
||||
|
||||
def setup(self):
|
||||
"""
|
||||
@ -559,6 +553,13 @@ class MainDisplay(OpenLPMixin, Display, RegistryProperties):
|
||||
if window_id == main_window_id:
|
||||
self.main_window.raise_()
|
||||
|
||||
def shake_web_view(self):
|
||||
"""
|
||||
Resizes the web_view a bit to force an update. Workaround for bug #1531319, should not be needed with PyQt 5.6.
|
||||
"""
|
||||
self.web_view.setGeometry(0, 0, self.width(), self.height() - 1)
|
||||
self.web_view.setGeometry(0, 0, self.width(), self.height())
|
||||
|
||||
|
||||
class AudioPlayer(OpenLPMixin, QtCore.QObject):
|
||||
"""
|
||||
@ -576,6 +577,7 @@ class AudioPlayer(OpenLPMixin, QtCore.QObject):
|
||||
self.player = QtMultimedia.QMediaPlayer()
|
||||
self.playlist = QtMultimedia.QMediaPlaylist(self.player)
|
||||
self.volume_slider = None
|
||||
self.player.setPlaylist(self.playlist)
|
||||
self.player.positionChanged.connect(self._on_position_changed)
|
||||
|
||||
def __del__(self):
|
||||
@ -643,7 +645,7 @@ class AudioPlayer(OpenLPMixin, QtCore.QObject):
|
||||
if not isinstance(file_names, list):
|
||||
file_names = [file_names]
|
||||
for file_name in file_names:
|
||||
self.playlist.addMedia(QtCore.QUrl(file_name))
|
||||
self.playlist.addMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file_name)))
|
||||
|
||||
def next(self):
|
||||
"""
|
||||
|
@ -31,7 +31,7 @@ from threading import Lock
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import Registry, RegistryProperties, Settings, SlideLimits, UiStrings, translate, \
|
||||
RegistryMixin, OpenLPMixin
|
||||
RegistryMixin, OpenLPMixin, is_win
|
||||
from openlp.core.lib import OpenLPToolbar, ItemCapabilities, ServiceItem, ImageSource, ServiceItemAction, \
|
||||
ScreenList, build_icon, build_html
|
||||
from openlp.core.ui import HideMode, MainDisplay, Display, DisplayControllerType
|
||||
@ -1101,6 +1101,9 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
self.display.image(to_display)
|
||||
# reset the store used to display first image
|
||||
self.service_item.bg_image_bytes = None
|
||||
# Workaround for bug #1531319, should not be needed with PyQt 5.6.
|
||||
if self.is_live and is_win():
|
||||
self.display.shake_web_view()
|
||||
self.selected_row = row
|
||||
self.update_preview()
|
||||
self.preview_widget.change_slide(row)
|
||||
@ -1421,7 +1424,7 @@ class SlideController(DisplayController, RegistryProperties):
|
||||
|
||||
:param time: the time remaining
|
||||
"""
|
||||
seconds = self.display.audio_player.media_object.remainingTime() // 1000
|
||||
seconds = (self.display.audio_player.player.duration() - self.display.audio_player.player.position()) // 1000
|
||||
minutes = seconds // 60
|
||||
seconds %= 60
|
||||
self.audio_time_label.setText(' %02d:%02d ' % (minutes, seconds))
|
||||
|
@ -843,7 +843,9 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
||||
:param text: The text of the verse order edit (ignored).
|
||||
"""
|
||||
# First make sure that all letters entered in the verse order field are uppercase
|
||||
pos = self.verse_order_edit.cursorPosition()
|
||||
self.verse_order_edit.setText(text.upper())
|
||||
self.verse_order_edit.setCursorPosition(pos)
|
||||
# Extract all verses which were used in the order.
|
||||
verses_in_order = self._extract_verse_order(self.verse_order_edit.text())
|
||||
# Find the verses which were not used in the order.
|
||||
|
@ -157,6 +157,7 @@ class OpenSongImport(SongImport):
|
||||
if isinstance(fn_or_string, str):
|
||||
if attr in ['ccli']:
|
||||
if ustring:
|
||||
ustring = ''.join(re.findall('\d+', ustring))
|
||||
setattr(self, fn_or_string, int(ustring))
|
||||
else:
|
||||
setattr(self, fn_or_string, None)
|
||||
|
@ -27,9 +27,10 @@ from unittest import TestCase
|
||||
from PyQt5 import QtCore
|
||||
|
||||
from openlp.core.common import Registry
|
||||
from openlp.core.lib import Renderer, ScreenList, ServiceItem
|
||||
from openlp.core.lib import Renderer, ScreenList, ServiceItem, FormattingTags
|
||||
from openlp.core.lib.renderer import words_split, get_start_tags
|
||||
|
||||
from tests.functional import MagicMock
|
||||
from tests.functional import MagicMock, patch
|
||||
|
||||
SCREEN = {
|
||||
'primary': False,
|
||||
@ -71,34 +72,39 @@ class TestRenderer(TestCase):
|
||||
self.assertEqual(renderer.screen_ratio, 0.75, 'The base renderer should be a live controller')
|
||||
self.assertEqual(renderer.footer_start, 691, 'The base renderer should be a live controller')
|
||||
|
||||
def _get_start_tags_test(self):
|
||||
@patch('openlp.core.lib.renderer.FormattingTags.get_html_tags')
|
||||
def get_start_tags_test(self, mocked_get_html_tags):
|
||||
"""
|
||||
Test the _get_start_tags() method
|
||||
Test the get_start_tags() method
|
||||
"""
|
||||
# GIVEN: A new renderer instance. Broken raw_text (missing closing tags).
|
||||
renderer = Renderer()
|
||||
given_raw_text = '{st}{r}Text text text'
|
||||
expected_tuple = ('{st}{r}Text text text{/r}{/st}', '{st}{r}',
|
||||
'<strong><span style="-webkit-text-fill-color:red">')
|
||||
mocked_get_html_tags.return_value = [{'temporary': False, 'end tag': '{/r}', 'desc': 'Red',
|
||||
'start html': '<span style="-webkit-text-fill-color:red">',
|
||||
'end html': '</span>', 'start tag': '{r}', 'protected': True},
|
||||
{'temporary': False, 'end tag': '{/st}', 'desc': 'Bold',
|
||||
'start html': '<strong>', 'end html': '</strong>', 'start tag': '{st}',
|
||||
'protected': True}]
|
||||
|
||||
# WHEN: The renderer converts the start tags
|
||||
result = renderer._get_start_tags(given_raw_text)
|
||||
result = get_start_tags(given_raw_text)
|
||||
|
||||
# THEN: Check if the correct tuple is returned.
|
||||
self.assertEqual(result, expected_tuple), 'A tuple should be returned containing the text with correct ' \
|
||||
'tags, the opening tags, and the opening html tags.'
|
||||
|
||||
def _word_split_test(self):
|
||||
def word_split_test(self):
|
||||
"""
|
||||
Test the _word_split() method
|
||||
Test the word_split() method
|
||||
"""
|
||||
# GIVEN: A line of text
|
||||
renderer = Renderer()
|
||||
given_line = 'beginning asdf \n end asdf'
|
||||
expected_words = ['beginning', 'asdf', 'end', 'asdf']
|
||||
|
||||
# WHEN: Split the line based on word split rules
|
||||
result_words = renderer._words_split(given_line)
|
||||
result_words = words_split(given_line)
|
||||
|
||||
# THEN: The word lists should be the same.
|
||||
self.assertListEqual(result_words, expected_words)
|
||||
|
@ -52,6 +52,8 @@ class TestOpenSongFileImport(SongImportTestHelper):
|
||||
self.load_external_result_data(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.json')))
|
||||
self.file_import([os.path.join(TEST_PATH, 'One, Two, Three, Four, Five')],
|
||||
self.load_external_result_data(os.path.join(TEST_PATH, 'One, Two, Three, Four, Five.json')))
|
||||
self.file_import([os.path.join(TEST_PATH, 'Amazing Grace2')],
|
||||
self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json')))
|
||||
|
||||
|
||||
class TestOpenSongImport(TestCase):
|
||||
|
56
tests/resources/opensongsongs/Amazing Grace2
Normal file
56
tests/resources/opensongsongs/Amazing Grace2
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<song>
|
||||
<title>Amazing Grace (Demonstration)</title>
|
||||
<author>John Newton, Edwin Excell & John P. Rees</author>
|
||||
<copyright>Public Domain </copyright>
|
||||
<presentation>V1 V2 V3 V4 V5</presentation>
|
||||
<capo print="false"></capo>
|
||||
<tempo></tempo>
|
||||
<ccli>CC: 22025 number</ccli>
|
||||
<theme>God: Assurance/Grace/Salvation</theme>
|
||||
<alttheme>Worship: Praise</alttheme>
|
||||
<user1> </user1>
|
||||
<user2> </user2>
|
||||
<user3> </user3>
|
||||
<lyrics>[V]
|
||||
;Test the chords format
|
||||
;Chords beging with .
|
||||
;Verses begin with their verse number
|
||||
;Link words with _
|
||||
;Comments begin with ;
|
||||
. D D7 G D
|
||||
1A______ma________zing grace! How sweet the sound!
|
||||
2'Twas grace that taught my heart to fear,
|
||||
3The Lord has pro____mised good to me,
|
||||
4Thro' ma________ny dan____gers, toils and snares
|
||||
5When we've been there ten thou__sand years,
|
||||
|
||||
. Bm E A A7
|
||||
1That saved a wretch like me!
|
||||
2And grace my fears re___lieved.
|
||||
3His Word my hope se___cures.
|
||||
4I have al___rea____dy come.
|
||||
5Bright shi___ning as the sun,
|
||||
|
||||
. D D7 G D
|
||||
1I once was lost, but now am found;
|
||||
2How pre___cious did that grace ap____pear,
|
||||
3He will my shield and por___tion be
|
||||
4'Tis grace that brought me safe thus far,
|
||||
5We've no less days to sing God's praise,
|
||||
|
||||
. Bm A G D
|
||||
1Was blind, but now I see.
|
||||
2The hour I first be_lieved.
|
||||
3As long as life en_dures.
|
||||
4And grace will lead me home.
|
||||
5Than when we first be_gun.
|
||||
|
||||
</lyrics>
|
||||
<hymn_number>Demonstration Songs 0</hymn_number>
|
||||
<key></key>
|
||||
<aka></aka>
|
||||
<key_line></key_line>
|
||||
<time_sig></time_sig>
|
||||
<style index="default_style"></style>
|
||||
</song>
|
Loading…
Reference in New Issue
Block a user