Merge lp:~tomasgroth/openlp/23bugfixes into lp:openlp

Proposed by Tomas Groth
Status: Merged
Approved by: Tomas Groth
Approved revision: 2618
Merged at revision: 2610
Proposed branch: lp:~tomasgroth/openlp/23bugfixes
Merge into: lp:openlp
Diff against target: 291 lines (+96/-24)
9 files modified
openlp/core/common/uistrings.py (+2/-2)
openlp/core/lib/renderer.py (+3/-3)
openlp/core/ui/maindisplay.py (+9/-7)
openlp/core/ui/slidecontroller.py (+5/-2)
openlp/plugins/songs/forms/editsongform.py (+2/-0)
openlp/plugins/songs/lib/importers/opensong.py (+1/-0)
tests/functional/openlp_core_lib/test_renderer.py (+16/-10)
tests/functional/openlp_plugins/songs/test_opensongimport.py (+2/-0)
tests/resources/opensongsongs/Amazing Grace2 (+56/-0)
To merge this branch: bzr merge lp:~tomasgroth/openlp/23bugfixes
Reviewer Review Type Date Requested Status
Tomas Groth Approve
Tim Bentley Approve
Review via email: mp+283716@code.launchpad.net

Description of the change

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.

To post a comment you must log in.
Revision history for this message
Tomas Groth (tomasgroth) wrote :
Revision history for this message
Tim Bentley (trb143) :
review: Approve
Revision history for this message
Tomas Groth (tomasgroth) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openlp/core/common/uistrings.py'
--- openlp/core/common/uistrings.py 2015-12-31 22:46:06 +0000
+++ openlp/core/common/uistrings.py 2016-01-23 12:46:09 +0000
@@ -122,8 +122,8 @@
122 self.Projectors = translate('OpenLP.Ui', 'Projectors', 'Plural')122 self.Projectors = translate('OpenLP.Ui', 'Projectors', 'Plural')
123 self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background')123 self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
124 self.ReplaceLiveBG = translate('OpenLP.Ui', 'Replace live background.')124 self.ReplaceLiveBG = translate('OpenLP.Ui', 'Replace live background.')
125 self.ReplaceLiveBGDisabled = translate('OpenLP.Ui', 'Replace live background is not available on this '125 self.ReplaceLiveBGDisabled = translate('OpenLP.Ui', 'Replace live background is not available when the WebKit '
126 'platform in this version of OpenLP.')126 'player is disabled.')
127 self.ResetBG = translate('OpenLP.Ui', 'Reset Background')127 self.ResetBG = translate('OpenLP.Ui', 'Reset Background')
128 self.ResetLiveBG = translate('OpenLP.Ui', 'Reset live background.')128 self.ResetLiveBG = translate('OpenLP.Ui', 'Reset live background.')
129 self.Seconds = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds')129 self.Seconds = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds')
130130
=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py 2016-01-09 16:26:14 +0000
+++ openlp/core/lib/renderer.py 2016-01-23 12:46:09 +0000
@@ -20,6 +20,7 @@
20# Temple Place, Suite 330, Boston, MA 02111-1307 USA #20# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
21###############################################################################21###############################################################################
2222
23import re
2324
24from PyQt5 import QtGui, QtCore, QtWebKitWidgets25from PyQt5 import QtGui, QtCore, QtWebKitWidgets
2526
@@ -441,7 +442,7 @@
441 previous_raw = line + line_end442 previous_raw = line + line_end
442 continue443 continue
443 # Figure out how many words of the line will fit on screen as the line will not fit as a whole.444 # Figure out how many words of the line will fit on screen as the line will not fit as a whole.
444 raw_words = Renderer.words_split(line)445 raw_words = words_split(line)
445 html_words = list(map(expand_tags, raw_words))446 html_words = list(map(expand_tags, raw_words))
446 previous_html, previous_raw = \447 previous_html, previous_raw = \
447 self._binary_chop(formatted, previous_html, previous_raw, html_words, raw_words, ' ', line_end)448 self._binary_chop(formatted, previous_html, previous_raw, html_words, raw_words, ' ', line_end)
@@ -528,8 +529,7 @@
528 :param line: Line to be split529 :param line: Line to be split
529 """530 """
530 # this parse we are to be wordy531 # this parse we are to be wordy
531 line = line.replace('\n', ' ')532 return re.split('\s+', line)
532 return line.split(' ')
533533
534534
535def get_start_tags(raw_text):535def get_start_tags(raw_text):
536536
=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py 2016-01-08 21:43:43 +0000
+++ openlp/core/ui/maindisplay.py 2016-01-23 12:46:09 +0000
@@ -86,12 +86,6 @@
86 super(Display, self).__init__()86 super(Display, self).__init__()
87 self.controller = parent87 self.controller = parent
88 self.screen = {}88 self.screen = {}
89 # FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with
90 # OpenGL. Only white blank screen is shown on the 2nd monitor all the
91 # time. We need to investigate more how to use OpenGL properly on Mac OS
92 # X.
93 if not is_macosx() and not is_win():
94 self.setViewport(QtOpenGL.QGLWidget())
9589
96 def setup(self):90 def setup(self):
97 """91 """
@@ -559,6 +553,13 @@
559 if window_id == main_window_id:553 if window_id == main_window_id:
560 self.main_window.raise_()554 self.main_window.raise_()
561555
556 def shake_web_view(self):
557 """
558 Resizes the web_view a bit to force an update. Workaround for bug #1531319, should not be needed with PyQt 5.6.
559 """
560 self.web_view.setGeometry(0, 0, self.width(), self.height() - 1)
561 self.web_view.setGeometry(0, 0, self.width(), self.height())
562
562563
563class AudioPlayer(OpenLPMixin, QtCore.QObject):564class AudioPlayer(OpenLPMixin, QtCore.QObject):
564 """565 """
@@ -576,6 +577,7 @@
576 self.player = QtMultimedia.QMediaPlayer()577 self.player = QtMultimedia.QMediaPlayer()
577 self.playlist = QtMultimedia.QMediaPlaylist(self.player)578 self.playlist = QtMultimedia.QMediaPlaylist(self.player)
578 self.volume_slider = None579 self.volume_slider = None
580 self.player.setPlaylist(self.playlist)
579 self.player.positionChanged.connect(self._on_position_changed)581 self.player.positionChanged.connect(self._on_position_changed)
580582
581 def __del__(self):583 def __del__(self):
@@ -643,7 +645,7 @@
643 if not isinstance(file_names, list):645 if not isinstance(file_names, list):
644 file_names = [file_names]646 file_names = [file_names]
645 for file_name in file_names:647 for file_name in file_names:
646 self.playlist.addMedia(QtCore.QUrl(file_name))648 self.playlist.addMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file_name)))
647649
648 def next(self):650 def next(self):
649 """651 """
650652
=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py 2016-01-13 21:00:46 +0000
+++ openlp/core/ui/slidecontroller.py 2016-01-23 12:46:09 +0000
@@ -31,7 +31,7 @@
31from PyQt5 import QtCore, QtGui, QtWidgets31from PyQt5 import QtCore, QtGui, QtWidgets
3232
33from openlp.core.common import Registry, RegistryProperties, Settings, SlideLimits, UiStrings, translate, \33from openlp.core.common import Registry, RegistryProperties, Settings, SlideLimits, UiStrings, translate, \
34 RegistryMixin, OpenLPMixin34 RegistryMixin, OpenLPMixin, is_win
35from openlp.core.lib import OpenLPToolbar, ItemCapabilities, ServiceItem, ImageSource, ServiceItemAction, \35from openlp.core.lib import OpenLPToolbar, ItemCapabilities, ServiceItem, ImageSource, ServiceItemAction, \
36 ScreenList, build_icon, build_html36 ScreenList, build_icon, build_html
37from openlp.core.ui import HideMode, MainDisplay, Display, DisplayControllerType37from openlp.core.ui import HideMode, MainDisplay, Display, DisplayControllerType
@@ -1101,6 +1101,9 @@
1101 self.display.image(to_display)1101 self.display.image(to_display)
1102 # reset the store used to display first image1102 # reset the store used to display first image
1103 self.service_item.bg_image_bytes = None1103 self.service_item.bg_image_bytes = None
1104 # Workaround for bug #1531319, should not be needed with PyQt 5.6.
1105 if self.is_live and is_win():
1106 self.display.shake_web_view()
1104 self.selected_row = row1107 self.selected_row = row
1105 self.update_preview()1108 self.update_preview()
1106 self.preview_widget.change_slide(row)1109 self.preview_widget.change_slide(row)
@@ -1421,7 +1424,7 @@
14211424
1422 :param time: the time remaining1425 :param time: the time remaining
1423 """1426 """
1424 seconds = self.display.audio_player.media_object.remainingTime() // 10001427 seconds = (self.display.audio_player.player.duration() - self.display.audio_player.player.position()) // 1000
1425 minutes = seconds // 601428 minutes = seconds // 60
1426 seconds %= 601429 seconds %= 60
1427 self.audio_time_label.setText(' %02d:%02d ' % (minutes, seconds))1430 self.audio_time_label.setText(' %02d:%02d ' % (minutes, seconds))
14281431
=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py 2016-01-15 20:37:53 +0000
+++ openlp/plugins/songs/forms/editsongform.py 2016-01-23 12:46:09 +0000
@@ -843,7 +843,9 @@
843 :param text: The text of the verse order edit (ignored).843 :param text: The text of the verse order edit (ignored).
844 """844 """
845 # First make sure that all letters entered in the verse order field are uppercase845 # First make sure that all letters entered in the verse order field are uppercase
846 pos = self.verse_order_edit.cursorPosition()
846 self.verse_order_edit.setText(text.upper())847 self.verse_order_edit.setText(text.upper())
848 self.verse_order_edit.setCursorPosition(pos)
847 # Extract all verses which were used in the order.849 # Extract all verses which were used in the order.
848 verses_in_order = self._extract_verse_order(self.verse_order_edit.text())850 verses_in_order = self._extract_verse_order(self.verse_order_edit.text())
849 # Find the verses which were not used in the order.851 # Find the verses which were not used in the order.
850852
=== modified file 'openlp/plugins/songs/lib/importers/opensong.py'
--- openlp/plugins/songs/lib/importers/opensong.py 2015-12-31 22:46:06 +0000
+++ openlp/plugins/songs/lib/importers/opensong.py 2016-01-23 12:46:09 +0000
@@ -157,6 +157,7 @@
157 if isinstance(fn_or_string, str):157 if isinstance(fn_or_string, str):
158 if attr in ['ccli']:158 if attr in ['ccli']:
159 if ustring:159 if ustring:
160 ustring = ''.join(re.findall('\d+', ustring))
160 setattr(self, fn_or_string, int(ustring))161 setattr(self, fn_or_string, int(ustring))
161 else:162 else:
162 setattr(self, fn_or_string, None)163 setattr(self, fn_or_string, None)
163164
=== modified file 'tests/functional/openlp_core_lib/test_renderer.py'
--- tests/functional/openlp_core_lib/test_renderer.py 2015-12-31 22:46:06 +0000
+++ tests/functional/openlp_core_lib/test_renderer.py 2016-01-23 12:46:09 +0000
@@ -27,9 +27,10 @@
27from PyQt5 import QtCore27from PyQt5 import QtCore
2828
29from openlp.core.common import Registry29from openlp.core.common import Registry
30from openlp.core.lib import Renderer, ScreenList, ServiceItem30from openlp.core.lib import Renderer, ScreenList, ServiceItem, FormattingTags
31from openlp.core.lib.renderer import words_split, get_start_tags
3132
32from tests.functional import MagicMock33from tests.functional import MagicMock, patch
3334
34SCREEN = {35SCREEN = {
35 'primary': False,36 'primary': False,
@@ -71,34 +72,39 @@
71 self.assertEqual(renderer.screen_ratio, 0.75, 'The base renderer should be a live controller')72 self.assertEqual(renderer.screen_ratio, 0.75, 'The base renderer should be a live controller')
72 self.assertEqual(renderer.footer_start, 691, 'The base renderer should be a live controller')73 self.assertEqual(renderer.footer_start, 691, 'The base renderer should be a live controller')
7374
74 def _get_start_tags_test(self):75 @patch('openlp.core.lib.renderer.FormattingTags.get_html_tags')
76 def get_start_tags_test(self, mocked_get_html_tags):
75 """77 """
76 Test the _get_start_tags() method78 Test the get_start_tags() method
77 """79 """
78 # GIVEN: A new renderer instance. Broken raw_text (missing closing tags).80 # GIVEN: A new renderer instance. Broken raw_text (missing closing tags).
79 renderer = Renderer()
80 given_raw_text = '{st}{r}Text text text'81 given_raw_text = '{st}{r}Text text text'
81 expected_tuple = ('{st}{r}Text text text{/r}{/st}', '{st}{r}',82 expected_tuple = ('{st}{r}Text text text{/r}{/st}', '{st}{r}',
82 '<strong><span style="-webkit-text-fill-color:red">')83 '<strong><span style="-webkit-text-fill-color:red">')
84 mocked_get_html_tags.return_value = [{'temporary': False, 'end tag': '{/r}', 'desc': 'Red',
85 'start html': '<span style="-webkit-text-fill-color:red">',
86 'end html': '</span>', 'start tag': '{r}', 'protected': True},
87 {'temporary': False, 'end tag': '{/st}', 'desc': 'Bold',
88 'start html': '<strong>', 'end html': '</strong>', 'start tag': '{st}',
89 'protected': True}]
8390
84 # WHEN: The renderer converts the start tags91 # WHEN: The renderer converts the start tags
85 result = renderer._get_start_tags(given_raw_text)92 result = get_start_tags(given_raw_text)
8693
87 # THEN: Check if the correct tuple is returned.94 # THEN: Check if the correct tuple is returned.
88 self.assertEqual(result, expected_tuple), 'A tuple should be returned containing the text with correct ' \95 self.assertEqual(result, expected_tuple), 'A tuple should be returned containing the text with correct ' \
89 'tags, the opening tags, and the opening html tags.'96 'tags, the opening tags, and the opening html tags.'
9097
91 def _word_split_test(self):98 def word_split_test(self):
92 """99 """
93 Test the _word_split() method100 Test the word_split() method
94 """101 """
95 # GIVEN: A line of text102 # GIVEN: A line of text
96 renderer = Renderer()
97 given_line = 'beginning asdf \n end asdf'103 given_line = 'beginning asdf \n end asdf'
98 expected_words = ['beginning', 'asdf', 'end', 'asdf']104 expected_words = ['beginning', 'asdf', 'end', 'asdf']
99105
100 # WHEN: Split the line based on word split rules106 # WHEN: Split the line based on word split rules
101 result_words = renderer._words_split(given_line)107 result_words = words_split(given_line)
102108
103 # THEN: The word lists should be the same.109 # THEN: The word lists should be the same.
104 self.assertListEqual(result_words, expected_words)110 self.assertListEqual(result_words, expected_words)
105111
=== modified file 'tests/functional/openlp_plugins/songs/test_opensongimport.py'
--- tests/functional/openlp_plugins/songs/test_opensongimport.py 2015-12-31 22:46:06 +0000
+++ tests/functional/openlp_plugins/songs/test_opensongimport.py 2016-01-23 12:46:09 +0000
@@ -52,6 +52,8 @@
52 self.load_external_result_data(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.json')))52 self.load_external_result_data(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.json')))
53 self.file_import([os.path.join(TEST_PATH, 'One, Two, Three, Four, Five')],53 self.file_import([os.path.join(TEST_PATH, 'One, Two, Three, Four, Five')],
54 self.load_external_result_data(os.path.join(TEST_PATH, 'One, Two, Three, Four, Five.json')))54 self.load_external_result_data(os.path.join(TEST_PATH, 'One, Two, Three, Four, Five.json')))
55 self.file_import([os.path.join(TEST_PATH, 'Amazing Grace2')],
56 self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json')))
5557
5658
57class TestOpenSongImport(TestCase):59class TestOpenSongImport(TestCase):
5860
=== added file 'tests/resources/opensongsongs/Amazing Grace2'
--- tests/resources/opensongsongs/Amazing Grace2 1970-01-01 00:00:00 +0000
+++ tests/resources/opensongsongs/Amazing Grace2 2016-01-23 12:46:09 +0000
@@ -0,0 +1,56 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<song>
3 <title>Amazing Grace (Demonstration)</title>
4 <author>John Newton, Edwin Excell &amp; John P. Rees</author>
5 <copyright>Public Domain </copyright>
6 <presentation>V1 V2 V3 V4 V5</presentation>
7 <capo print="false"></capo>
8 <tempo></tempo>
9 <ccli>CC: 22025 number</ccli>
10 <theme>God: Assurance/Grace/Salvation</theme>
11 <alttheme>Worship: Praise</alttheme>
12 <user1> </user1>
13 <user2> </user2>
14 <user3> </user3>
15 <lyrics>[V]
16;Test the chords format
17;Chords beging with .
18;Verses begin with their verse number
19;Link words with _
20;Comments begin with ;
21. D D7 G D
221A______ma________zing grace! How sweet the sound!
232'Twas grace that taught my heart to fear,
243The Lord has pro____mised good to me,
254Thro' ma________ny dan____gers, toils and snares
265When we've been there ten thou__sand years,
27
28. Bm E A A7
291That saved a wretch like me!
302And grace my fears re___lieved.
313His Word my hope se___cures.
324I have al___rea____dy come.
335Bright shi___ning as the sun,
34
35. D D7 G D
361I once was lost, but now am found;
372How pre___cious did that grace ap____pear,
383He will my shield and por___tion be
394'Tis grace that brought me safe thus far,
405We've no less days to sing God's praise,
41
42. Bm A G D
431Was blind, but now I see.
442The hour I first be_lieved.
453As long as life en_dures.
464And grace will lead me home.
475Than when we first be_gun.
48
49</lyrics>
50 <hymn_number>Demonstration Songs 0</hymn_number>
51 <key></key>
52 <aka></aka>
53 <key_line></key_line>
54 <time_sig></time_sig>
55 <style index="default_style"></style>
56</song>
0\ No newline at end of file57\ No newline at end of file