diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index 51bea5474..7680caf2c 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -127,7 +127,7 @@ sup { document.getElementById('footer').innerHTML = footertext; } - function show_text(newtext){ + function show_text(new_text){ var match = /-webkit-text-fill-color:[^;\"]+/gi; if(timer != null) clearTimeout(timer); @@ -142,57 +142,47 @@ sup { if(outline != null) txt = outline; if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){ - newtext = newtext.replace(/(\s| )+(?![^<]*>)/g, + new_text = new_text.replace(/(\s| )+(?![^<]*>)/g, function(match) { return '' + match + ''; }); - newtext = '' + newtext + ''; + new_text = '' + new_text + ''; } } - text_fade('lyricsmain', newtext); - text_fade('lyricsoutline', newtext); - text_fade('lyricsshadow', newtext.replace(match, '')); - if(text_opacity() == 1) return; - timer = setTimeout(function(){ - show_text(newtext); - }, 100); + text_fade('lyricsmain', new_text); + text_fade('lyricsoutline', new_text); + text_fade('lyricsshadow', new_text.replace(match, '')); } - function text_fade(id, newtext){ + function text_fade(id, new_text){ /* - Using -webkit-transition: opacity 1s linear; would have been preferred - but it isn't currently quick enough when animating multiple layers of - large areas of large text. Therefore do it manually as best we can. - Hopefully in the future we can revisit and do more interesting - transitions using -webkit-transition and -webkit-transform. - However we need to ensure interrupted transitions (quickly change 2 - slides) still looks pretty and is zippy. + Show the text. */ var text = document.getElementById(id); if(text == null) return; if(!transition){ - text.innerHTML = newtext; + text.innerHTML = new_text; return; } - if(newtext == text.innerHTML){ - text.style.opacity = parseFloat(text.style.opacity) + 0.3; - if(text.style.opacity > 0.7) - text.style.opacity = 1; - } else { - text.style.opacity = parseFloat(text.style.opacity) - 0.3; - if(text.style.opacity <= 0.1){ - text.innerHTML = newtext; - } - } + // Fade text out. 0.2 to minimize the time "nothing" is shown on the screen. + text.style.opacity = '0.2'; + // Fade new text in after the old text has finished fading out. + timer = window.setTimeout(function(){_show_text(text, new_text)}, 400); } - function text_opacity(){ - var text = document.getElementById('lyricsmain'); - return getComputedStyle(text, '').opacity; + 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_complete(){ - return (text_opacity() == 1); + function show_text_completed(){ + return (timer == null); } @@ -336,6 +326,7 @@ def build_lyrics_css(item, webkit_ver): .lyricscell { display: table-cell; word-wrap: break-word; + -webkit-transition: opacity 0.4s ease; %s } .lyricsmain { diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index ea1f95a1d..0dd990b55 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -344,13 +344,14 @@ class MainDisplay(Display): Generates a preview of the image displayed. """ log.debug(u'preview for %s', self.is_live) + was_visible = self.isVisible() self.application.process_events() # We must have a service item to preview. if self.is_live and hasattr(self, u'serviceItem'): # Wait for the fade to finish before geting the preview. # Important otherwise preview will have incorrect text if at all! if self.serviceItem.themedata and self.serviceItem.themedata.display_slide_transition: - while self.frame.evaluateJavaScript(u'show_text_complete()') == u'false': + while not self.frame.evaluateJavaScript(u'show_text_completed()'): self.application.process_events() # Wait for the webview to update before getting the preview. # Important otherwise first preview will miss the background ! @@ -360,7 +361,9 @@ class MainDisplay(Display): if self.is_live: if self.hide_mode: self.hide_display(self.hide_mode) - else: + # Only continue if the visibility wasn't changed during method call. + elif was_visible == self.isVisible(): + # Single screen active if self.screens.display_count == 1: # Only make visible if setting enabled. diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index 1b8b93130..baa52d404 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -344,7 +344,7 @@ class MediaController(object): if controller.is_live and controller.display: if self.current_media_players and value: if self.current_media_players[controller.controller_type] != self.media_players[u'webkit']: - controller.display.setTransparency(False) + controller.display.set_transparency(False) def resize(self, display, player): """ diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 501ee7eea..694fd1028 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -923,6 +923,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.song.verse_order) except: log.exception(u'Problem processing song Lyrics \n%s', sxml.dump_xml()) + raise def _get_plugin_manager(self): """ diff --git a/tests/functional/openlp_core_lib/test_lib.py b/tests/functional/openlp_core_lib/test_lib.py index 8527373dc..9bbce1359 100644 --- a/tests/functional/openlp_core_lib/test_lib.py +++ b/tests/functional/openlp_core_lib/test_lib.py @@ -7,7 +7,7 @@ from datetime import datetime, timedelta from mock import MagicMock, patch from openlp.core.lib import str_to_bool, translate, check_directory_exists, get_text_file_string, build_icon, \ - image_to_byte, check_item_selected, validate_thumb, create_separated_list + image_to_byte, check_item_selected, validate_thumb, create_separated_list, expand_tags class TestLib(TestCase): @@ -299,6 +299,45 @@ class TestLib(TestCase): MockedQtGui.QMessageBox.information.assert_called_with(u'parent', u'mocked translate', 'message') assert not result, u'The result should be False' + def expand_tags_test(self): + """ + Test the expand_tags() method. + """ + with patch(u'openlp.core.lib.FormattingTags.get_html_tags') as mocked_get_tags: + # GIVEN: Mocked get_html_tags() method. + mocked_get_tags.return_value = [ + { + u'desc': u'Black', + u'start tag': u'{b}', + u'start html': u'', + u'end tag': u'{/b}', u'end html': u'', u'protected': True, + u'temporary': False + }, + { + u'desc': u'Yellow', + u'start tag': u'{y}', + u'start html': u'', + u'end tag': u'{/y}', u'end html': u'', u'protected': True, + u'temporary': False + }, + { + u'desc': u'Green', + u'start tag': u'{g}', + u'start html': u'', + u'end tag': u'{/g}', u'end html': u'', u'protected': True, + u'temporary': False + } + ] + string_to_pass = u'{b}black{/b}{y}yellow{/y}' + wanted_string = u'black' + \ + 'yellow' + + # WHEN: Replace the tags. + result_string = expand_tags(string_to_pass) + + # THEN: The strings should be identical. + assert result_string == wanted_string, u'The strings should be identical.' + def validate_thumb_file_does_not_exist_test(self): """ Test the validate_thumb() function when the thumbnail does not exist