forked from openlp/openlp
Merge branch 'master' of gitlab.com:openlp/openlp
This commit is contained in:
commit
49f30e497c
109
openlp/core/common/enum.py
Normal file
109
openlp/core/common/enum.py
Normal 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
|
49
openlp/core/common/utils.py
Normal file
49
openlp/core/common/utils.py
Normal 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
|
@ -383,6 +383,7 @@ var Display = {
|
||||
init: function (doTransitions=false) {
|
||||
Display._doTransitions = doTransitions;
|
||||
Reveal.initialize(Display._revealConfig);
|
||||
displayWatcher.setInitialised(true);
|
||||
},
|
||||
/**
|
||||
* Reinitialise Reveal
|
||||
@ -1134,4 +1135,5 @@ var Display = {
|
||||
};
|
||||
new QWebChannel(qt.webChannelTransport, function (channel) {
|
||||
window.mediaWatcher = channel.objects.mediaWatcher;
|
||||
window.displayWatcher = channel.objects.displayWatcher;
|
||||
});
|
||||
|
@ -36,6 +36,7 @@ from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.mixins import LogMixin
|
||||
from openlp.core.common.registry import Registry, RegistryBase
|
||||
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.window import DisplayWindow
|
||||
from openlp.core.lib import ItemCapabilities
|
||||
@ -486,35 +487,6 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
|
||||
footer_html = 'Dummy footer text'
|
||||
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):
|
||||
"""
|
||||
Generate a preview of a theme.
|
||||
@ -535,7 +507,8 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
|
||||
verses['verse'] = 'V1'
|
||||
verses['footer'] = self.generate_footer()
|
||||
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
|
||||
if generate_screenshot:
|
||||
return self.grab()
|
||||
@ -550,8 +523,7 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
|
||||
:param item: The :class:`~openlp.core.lib.serviceitem.ServiceItem` item object.
|
||||
|
||||
"""
|
||||
while not self._is_initialised:
|
||||
QtWidgets.QApplication.instance().processEvents()
|
||||
wait_for(lambda: self._is_initialised)
|
||||
self.log_debug('format slide')
|
||||
if item:
|
||||
# Set theme for preview
|
||||
@ -771,8 +743,10 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
|
||||
:param text: The text to check. It may contain HTML tags.
|
||||
"""
|
||||
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");'
|
||||
.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)
|
||||
return does_text_fits
|
||||
|
||||
|
@ -25,18 +25,18 @@ import json
|
||||
import logging
|
||||
import os
|
||||
import copy
|
||||
import time
|
||||
|
||||
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.ui import HideMode
|
||||
from openlp.core.display.screens import ScreenList
|
||||
from openlp.core.common.i18n import translate
|
||||
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__)
|
||||
|
||||
@ -102,6 +102,21 @@ class MediaWatcher(QtCore.QObject):
|
||||
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):
|
||||
"""
|
||||
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.openlp_splash_screen_path = display_base_path / 'openlp-splash-screen.png'
|
||||
self.set_url(QtCore.QUrl.fromLocalFile(path_to_str(self.display_path)))
|
||||
self.media_watcher = MediaWatcher(self)
|
||||
self.channel = QtWebChannel.QWebChannel(self)
|
||||
self.media_watcher = MediaWatcher(self)
|
||||
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.display_watcher.initialised.connect(self.on_initialised)
|
||||
self.is_display = False
|
||||
self.scale = 1
|
||||
self.hide_mode = None
|
||||
@ -155,6 +173,16 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
if len(ScreenList()) > 1 or Settings().value('core/display on monitor'):
|
||||
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):
|
||||
"""
|
||||
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()
|
||||
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:
|
||||
self.set_scale(self.scale)
|
||||
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
|
||||
"""
|
||||
log.debug(script)
|
||||
# Wait for other scripts to finish
|
||||
end_time = time.time() + 10
|
||||
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()
|
||||
# Wait for previous scripts to finish
|
||||
wait_for(lambda: self.__script_done)
|
||||
if not is_sync:
|
||||
self.webview.page().runJavaScript(script)
|
||||
else:
|
||||
@ -244,14 +266,9 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
self.__script_result = result
|
||||
|
||||
self.webview.page().runJavaScript(script, handle_result)
|
||||
end_time = time.time() + 10
|
||||
while not self.__script_done:
|
||||
if time.time() > end_time:
|
||||
self.__script_done = True
|
||||
log.error('Timed out waiting for javascript script to finish')
|
||||
break
|
||||
time.sleep(0.001)
|
||||
self.application.process_events()
|
||||
# Wait for script to finish
|
||||
if not wait_for(lambda: self.__script_done):
|
||||
self.__script_done = True
|
||||
return self.__script_result
|
||||
|
||||
def go_to_slide(self, verse):
|
||||
|
@ -43,24 +43,6 @@ class HideMode(object):
|
||||
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):
|
||||
"""
|
||||
This is an enumeration class which says where a display controller originated from.
|
||||
|
@ -37,6 +37,7 @@ from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
from openlp.core.common.path import create_paths
|
||||
from openlp.core.common.registry import Registry, RegistryBase
|
||||
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.exceptions import ValidationError
|
||||
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.global_theme = Settings().value(self.settings_section + '/global theme')
|
||||
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):
|
||||
"""
|
||||
@ -175,8 +175,14 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
|
||||
self.theme_form = ThemeForm(self)
|
||||
self.theme_form.path = self.theme_path
|
||||
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()
|
||||
Registry().register_function('theme_update_global', self.change_global_from_tab)
|
||||
|
||||
def upgrade_themes(self):
|
||||
"""
|
||||
@ -184,6 +190,8 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
|
||||
|
||||
: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')
|
||||
for xml_file_path in xml_file_paths:
|
||||
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()
|
||||
self.progress_form.theme_list = theme_name_list
|
||||
self.progress_form.show()
|
||||
self.progress_form.theme_display.wait_till_loaded()
|
||||
for theme_name in theme_name_list:
|
||||
theme_data = self._get_theme_data(theme_name)
|
||||
preview_pixmap = self.progress_form.get_preview(theme_name, theme_data)
|
||||
|
@ -23,12 +23,13 @@ The theme regeneration progress dialog
|
||||
"""
|
||||
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.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
|
||||
"""
|
||||
@ -38,9 +39,9 @@ class ThemeProgressForm(QtWidgets.QDialog, UiThemeProgressDialog, RegistryProper
|
||||
self._theme_list = []
|
||||
|
||||
def show(self):
|
||||
self.progress_bar.setValue(0)
|
||||
self.progress_bar.setMinimum(0)
|
||||
self.progress_bar.setMaximum(0)
|
||||
self.progress_bar.setValue(0)
|
||||
try:
|
||||
screens = ScreenList()
|
||||
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):
|
||||
self.label.setText(theme_name)
|
||||
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())
|
||||
return self.theme_display.generate_preview(theme_data, generate_screenshot=True)
|
||||
|
||||
|
@ -26,13 +26,13 @@ from PyQt5 import QtGui
|
||||
from openlp.core.state import State
|
||||
from openlp.core.api.http import register_endpoint
|
||||
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.settings import Settings
|
||||
from openlp.core.lib.db import Manager
|
||||
from openlp.core.lib.plugin import Plugin, StringContent
|
||||
from openlp.core.lib.theme import VerticalType
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.core.ui import AlertLocation
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.plugins.alerts.endpoint import api_alerts_endpoint, alerts_endpoint
|
||||
from openlp.plugins.alerts.forms.alertform import AlertForm
|
||||
|
@ -24,15 +24,15 @@ import logging
|
||||
from openlp.core.state import State
|
||||
from openlp.core.api.http import register_endpoint
|
||||
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.ui.icons import UiIcons
|
||||
from openlp.core.lib.plugin import Plugin, StringContent
|
||||
from openlp.core.lib.ui import create_action
|
||||
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.manager import BibleManager
|
||||
from openlp.plugins.bibles.lib.mediaitem import BibleMediaItem, BibleSearch
|
||||
from openlp.plugins.bibles.lib.mediaitem import BibleMediaItem
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -21,10 +21,11 @@
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.enum import LanguageSelection
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
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
|
||||
|
||||
|
||||
|
@ -36,34 +36,6 @@ REFERENCE_MATCHES = {}
|
||||
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):
|
||||
"""
|
||||
Provide standard strings for objects to use.
|
||||
|
@ -23,13 +23,13 @@ import logging
|
||||
|
||||
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.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib.settingstab import SettingsTab
|
||||
from openlp.core.lib.ui import find_and_set_in_combo_box
|
||||
from openlp.plugins.bibles.lib import DisplayStyle, LanguageSelection, LayoutStyle, get_reference_separator, \
|
||||
update_reference_separators
|
||||
from openlp.plugins.bibles.lib import get_reference_separator, update_reference_separators
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -33,11 +33,12 @@ from sqlalchemy.orm import class_mapper, mapper, relation
|
||||
from sqlalchemy.orm.exc import UnmappedClassError
|
||||
|
||||
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.i18n import translate
|
||||
from openlp.core.lib.db import BaseModel, Manager, init_db
|
||||
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__)
|
||||
@ -307,7 +308,8 @@ class BibleDB(Manager):
|
||||
:rtype: list[int]
|
||||
"""
|
||||
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
|
||||
# escape reserved characters
|
||||
for character in RESERVED_CHARACTERS:
|
||||
|
@ -22,11 +22,12 @@ import logging
|
||||
from pathlib import Path
|
||||
|
||||
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.i18n import UiStrings, translate
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
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 .importers.csvbible import CSVBible
|
||||
|
@ -25,6 +25,7 @@ from enum import IntEnum, unique
|
||||
|
||||
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.registry import Registry
|
||||
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.plugins.bibles.forms.bibleimportform import BibleImportForm
|
||||
from openlp.plugins.bibles.forms.editbibleform import EditBibleForm
|
||||
from openlp.plugins.bibles.lib import DisplayStyle, LayoutStyle, get_reference_match, \
|
||||
get_reference_separator
|
||||
from openlp.plugins.bibles.lib import get_reference_match, get_reference_separator
|
||||
from openlp.plugins.bibles.lib.versereferencelist import VerseReferenceList
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -53,16 +53,6 @@ def get_reference_separators():
|
||||
'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
|
||||
class ResultsTab(IntEnum):
|
||||
"""
|
||||
|
@ -27,6 +27,7 @@ import logging
|
||||
|
||||
from openlp.core.state import State
|
||||
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.lib import build_icon
|
||||
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.plugins.custom.endpoint import api_custom_endpoint, custom_endpoint
|
||||
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
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ import logging
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
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.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
@ -41,14 +42,6 @@ from openlp.plugins.custom.lib.db import CustomSlide
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CustomSearch(object):
|
||||
"""
|
||||
An enumeration for custom search methods.
|
||||
"""
|
||||
Titles = 1
|
||||
Themes = 2
|
||||
|
||||
|
||||
class CustomMediaItem(MediaManagerItem):
|
||||
"""
|
||||
This is the custom media manager item for Custom Slides.
|
||||
|
@ -228,8 +228,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
:param media: The media
|
||||
:param target_group:
|
||||
"""
|
||||
# TODO needs to be fixed as no idea why this fails
|
||||
# media.sort(key=lambda file_path: get_natural_key(file_path.name))
|
||||
media.sort(key=lambda file_path: get_natural_key(os.path.split(str(file_path))[1]))
|
||||
file_name = translate('MediaPlugin.MediaItem', 'Live Stream')
|
||||
item_name = QtWidgets.QListWidgetItem(file_name)
|
||||
item_name.setIcon(UiIcons().video)
|
||||
@ -281,13 +280,13 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
:return: The media list
|
||||
"""
|
||||
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:
|
||||
extension = AUDIO_EXT
|
||||
else:
|
||||
extension = VIDEO_EXT
|
||||
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
|
||||
|
||||
def search(self, string, show_error):
|
||||
|
@ -28,6 +28,7 @@ from sqlalchemy.sql import and_, or_
|
||||
|
||||
from openlp.core.state import State
|
||||
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.path import create_paths
|
||||
from openlp.core.common.registry import Registry
|
||||
@ -51,21 +52,6 @@ from openlp.plugins.songs.lib.ui import SongStrings
|
||||
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):
|
||||
"""
|
||||
This is the custom media manager item for Songs.
|
||||
|
@ -33,6 +33,7 @@ from PyQt5 import QtCore, QtWidgets
|
||||
from openlp.core.state import State
|
||||
from openlp.core.api.http import register_endpoint
|
||||
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.registry import Registry
|
||||
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.importer import SongFormat
|
||||
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
|
||||
|
||||
|
||||
|
@ -58,7 +58,6 @@ class TestThemeManager(TestCase, TestMixin):
|
||||
# GIVEN: A new a call to initialise
|
||||
self.theme_manager.setup_ui = MagicMock()
|
||||
self.theme_manager.build_theme_path = MagicMock()
|
||||
self.theme_manager.upgrade_themes = MagicMock()
|
||||
Settings().setValue('themes/global theme', 'my_theme')
|
||||
|
||||
# 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)
|
||||
assert self.theme_manager.global_theme == 'my_theme'
|
||||
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.AppLocation.get_section_data_path')
|
||||
@ -110,7 +108,6 @@ class TestThemeManager(TestCase, TestMixin):
|
||||
Test the functions of bootstrap_post_setup are called.
|
||||
"""
|
||||
# GIVEN:
|
||||
self.theme_manager.load_themes = MagicMock()
|
||||
self.theme_manager.theme_path = MagicMock()
|
||||
|
||||
# WHEN:
|
||||
@ -118,4 +115,21 @@ class TestThemeManager(TestCase, TestMixin):
|
||||
self.theme_manager.bootstrap_post_set_up()
|
||||
|
||||
# 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()
|
||||
|
@ -24,9 +24,9 @@ Functional tests to test the Bible Manager class and related methods.
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from openlp.core.common.enum import LanguageSelection
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.plugins.bibles.lib import LanguageSelection
|
||||
from openlp.plugins.bibles.lib.manager import BibleManager
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
from tests.utils.constants import TEST_RESOURCES_PATH
|
||||
|
@ -24,9 +24,10 @@ This module contains tests for the lib submodule of the Bibles plugin.
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from openlp.core.common.enum import LanguageSelection
|
||||
from openlp.core.common.registry import Registry
|
||||
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 tests.helpers.testmixin import TestMixin
|
||||
from tests.utils.constants import TEST_RESOURCES_PATH
|
||||
|
@ -1,5 +1,10 @@
|
||||
// This is a mock QWebChannel
|
||||
var qt = {webChannelTransport: 1};
|
||||
var displayWatcher = {
|
||||
setInitialised: function (is_initialised) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
var QWebChannel = function (transport, callback) {
|
||||
callback({objects: {mediaWatcher: {}}});
|
||||
callback({objects: {mediaWatcher: {}, displayWatcher: displayWatcher}});
|
||||
};
|
||||
|
44
tests/openlp_core/common/test_utils.py
Normal file
44
tests/openlp_core/common/test_utils.py
Normal 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
|
Loading…
Reference in New Issue
Block a user