Merge branch 'master' of gitlab.com:openlp/openlp

This commit is contained in:
Tim 2019-12-18 17:13:10 +00:00
commit 49f30e497c
No known key found for this signature in database
GPG Key ID: 3D454289AF831A6D
26 changed files with 318 additions and 166 deletions

109
openlp/core/common/enum.py Normal file
View File

@ -0,0 +1,109 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2019 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
The :mod:`enumm` module provides enumm functions.
"""
from enum import IntEnum, unique
@unique
class AlertLocation(IntEnum):
"""
This is an enumeration class which controls where Alerts are placed on the screen.
``Top``
Place the text at the top of the screen.
``Middle``
Place the text in the middle of the screen.
``Bottom``
Place the text at the bottom of the screen.
"""
Top = 0
Middle = 1
Bottom = 2
@unique
class BibleSearch(IntEnum):
"""
Enumeration class for the different search types for the "Search" tab.
"""
Reference = 1
Text = 2
Combined = 3
@unique
class CustomSearch(IntEnum):
"""
An enumeration for custom search methods.
"""
Titles = 1
Themes = 2
@unique
class DisplayStyle(IntEnum):
"""
An enumeration for bible text bracket display styles.
"""
NoBrackets = 0
Round = 1
Curly = 2
Square = 3
@unique
class LayoutStyle(IntEnum):
"""
An enumeration for bible screen layout styles.
"""
VersePerSlide = 0
VersePerLine = 1
Continuous = 2
@unique
class LanguageSelection(IntEnum):
"""
An enumeration for bible bookname language. And standard strings for use throughout the bibles plugin.
"""
Bible = 0
Application = 1
English = 2
@unique
class SongSearch(IntEnum):
"""
An enumeration for song search methods.
"""
Entire = 1
Titles = 2
Lyrics = 3
Authors = 4
Topics = 5
Books = 6
Themes = 7
Copyright = 8
CCLInumber = 9

View File

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2019 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
The :mod:`~openlp.core.display.window` module contains the display window
"""
import logging
import time
from openlp.core.common.registry import Registry
log = logging.getLogger(__name__)
def wait_for(check_func, error_message='Timed out waiting for completion', timeout=10):
"""
Wait until web engine page loaded
:return boolean: True on success, False on timeout
"""
# Timeout in 10 seconds
end_time = time.time() + timeout
app = Registry().get('application')
success = True
while not check_func():
now = time.time()
if now > end_time:
log.error(error_message)
success = False
break
time.sleep(0.001)
app.process_events()
return success

View File

@ -383,6 +383,7 @@ var Display = {
init: function (doTransitions=false) { init: function (doTransitions=false) {
Display._doTransitions = doTransitions; Display._doTransitions = doTransitions;
Reveal.initialize(Display._revealConfig); Reveal.initialize(Display._revealConfig);
displayWatcher.setInitialised(true);
}, },
/** /**
* Reinitialise Reveal * Reinitialise Reveal
@ -1134,4 +1135,5 @@ var Display = {
}; };
new QWebChannel(qt.webChannelTransport, function (channel) { new QWebChannel(qt.webChannelTransport, function (channel) {
window.mediaWatcher = channel.objects.mediaWatcher; window.mediaWatcher = channel.objects.mediaWatcher;
window.displayWatcher = channel.objects.displayWatcher;
}); });

View File

@ -36,6 +36,7 @@ from openlp.core.common.i18n import translate
from openlp.core.common.mixins import LogMixin from openlp.core.common.mixins import LogMixin
from openlp.core.common.registry import Registry, RegistryBase from openlp.core.common.registry import Registry, RegistryBase
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.core.common.utils import wait_for
from openlp.core.display.screens import ScreenList from openlp.core.display.screens import ScreenList
from openlp.core.display.window import DisplayWindow from openlp.core.display.window import DisplayWindow
from openlp.core.lib import ItemCapabilities from openlp.core.lib import ItemCapabilities
@ -486,35 +487,6 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
footer_html = 'Dummy footer text' footer_html = 'Dummy footer text'
return footer_html return footer_html
def wait_till_loaded(self):
"""
Wait until web engine page loaded
:return boolean: True on success, False on timeout
"""
# Timeout in 10 seconds
end_time = time.time() + 10
app = Registry().get('application')
success = True
while not self._is_initialised:
if time.time() > end_time:
log.error('Timed out waiting for web engine page to load')
success = False
break
time.sleep(0.1)
app.process_events()
return success
def _wait_and_process(self, delay):
"""
Wait while allowing things to process
:param delay: The amount of time in seconds to delay, can be a float
"""
end_time = time.time() + delay
app = Registry().get('application')
while time.time() < end_time:
app.process_events()
def generate_preview(self, theme_data, force_page=False, generate_screenshot=True): def generate_preview(self, theme_data, force_page=False, generate_screenshot=True):
""" """
Generate a preview of a theme. Generate a preview of a theme.
@ -535,7 +507,8 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
verses['verse'] = 'V1' verses['verse'] = 'V1'
verses['footer'] = self.generate_footer() verses['footer'] = self.generate_footer()
self.load_verses([verses], is_sync=True) self.load_verses([verses], is_sync=True)
self._wait_and_process(1) # Wait for a second
wait_for(lambda: False, timeout=1)
self.force_page = False self.force_page = False
if generate_screenshot: if generate_screenshot:
return self.grab() return self.grab()
@ -550,8 +523,7 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
:param item: The :class:`~openlp.core.lib.serviceitem.ServiceItem` item object. :param item: The :class:`~openlp.core.lib.serviceitem.ServiceItem` item object.
""" """
while not self._is_initialised: wait_for(lambda: self._is_initialised)
QtWidgets.QApplication.instance().processEvents()
self.log_debug('format slide') self.log_debug('format slide')
if item: if item:
# Set theme for preview # Set theme for preview
@ -771,8 +743,10 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
:param text: The text to check. It may contain HTML tags. :param text: The text to check. It may contain HTML tags.
""" """
self.clear_slides() self.clear_slides()
self.log_debug('_text_fits_on_slide: 1\n{text}'.format(text=text))
self.run_javascript('Display.addTextSlide("v1", "{text}", "Dummy Footer");' self.run_javascript('Display.addTextSlide("v1", "{text}", "Dummy Footer");'
.format(text=text.replace('"', '\\"')), is_sync=True) .format(text=text.replace('"', '\\"')), is_sync=True)
self.log_debug('_text_fits_on_slide: 2')
does_text_fits = self.run_javascript('Display.doesContentFit();', is_sync=True) does_text_fits = self.run_javascript('Display.doesContentFit();', is_sync=True)
return does_text_fits return does_text_fits

View File

@ -25,18 +25,18 @@ import json
import logging import logging
import os import os
import copy import copy
import time
from PyQt5 import QtCore, QtWebChannel, QtWidgets from PyQt5 import QtCore, QtWebChannel, QtWidgets
from openlp.core.common.i18n import translate
from openlp.core.common.path import path_to_str
from openlp.core.common.settings import Settings
from openlp.core.common.registry import Registry
from openlp.core.common.applocation import AppLocation from openlp.core.common.applocation import AppLocation
from openlp.core.ui import HideMode from openlp.core.common.i18n import translate
from openlp.core.display.screens import ScreenList
from openlp.core.common.mixins import RegistryProperties from openlp.core.common.mixins import RegistryProperties
from openlp.core.common.path import path_to_str
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.common.utils import wait_for
from openlp.core.display.screens import ScreenList
from openlp.core.ui import HideMode
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -102,6 +102,21 @@ class MediaWatcher(QtCore.QObject):
self.muted.emit(is_muted) self.muted.emit(is_muted)
class DisplayWatcher(QtCore.QObject):
"""
This facilitates communication from the Display object in the browser back to the Python
"""
initialised = QtCore.pyqtSignal(bool)
@QtCore.pyqtSlot(bool)
def setInitialised(self, is_initialised):
"""
This method is called from the JS in the browser to set the _is_initialised attribute
"""
log.info('Display is initialised: {init}'.format(init=is_initialised))
self.initialised.emit(is_initialised)
class DisplayWindow(QtWidgets.QWidget, RegistryProperties): class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
""" """
This is a window to show the output This is a window to show the output
@ -137,10 +152,13 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
self.checkerboard_path = display_base_path / 'checkerboard.png' self.checkerboard_path = display_base_path / 'checkerboard.png'
self.openlp_splash_screen_path = display_base_path / 'openlp-splash-screen.png' self.openlp_splash_screen_path = display_base_path / 'openlp-splash-screen.png'
self.set_url(QtCore.QUrl.fromLocalFile(path_to_str(self.display_path))) self.set_url(QtCore.QUrl.fromLocalFile(path_to_str(self.display_path)))
self.media_watcher = MediaWatcher(self)
self.channel = QtWebChannel.QWebChannel(self) self.channel = QtWebChannel.QWebChannel(self)
self.media_watcher = MediaWatcher(self)
self.channel.registerObject('mediaWatcher', self.media_watcher) self.channel.registerObject('mediaWatcher', self.media_watcher)
self.display_watcher = DisplayWatcher(self)
self.channel.registerObject('displayWatcher', self.display_watcher)
self.webview.page().setWebChannel(self.channel) self.webview.page().setWebChannel(self.channel)
self.display_watcher.initialised.connect(self.on_initialised)
self.is_display = False self.is_display = False
self.scale = 1 self.scale = 1
self.hide_mode = None self.hide_mode = None
@ -155,6 +173,16 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
if len(ScreenList()) > 1 or Settings().value('core/display on monitor'): if len(ScreenList()) > 1 or Settings().value('core/display on monitor'):
self.show() self.show()
@property
def is_initialised(self):
return self._is_initialised
def on_initialised(self, is_initialised):
"""
Update the initialised status
"""
self._is_initialised = is_initialised
def update_from_screen(self, screen): def update_from_screen(self, screen):
""" """
Update the number and the geometry from the screen. Update the number and the geometry from the screen.
@ -208,7 +236,7 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
""" """
js_is_display = str(self.is_display).lower() js_is_display = str(self.is_display).lower()
self.run_javascript('Display.init({do_transitions});'.format(do_transitions=js_is_display)) self.run_javascript('Display.init({do_transitions});'.format(do_transitions=js_is_display))
self._is_initialised = True wait_for(lambda: self._is_initialised)
if self.scale != 1: if self.scale != 1:
self.set_scale(self.scale) self.set_scale(self.scale)
if self._can_show_startup_screen: if self._can_show_startup_screen:
@ -222,14 +250,8 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
:param is_sync: Run the script synchronously. Defaults to False :param is_sync: Run the script synchronously. Defaults to False
""" """
log.debug(script) log.debug(script)
# Wait for other scripts to finish # Wait for previous scripts to finish
end_time = time.time() + 10 wait_for(lambda: self.__script_done)
while not self.__script_done:
if time.time() > end_time:
log.error('Timed out waiting for preivous javascript script to finish')
break
time.sleep(0.1)
self.application.process_events()
if not is_sync: if not is_sync:
self.webview.page().runJavaScript(script) self.webview.page().runJavaScript(script)
else: else:
@ -244,14 +266,9 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
self.__script_result = result self.__script_result = result
self.webview.page().runJavaScript(script, handle_result) self.webview.page().runJavaScript(script, handle_result)
end_time = time.time() + 10 # Wait for script to finish
while not self.__script_done: if not wait_for(lambda: self.__script_done):
if time.time() > end_time: self.__script_done = True
self.__script_done = True
log.error('Timed out waiting for javascript script to finish')
break
time.sleep(0.001)
self.application.process_events()
return self.__script_result return self.__script_result
def go_to_slide(self, verse): def go_to_slide(self, verse):

View File

@ -43,24 +43,6 @@ class HideMode(object):
Screen = 3 Screen = 3
class AlertLocation(object):
"""
This is an enumeration class which controls where Alerts are placed on the screen.
``Top``
Place the text at the top of the screen.
``Middle``
Place the text in the middle of the screen.
``Bottom``
Place the text at the bottom of the screen.
"""
Top = 0
Middle = 1
Bottom = 2
class DisplayControllerType(object): class DisplayControllerType(object):
""" """
This is an enumeration class which says where a display controller originated from. This is an enumeration class which says where a display controller originated from.

View File

@ -37,6 +37,7 @@ from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.path import create_paths from openlp.core.common.path import create_paths
from openlp.core.common.registry import Registry, RegistryBase from openlp.core.common.registry import Registry, RegistryBase
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.core.common.utils import wait_for
from openlp.core.lib import build_icon, check_item_selected, create_thumb, get_text_file_string, validate_thumb from openlp.core.lib import build_icon, check_item_selected, create_thumb, get_text_file_string, validate_thumb
from openlp.core.lib.exceptions import ValidationError from openlp.core.lib.exceptions import ValidationError
from openlp.core.lib.theme import Theme from openlp.core.lib.theme import Theme
@ -165,7 +166,6 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
self.setup_ui(self) self.setup_ui(self)
self.global_theme = Settings().value(self.settings_section + '/global theme') self.global_theme = Settings().value(self.settings_section + '/global theme')
self.build_theme_path() self.build_theme_path()
self.upgrade_themes() # TODO: Can be removed when upgrade path from OpenLP 2.4 no longer needed
def bootstrap_post_set_up(self): def bootstrap_post_set_up(self):
""" """
@ -175,8 +175,14 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
self.theme_form = ThemeForm(self) self.theme_form = ThemeForm(self)
self.theme_form.path = self.theme_path self.theme_form.path = self.theme_path
self.file_rename_form = FileRenameForm() self.file_rename_form = FileRenameForm()
Registry().register_function('theme_update_global', self.change_global_from_tab)
def bootstrap_completion(self):
"""
process the bootstrap completion request
"""
self.upgrade_themes() # TODO: Can be removed when upgrade path from OpenLP 2.4 no longer needed
self.load_themes() self.load_themes()
Registry().register_function('theme_update_global', self.change_global_from_tab)
def upgrade_themes(self): def upgrade_themes(self):
""" """
@ -184,6 +190,8 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
:rtype: None :rtype: None
""" """
# Wait for 2 seconds to allow some other things to start processing first
wait_for(lambda: False, timeout=1)
xml_file_paths = AppLocation.get_section_data_path('themes').glob('*/*.xml') xml_file_paths = AppLocation.get_section_data_path('themes').glob('*/*.xml')
for xml_file_path in xml_file_paths: for xml_file_path in xml_file_paths:
theme_data = get_text_file_string(xml_file_path) theme_data = get_text_file_string(xml_file_path)
@ -722,7 +730,6 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
theme_name_list = theme_name_list or self.get_theme_names() theme_name_list = theme_name_list or self.get_theme_names()
self.progress_form.theme_list = theme_name_list self.progress_form.theme_list = theme_name_list
self.progress_form.show() self.progress_form.show()
self.progress_form.theme_display.wait_till_loaded()
for theme_name in theme_name_list: for theme_name in theme_name_list:
theme_data = self._get_theme_data(theme_name) theme_data = self._get_theme_data(theme_name)
preview_pixmap = self.progress_form.get_preview(theme_name, theme_data) preview_pixmap = self.progress_form.get_preview(theme_name, theme_data)

View File

@ -23,12 +23,13 @@ The theme regeneration progress dialog
""" """
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
from openlp.core.common.mixins import RegistryProperties, LogMixin
from openlp.core.common.utils import wait_for
from openlp.core.display.screens import ScreenList from openlp.core.display.screens import ScreenList
from openlp.core.ui.themeprogressdialog import UiThemeProgressDialog from openlp.core.ui.themeprogressdialog import UiThemeProgressDialog
from openlp.core.common.mixins import RegistryProperties
class ThemeProgressForm(QtWidgets.QDialog, UiThemeProgressDialog, RegistryProperties): class ThemeProgressForm(QtWidgets.QDialog, UiThemeProgressDialog, RegistryProperties, LogMixin):
""" """
The theme regeneration progress dialog The theme regeneration progress dialog
""" """
@ -38,9 +39,9 @@ class ThemeProgressForm(QtWidgets.QDialog, UiThemeProgressDialog, RegistryProper
self._theme_list = [] self._theme_list = []
def show(self): def show(self):
self.progress_bar.setValue(0)
self.progress_bar.setMinimum(0) self.progress_bar.setMinimum(0)
self.progress_bar.setMaximum(0) self.progress_bar.setMaximum(0)
self.progress_bar.setValue(0)
try: try:
screens = ScreenList() screens = ScreenList()
self.ratio = screens.current.display_geometry.width() / screens.current.display_geometry.height() self.ratio = screens.current.display_geometry.width() / screens.current.display_geometry.height()
@ -52,6 +53,7 @@ class ThemeProgressForm(QtWidgets.QDialog, UiThemeProgressDialog, RegistryProper
def get_preview(self, theme_name, theme_data): def get_preview(self, theme_name, theme_data):
self.label.setText(theme_name) self.label.setText(theme_name)
self.progress_bar.setValue(self.progress_bar.value() + 1) self.progress_bar.setValue(self.progress_bar.value() + 1)
wait_for(lambda: self.theme_display.is_initialised)
self.theme_display.set_scale(float(self.theme_display.width()) / self.renderer.width()) self.theme_display.set_scale(float(self.theme_display.width()) / self.renderer.width())
return self.theme_display.generate_preview(theme_data, generate_screenshot=True) return self.theme_display.generate_preview(theme_data, generate_screenshot=True)

View File

@ -26,13 +26,13 @@ from PyQt5 import QtGui
from openlp.core.state import State from openlp.core.state import State
from openlp.core.api.http import register_endpoint from openlp.core.api.http import register_endpoint
from openlp.core.common.actions import ActionList from openlp.core.common.actions import ActionList
from openlp.core.common.enum import AlertLocation
from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.core.lib.db import Manager from openlp.core.lib.db import Manager
from openlp.core.lib.plugin import Plugin, StringContent from openlp.core.lib.plugin import Plugin, StringContent
from openlp.core.lib.theme import VerticalType from openlp.core.lib.theme import VerticalType
from openlp.core.lib.ui import create_action from openlp.core.lib.ui import create_action
from openlp.core.ui import AlertLocation
from openlp.core.ui.icons import UiIcons from openlp.core.ui.icons import UiIcons
from openlp.plugins.alerts.endpoint import api_alerts_endpoint, alerts_endpoint from openlp.plugins.alerts.endpoint import api_alerts_endpoint, alerts_endpoint
from openlp.plugins.alerts.forms.alertform import AlertForm from openlp.plugins.alerts.forms.alertform import AlertForm

View File

@ -24,15 +24,15 @@ import logging
from openlp.core.state import State from openlp.core.state import State
from openlp.core.api.http import register_endpoint from openlp.core.api.http import register_endpoint
from openlp.core.common.actions import ActionList from openlp.core.common.actions import ActionList
from openlp.core.common.enum import BibleSearch, LayoutStyle, DisplayStyle, LanguageSelection
from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.i18n import UiStrings, translate
from openlp.core.ui.icons import UiIcons from openlp.core.ui.icons import UiIcons
from openlp.core.lib.plugin import Plugin, StringContent from openlp.core.lib.plugin import Plugin, StringContent
from openlp.core.lib.ui import create_action from openlp.core.lib.ui import create_action
from openlp.plugins.bibles.endpoint import api_bibles_endpoint, bibles_endpoint from openlp.plugins.bibles.endpoint import api_bibles_endpoint, bibles_endpoint
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, LanguageSelection
from openlp.plugins.bibles.lib.biblestab import BiblesTab from openlp.plugins.bibles.lib.biblestab import BiblesTab
from openlp.plugins.bibles.lib.manager import BibleManager from openlp.plugins.bibles.lib.manager import BibleManager
from openlp.plugins.bibles.lib.mediaitem import BibleMediaItem, BibleSearch from openlp.plugins.bibles.lib.mediaitem import BibleMediaItem
log = logging.getLogger(__name__) log = logging.getLogger(__name__)

View File

@ -21,10 +21,11 @@
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtWidgets
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.i18n import translate from openlp.core.common.i18n import translate
from openlp.core.lib.ui import create_button_box from openlp.core.lib.ui import create_button_box
from openlp.core.ui.icons import UiIcons from openlp.core.ui.icons import UiIcons
from openlp.plugins.bibles.lib import BibleStrings, LanguageSelection from openlp.plugins.bibles.lib import BibleStrings
from openlp.plugins.bibles.lib.db import BiblesResourcesDB from openlp.plugins.bibles.lib.db import BiblesResourcesDB

View File

@ -36,34 +36,6 @@ REFERENCE_MATCHES = {}
REFERENCE_SEPARATORS = {} REFERENCE_SEPARATORS = {}
class LayoutStyle(object):
"""
An enumeration for bible screen layout styles.
"""
VersePerSlide = 0
VersePerLine = 1
Continuous = 2
class DisplayStyle(object):
"""
An enumeration for bible text bracket display styles.
"""
NoBrackets = 0
Round = 1
Curly = 2
Square = 3
class LanguageSelection(object):
"""
An enumeration for bible bookname language. And standard strings for use throughout the bibles plugin.
"""
Bible = 0
Application = 1
English = 2
class BibleStrings(metaclass=Singleton): class BibleStrings(metaclass=Singleton):
""" """
Provide standard strings for objects to use. Provide standard strings for objects to use.

View File

@ -23,13 +23,13 @@ import logging
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common.enum import DisplayStyle, LanguageSelection, LayoutStyle
from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.core.lib.settingstab import SettingsTab from openlp.core.lib.settingstab import SettingsTab
from openlp.core.lib.ui import find_and_set_in_combo_box from openlp.core.lib.ui import find_and_set_in_combo_box
from openlp.plugins.bibles.lib import DisplayStyle, LanguageSelection, LayoutStyle, get_reference_separator, \ from openlp.plugins.bibles.lib import get_reference_separator, update_reference_separators
update_reference_separators
log = logging.getLogger(__name__) log = logging.getLogger(__name__)

View File

@ -33,11 +33,12 @@ from sqlalchemy.orm import class_mapper, mapper, relation
from sqlalchemy.orm.exc import UnmappedClassError from sqlalchemy.orm.exc import UnmappedClassError
from openlp.core.common import clean_filename from openlp.core.common import clean_filename
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.applocation import AppLocation from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import translate from openlp.core.common.i18n import translate
from openlp.core.lib.db import BaseModel, Manager, init_db from openlp.core.lib.db import BaseModel, Manager, init_db
from openlp.core.lib.ui import critical_error_message_box from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.bibles.lib import BibleStrings, LanguageSelection, upgrade from openlp.plugins.bibles.lib import BibleStrings, upgrade
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -307,7 +308,8 @@ class BibleDB(Manager):
:rtype: list[int] :rtype: list[int]
""" """
log.debug('get_book_ref_id_by_localised_name("{book}", "{lang}")'.format(book=book, lang=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 from openlp.core.common.enum import LanguageSelection
from openlp.plugins.bibles.lib import BibleStrings
book_names = BibleStrings().BookNames book_names = BibleStrings().BookNames
# escape reserved characters # escape reserved characters
for character in RESERVED_CHARACTERS: for character in RESERVED_CHARACTERS:

View File

@ -22,11 +22,12 @@ import logging
from pathlib import Path from pathlib import Path
from openlp.core.common import delete_file from openlp.core.common import delete_file
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.applocation import AppLocation from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.mixins import LogMixin, RegistryProperties from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.plugins.bibles.lib import LanguageSelection, parse_reference from openlp.plugins.bibles.lib import parse_reference
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from .importers.csvbible import CSVBible from .importers.csvbible import CSVBible

View File

@ -25,6 +25,7 @@ from enum import IntEnum, unique
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtWidgets
from openlp.core.common.enum import BibleSearch, DisplayStyle, LayoutStyle
from openlp.core.common.i18n import UiStrings, get_locale_key, translate from openlp.core.common.i18n import UiStrings, get_locale_key, translate
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
@ -37,8 +38,7 @@ from openlp.core.ui.icons import UiIcons
from openlp.core.widgets.edits import SearchEdit from openlp.core.widgets.edits import SearchEdit
from openlp.plugins.bibles.forms.bibleimportform import BibleImportForm from openlp.plugins.bibles.forms.bibleimportform import BibleImportForm
from openlp.plugins.bibles.forms.editbibleform import EditBibleForm from openlp.plugins.bibles.forms.editbibleform import EditBibleForm
from openlp.plugins.bibles.lib import DisplayStyle, LayoutStyle, get_reference_match, \ from openlp.plugins.bibles.lib import get_reference_match, get_reference_separator
get_reference_separator
from openlp.plugins.bibles.lib.versereferencelist import VerseReferenceList from openlp.plugins.bibles.lib.versereferencelist import VerseReferenceList
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -53,16 +53,6 @@ def get_reference_separators():
'list': get_reference_separator('sep_l_display')} 'list': get_reference_separator('sep_l_display')}
@unique
class BibleSearch(IntEnum):
"""
Enumeration class for the different search types for the "Search" tab.
"""
Reference = 1
Text = 2
Combined = 3
@unique @unique
class ResultsTab(IntEnum): class ResultsTab(IntEnum):
""" """

View File

@ -27,6 +27,7 @@ import logging
from openlp.core.state import State from openlp.core.state import State
from openlp.core.api.http import register_endpoint from openlp.core.api.http import register_endpoint
from openlp.core.common.enum import CustomSearch
from openlp.core.common.i18n import translate from openlp.core.common.i18n import translate
from openlp.core.lib import build_icon from openlp.core.lib import build_icon
from openlp.core.lib.db import Manager from openlp.core.lib.db import Manager
@ -34,7 +35,7 @@ from openlp.core.lib.plugin import Plugin, StringContent
from openlp.core.ui.icons import UiIcons from openlp.core.ui.icons import UiIcons
from openlp.plugins.custom.endpoint import api_custom_endpoint, custom_endpoint from openlp.plugins.custom.endpoint import api_custom_endpoint, custom_endpoint
from openlp.plugins.custom.lib.db import CustomSlide, init_schema from openlp.plugins.custom.lib.db import CustomSlide, init_schema
from openlp.plugins.custom.lib.mediaitem import CustomMediaItem, CustomSearch from openlp.plugins.custom.lib.mediaitem import CustomMediaItem
from openlp.plugins.custom.lib.customtab import CustomTab from openlp.plugins.custom.lib.customtab import CustomTab

View File

@ -24,6 +24,7 @@ import logging
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtWidgets
from sqlalchemy.sql import and_, func, or_ from sqlalchemy.sql import and_, func, or_
from openlp.core.common.enum import CustomSearch
from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
@ -41,14 +42,6 @@ from openlp.plugins.custom.lib.db import CustomSlide
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class CustomSearch(object):
"""
An enumeration for custom search methods.
"""
Titles = 1
Themes = 2
class CustomMediaItem(MediaManagerItem): class CustomMediaItem(MediaManagerItem):
""" """
This is the custom media manager item for Custom Slides. This is the custom media manager item for Custom Slides.

View File

@ -228,8 +228,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
:param media: The media :param media: The media
:param target_group: :param target_group:
""" """
# TODO needs to be fixed as no idea why this fails media.sort(key=lambda file_path: get_natural_key(os.path.split(str(file_path))[1]))
# media.sort(key=lambda file_path: get_natural_key(file_path.name))
file_name = translate('MediaPlugin.MediaItem', 'Live Stream') file_name = translate('MediaPlugin.MediaItem', 'Live Stream')
item_name = QtWidgets.QListWidgetItem(file_name) item_name = QtWidgets.QListWidgetItem(file_name)
item_name.setIcon(UiIcons().video) item_name.setIcon(UiIcons().video)
@ -281,13 +280,13 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
:return: The media list :return: The media list
""" """
media_file_paths = Settings().value(self.settings_section + '/media files') media_file_paths = Settings().value(self.settings_section + '/media files')
media_file_paths.sort(key=lambda file_path: get_natural_key(file_path.name)) media_file_paths.sort(key=lambda file_path: get_natural_key(os.path.split(str(file_path))[1]))
if media_type == MediaType.Audio: if media_type == MediaType.Audio:
extension = AUDIO_EXT extension = AUDIO_EXT
else: else:
extension = VIDEO_EXT extension = VIDEO_EXT
extension = [x[1:] for x in extension] extension = [x[1:] for x in extension]
media = [x for x in media_file_paths if x.suffix in extension] media = [x for x in media_file_paths if os.path.splitext(x)[1] in extension]
return media return media
def search(self, string, show_error): def search(self, string, show_error):

View File

@ -28,6 +28,7 @@ from sqlalchemy.sql import and_, or_
from openlp.core.state import State from openlp.core.state import State
from openlp.core.common.applocation import AppLocation from openlp.core.common.applocation import AppLocation
from openlp.core.common.enum import SongSearch
from openlp.core.common.i18n import UiStrings, get_natural_key, translate from openlp.core.common.i18n import UiStrings, get_natural_key, translate
from openlp.core.common.path import create_paths from openlp.core.common.path import create_paths
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
@ -51,21 +52,6 @@ from openlp.plugins.songs.lib.ui import SongStrings
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class SongSearch(object):
"""
An enumeration for song search methods.
"""
Entire = 1
Titles = 2
Lyrics = 3
Authors = 4
Topics = 5
Books = 6
Themes = 7
Copyright = 8
CCLInumber = 9
class SongMediaItem(MediaManagerItem): class SongMediaItem(MediaManagerItem):
""" """
This is the custom media manager item for Songs. This is the custom media manager item for Songs.

View File

@ -33,6 +33,7 @@ from PyQt5 import QtCore, QtWidgets
from openlp.core.state import State from openlp.core.state import State
from openlp.core.api.http import register_endpoint from openlp.core.api.http import register_endpoint
from openlp.core.common.actions import ActionList from openlp.core.common.actions import ActionList
from openlp.core.common.enum import SongSearch
from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.lib import build_icon from openlp.core.lib import build_icon
@ -48,7 +49,7 @@ from openlp.plugins.songs.lib import clean_song, upgrade
from openlp.plugins.songs.lib.db import Song, init_schema from openlp.plugins.songs.lib.db import Song, init_schema
from openlp.plugins.songs.lib.importer import SongFormat from openlp.plugins.songs.lib.importer import SongFormat
from openlp.plugins.songs.lib.importers.openlp import OpenLPSongImport from openlp.plugins.songs.lib.importers.openlp import OpenLPSongImport
from openlp.plugins.songs.lib.mediaitem import SongMediaItem, SongSearch from openlp.plugins.songs.lib.mediaitem import SongMediaItem
from openlp.plugins.songs.lib.songstab import SongsTab from openlp.plugins.songs.lib.songstab import SongsTab

View File

@ -58,7 +58,6 @@ class TestThemeManager(TestCase, TestMixin):
# GIVEN: A new a call to initialise # GIVEN: A new a call to initialise
self.theme_manager.setup_ui = MagicMock() self.theme_manager.setup_ui = MagicMock()
self.theme_manager.build_theme_path = MagicMock() self.theme_manager.build_theme_path = MagicMock()
self.theme_manager.upgrade_themes = MagicMock()
Settings().setValue('themes/global theme', 'my_theme') Settings().setValue('themes/global theme', 'my_theme')
# WHEN: the initialisation is run # WHEN: the initialisation is run
@ -68,7 +67,6 @@ class TestThemeManager(TestCase, TestMixin):
self.theme_manager.setup_ui.assert_called_once_with(self.theme_manager) self.theme_manager.setup_ui.assert_called_once_with(self.theme_manager)
assert self.theme_manager.global_theme == 'my_theme' assert self.theme_manager.global_theme == 'my_theme'
self.theme_manager.build_theme_path.assert_called_once_with() self.theme_manager.build_theme_path.assert_called_once_with()
self.theme_manager.upgrade_themes.assert_called_once_with()
@patch('openlp.core.ui.thememanager.create_paths') @patch('openlp.core.ui.thememanager.create_paths')
@patch('openlp.core.ui.thememanager.AppLocation.get_section_data_path') @patch('openlp.core.ui.thememanager.AppLocation.get_section_data_path')
@ -110,7 +108,6 @@ class TestThemeManager(TestCase, TestMixin):
Test the functions of bootstrap_post_setup are called. Test the functions of bootstrap_post_setup are called.
""" """
# GIVEN: # GIVEN:
self.theme_manager.load_themes = MagicMock()
self.theme_manager.theme_path = MagicMock() self.theme_manager.theme_path = MagicMock()
# WHEN: # WHEN:
@ -118,4 +115,21 @@ class TestThemeManager(TestCase, TestMixin):
self.theme_manager.bootstrap_post_set_up() self.theme_manager.bootstrap_post_set_up()
# THEN: # THEN:
assert 1 == self.theme_manager.load_themes.call_count, "load_themes should have been called once" assert self.theme_manager.progress_form is not None
assert self.theme_manager.theme_form is not None
assert self.theme_manager.file_rename_form is not None
def test_bootstrap_completion(self):
"""
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
self.theme_manager.load_themes = MagicMock()
self.theme_manager.upgrade_themes = MagicMock()
# WHEN:
self.theme_manager.bootstrap_completion()
# THEN:
self.theme_manager.upgrade_themes.assert_called_once()
self.theme_manager.load_themes.assert_called_once()

View File

@ -24,9 +24,9 @@ Functional tests to test the Bible Manager class and related methods.
from unittest import TestCase from unittest import TestCase
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.plugins.bibles.lib import LanguageSelection
from openlp.plugins.bibles.lib.manager import BibleManager from openlp.plugins.bibles.lib.manager import BibleManager
from tests.helpers.testmixin import TestMixin from tests.helpers.testmixin import TestMixin
from tests.utils.constants import TEST_RESOURCES_PATH from tests.utils.constants import TEST_RESOURCES_PATH

View File

@ -24,9 +24,10 @@ This module contains tests for the lib submodule of the Bibles plugin.
from unittest import TestCase from unittest import TestCase
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings from openlp.core.common.settings import Settings
from openlp.plugins.bibles.lib import LanguageSelection, parse_reference from openlp.plugins.bibles.lib import parse_reference
from openlp.plugins.bibles.lib.manager import BibleManager from openlp.plugins.bibles.lib.manager import BibleManager
from tests.helpers.testmixin import TestMixin from tests.helpers.testmixin import TestMixin
from tests.utils.constants import TEST_RESOURCES_PATH from tests.utils.constants import TEST_RESOURCES_PATH

View File

@ -1,5 +1,10 @@
// This is a mock QWebChannel // This is a mock QWebChannel
var qt = {webChannelTransport: 1}; var qt = {webChannelTransport: 1};
var displayWatcher = {
setInitialised: function (is_initialised) {
// do nothing
}
}
var QWebChannel = function (transport, callback) { var QWebChannel = function (transport, callback) {
callback({objects: {mediaWatcher: {}}}); callback({objects: {mediaWatcher: {}, displayWatcher: displayWatcher}});
}; };

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2019 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
Interface tests to test the themeManager class and related methods.
"""
from unittest.mock import MagicMock
from openlp.core.common.registry import Registry
from openlp.core.common.utils import wait_for
def test_wait_for(registry):
"""
Test the wait_for function
"""
# GIVEN: Mocked app and Registry
mock_app = MagicMock()
Registry().register('application', mock_app)
mock_func = MagicMock()
mock_func.side_effect = [False, True]
# WHEN: wait_for is run
wait_for(mock_func)
# THEN: the functions got called
assert mock_func.call_count == 2