mirror of https://gitlab.com/openlp/openlp.git
Update some system messaging
This commit is contained in:
parent
23c8d784a5
commit
96a6f2ab64
|
@ -25,7 +25,7 @@ import os
|
|||
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.state import State, MessageType
|
||||
from openlp.core.common import extension_loader
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.i18n import translate, UiStrings
|
||||
|
@ -169,13 +169,16 @@ class PluginManager(RegistryBase, LogMixin, RegistryProperties):
|
|||
if uninitialised_plugins:
|
||||
display_text = translate('OpenLP.PluginManager', 'Unable to initialise the following plugins:') + \
|
||||
'\n\n'.join(uninitialised_plugins) + '\n\n'
|
||||
error_text = State().get_text()
|
||||
error_text = State().get_text(MessageType.Error)
|
||||
info_text = State().get_text(MessageType.Information)
|
||||
if error_text:
|
||||
display_text = display_text + error_text + '\n'
|
||||
if display_text:
|
||||
display_text = display_text + translate('OpenLP.PluginManager', 'See the log file for more details')
|
||||
display_text = display_text + error_text + '\n' + \
|
||||
translate('OpenLP.PluginManager', 'See the log file for more details')
|
||||
QtWidgets.QMessageBox.critical(None, UiStrings().Error, display_text,
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
if info_text:
|
||||
QtWidgets.QMessageBox.information(None, UiStrings().Error, info_text,
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
|
||||
def finalise_plugins(self):
|
||||
"""
|
||||
|
|
|
@ -26,30 +26,38 @@ All the core functions of the OpenLP application including the GUI, settings, lo
|
|||
contained within the openlp.core module.
|
||||
"""
|
||||
import logging
|
||||
from enum import IntEnum
|
||||
|
||||
from openlp.core.common import Singleton
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.mixins import LogMixin
|
||||
from openlp.core.lib.plugin import PluginStatus
|
||||
from openlp.core.lib.plugin import Plugin, PluginStatus
|
||||
|
||||
|
||||
log = logging.getLogger()
|
||||
|
||||
|
||||
class MessageType(IntEnum):
|
||||
Error = 1
|
||||
Warning = 2
|
||||
Information = 3
|
||||
|
||||
|
||||
class StateModule(LogMixin):
|
||||
def __init__(self):
|
||||
"""
|
||||
Holder of State information per module
|
||||
"""
|
||||
super(StateModule, self).__init__()
|
||||
self.name = None
|
||||
self.order = 0
|
||||
self.is_plugin = None
|
||||
self.status = PluginStatus.Inactive
|
||||
self.pass_preconditions = False
|
||||
self.requires = None
|
||||
self.required_by = None
|
||||
self.text = None
|
||||
self.name: str | None = None
|
||||
self.order: int = 0
|
||||
self.is_plugin: bool = False
|
||||
self.status: PluginStatus = PluginStatus.Inactive
|
||||
self.pass_preconditions: bool = False
|
||||
self.requires: str | None = None
|
||||
self.required_by: list | None = None
|
||||
self.text: str | None = None
|
||||
self.message_type: MessageType = MessageType.Error
|
||||
|
||||
|
||||
class State(LogMixin, metaclass=Singleton):
|
||||
|
@ -60,7 +68,8 @@ class State(LogMixin, metaclass=Singleton):
|
|||
def save_settings(self):
|
||||
pass
|
||||
|
||||
def add_service(self, name, order, is_plugin=False, status=PluginStatus.Active, requires=None):
|
||||
def add_service(self, name: str, order: int, is_plugin: bool = False, status: PluginStatus = PluginStatus.Active,
|
||||
requires: str | None = None):
|
||||
"""
|
||||
Add a module to the array and load dependencies. There will only be one item per module
|
||||
:param name: Module name
|
||||
|
@ -83,7 +92,7 @@ class State(LogMixin, metaclass=Singleton):
|
|||
if requires not in self.modules[requires].required_by:
|
||||
self.modules[requires].required_by.append(name)
|
||||
|
||||
def missing_text(self, name, text):
|
||||
def missing_text(self, name: str, text: str, type_: MessageType = MessageType.Error):
|
||||
"""
|
||||
Updates the preconditions state of a module
|
||||
|
||||
|
@ -92,31 +101,32 @@ class State(LogMixin, metaclass=Singleton):
|
|||
:return:
|
||||
"""
|
||||
self.modules[name].text = text
|
||||
self.modules[name].message_type = type_
|
||||
|
||||
def get_text(self):
|
||||
def get_text(self, type_: MessageType | None = None) -> str:
|
||||
"""
|
||||
return an string of error text
|
||||
:return: a string of text
|
||||
"""
|
||||
error_text = ''
|
||||
all_text = ''
|
||||
for mod in self.modules:
|
||||
if self.modules[mod].text:
|
||||
error_text = error_text + self.modules[mod].text + '\n'
|
||||
return error_text
|
||||
if self.modules[mod].text and (not type_ or self.modules[mod].message_type == type_):
|
||||
all_text = all_text + self.modules[mod].text + '\n'
|
||||
return all_text
|
||||
|
||||
def update_pre_conditions(self, name, status):
|
||||
def update_pre_conditions(self, name: str, is_active: bool):
|
||||
"""
|
||||
Updates the preconditions state of a module
|
||||
|
||||
:param name: Module name
|
||||
:param status: Module new status
|
||||
:param is_active: Module new status
|
||||
:return:
|
||||
"""
|
||||
self.modules[name].pass_preconditions = status
|
||||
self.modules[name].pass_preconditions = is_active
|
||||
if self.modules[name].is_plugin:
|
||||
plugin = Registry().get('{mod}_plugin'.format(mod=name))
|
||||
if status:
|
||||
self.log_debug('Plugin {plugin} active'.format(plugin=str(plugin.name)))
|
||||
plugin = Registry().get(f'{name}_plugin')
|
||||
if is_active:
|
||||
self.log_debug(f'Plugin {plugin.name} active')
|
||||
plugin.set_status()
|
||||
else:
|
||||
plugin.status = PluginStatus.Disabled
|
||||
|
@ -136,10 +146,10 @@ class State(LogMixin, metaclass=Singleton):
|
|||
mdl[pl] = self.modules[pl]
|
||||
self.modules = mdl
|
||||
|
||||
def is_module_active(self, name):
|
||||
def is_module_active(self, name) -> bool:
|
||||
return self.modules[name].status == PluginStatus.Active
|
||||
|
||||
def check_preconditions(self, name):
|
||||
def check_preconditions(self, name: str) -> bool:
|
||||
"""
|
||||
Checks if a modules preconditions have been met.
|
||||
|
||||
|
@ -157,7 +167,7 @@ class State(LogMixin, metaclass=Singleton):
|
|||
# Module is missing so therefore not found.
|
||||
return False
|
||||
|
||||
def list_plugins(self):
|
||||
def list_plugins(self) -> list[Plugin]:
|
||||
"""
|
||||
Return a list of plugins
|
||||
:return: an array of plugins
|
||||
|
@ -165,5 +175,5 @@ class State(LogMixin, metaclass=Singleton):
|
|||
plugins = []
|
||||
for mod in self.modules:
|
||||
if self.modules[mod].is_plugin:
|
||||
plugins.append(Registry().get('{mod}_plugin'.format(mod=mod)))
|
||||
plugins.append(Registry().get(f'{mod}_plugin'))
|
||||
return plugins
|
||||
|
|
|
@ -1039,12 +1039,12 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
and (datetime.now() - self.screen_change_timestamp).seconds < 5
|
||||
should_show_messagebox = self.settings_form.isHidden() and not has_shown_messagebox_recently
|
||||
if should_show_messagebox:
|
||||
QtWidgets.QMessageBox.warning(self, translate('OpenLP.MainWindow', 'Screen setup has changed'),
|
||||
translate('OpenLP.MainWindow',
|
||||
'The screen setup has changed. '
|
||||
'OpenLP will try to automatically select a display screen, but '
|
||||
'you should consider updating the screen settings.'),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
QtWidgets.QMessageBox.information(self, translate('OpenLP.MainWindow', 'Screen setup has changed'),
|
||||
translate('OpenLP.MainWindow',
|
||||
'The screen setup has changed. OpenLP will try to '
|
||||
'automatically select a display screen, but '
|
||||
'you should consider updating the screen settings.'),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
self.screen_change_timestamp = datetime.now()
|
||||
self.application.set_busy_cursor()
|
||||
self.renderer.resize(self.live_controller.screens.current.display_geometry.size())
|
||||
|
|
|
@ -42,7 +42,7 @@ from openlp.core.common.registry import Registry, RegistryBase
|
|||
from openlp.core.display.window import DisplayWindow
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities
|
||||
from openlp.core.lib.ui import critical_error_message_box, warning_message_box
|
||||
from openlp.core.state import State
|
||||
from openlp.core.state import State, MessageType
|
||||
from openlp.core.ui import DisplayControllerType, HideMode
|
||||
from openlp.core.ui.slidecontroller import SlideController
|
||||
from openlp.core.ui.media import MediaState, ItemMediaInfo, MediaType, parse_optical_path, parse_stream_path, \
|
||||
|
@ -116,6 +116,7 @@ class MediaController(QtWidgets.QWidget, RegistryBase, LogMixin, RegistryPropert
|
|||
else:
|
||||
if hasattr(self.main_window, 'splash') and self.main_window.splash.isVisible():
|
||||
self.main_window.splash.hide()
|
||||
message_type = MessageType.Error
|
||||
generic_message = translate('OpenLP.MediaController',
|
||||
'OpenLP requires the following libraries in order to show videos and other '
|
||||
'media, but they are not installed. Please install these libraries to enable '
|
||||
|
@ -125,8 +126,11 @@ class MediaController(QtWidgets.QWidget, RegistryBase, LogMixin, RegistryPropert
|
|||
'repository: https://rpmfusion.org/')
|
||||
if is_macosx():
|
||||
message = translate('OpenLP.MediaController',
|
||||
'macOS is missing VLC. Please download and install from the VLC web site: '
|
||||
'https://www.videolan.org/vlc/')
|
||||
'<strong>OpenLP could not detect VLC.</strong> You will not be able to play media '
|
||||
'without it. Please download and install from the VLC web site: '
|
||||
'<a href="https://www.videolan.org/vlc/download-macosx.html">'
|
||||
'https://www.videolan.org/vlc/</a>')
|
||||
message_type = MessageType.Information
|
||||
else:
|
||||
packages = []
|
||||
if not has_vlc:
|
||||
|
@ -136,7 +140,7 @@ class MediaController(QtWidgets.QWidget, RegistryBase, LogMixin, RegistryPropert
|
|||
message = generic_message + '\n\n' + ', '.join(packages)
|
||||
if not has_vlc and is_linux(distro='fedora'):
|
||||
message += '\n\n' + fedora_rpmfusion
|
||||
State().missing_text('media_live', message)
|
||||
State().missing_text('media_live', message, message_type)
|
||||
return True
|
||||
|
||||
def bootstrap_post_set_up(self):
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
##########################################################################
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.state import State, MessageType
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.lib.plugin import PluginStatus
|
||||
|
||||
|
@ -158,10 +158,12 @@ def test_missing_text(state):
|
|||
State().modules['test'] = MagicMock()
|
||||
|
||||
# WHEN: missing_text() is called
|
||||
State().missing_text('test', 'Test test')
|
||||
State().missing_text('test', 'Test test', MessageType.Information)
|
||||
|
||||
# THEN: The text is set
|
||||
assert State().modules['test'].text == 'Test test', 'The text on the module should have been set'
|
||||
assert State().modules['test'].message_type == MessageType.Information, \
|
||||
'The message type on the module should have been set'
|
||||
|
||||
|
||||
def test_get_text(state):
|
||||
|
@ -169,7 +171,8 @@ def test_get_text(state):
|
|||
Test that the get_text() method returns the text of all the states
|
||||
"""
|
||||
# GIVEN: Some states with text
|
||||
State().modules.update({'test1': MagicMock(text='Test 1'), 'test2': MagicMock(text='Test 2')})
|
||||
State().modules.update({'test1': MagicMock(text='Test 1', message_type=MessageType.Error),
|
||||
'test2': MagicMock(text='Test 2', message_type=MessageType.Information)})
|
||||
|
||||
# WHEN: get_text() is called
|
||||
result = State().get_text()
|
||||
|
@ -178,6 +181,21 @@ def test_get_text(state):
|
|||
assert result == 'Test 1\nTest 2\n', 'The full text is returned'
|
||||
|
||||
|
||||
def test_get_text_single_type(state):
|
||||
"""
|
||||
Test that the get_text() method returns the text of only that particular message type
|
||||
"""
|
||||
# GIVEN: Some states with text
|
||||
State().modules.update({'test1': MagicMock(text='Test 1', message_type=MessageType.Error),
|
||||
'test2': MagicMock(text='Test 2', message_type=MessageType.Information)})
|
||||
|
||||
# WHEN: get_text() is called
|
||||
result = State().get_text(MessageType.Information)
|
||||
|
||||
# THEN: The correct text is returned
|
||||
assert result == 'Test 2\n', 'Only the information text is returned'
|
||||
|
||||
|
||||
def test_check_preconditions_no_required(state):
|
||||
"""
|
||||
Test that the check_preconditions() method returns the correct attribute when there are no requirements
|
||||
|
|
|
@ -757,8 +757,8 @@ def test_load_settings_view_mode_live(mocked_view_mode, main_window, settings):
|
|||
mocked_view_mode.assert_called_with(True, True, True, True, False, True)
|
||||
|
||||
|
||||
@patch('openlp.core.ui.mainwindow.QtWidgets.QMessageBox.warning')
|
||||
def test_screen_changed_modal(mocked_warning, main_window):
|
||||
@patch('openlp.core.ui.mainwindow.QtWidgets.QMessageBox.information')
|
||||
def test_screen_changed_modal(mocked_information: MagicMock, main_window: MainWindow):
|
||||
"""
|
||||
Test that the screen changed modal is shown whether a 'config_screen_changed' event is dispatched
|
||||
"""
|
||||
|
@ -771,11 +771,12 @@ def test_screen_changed_modal(mocked_warning, main_window):
|
|||
Registry().execute('config_screen_changed')
|
||||
|
||||
# THEN: The modal should be called once
|
||||
mocked_warning.assert_called_once()
|
||||
mocked_information.assert_called_once()
|
||||
|
||||
|
||||
@patch('openlp.core.ui.mainwindow.QtWidgets.QMessageBox.warning')
|
||||
def test_screen_changed_modal_sets_timestamp_after_blocking_on_modal(mocked_warning, main_window):
|
||||
@patch('openlp.core.ui.mainwindow.QtWidgets.QMessageBox.information')
|
||||
def test_screen_changed_modal_sets_timestamp_after_blocking_on_modal(mocked_information: MagicMock,
|
||||
main_window: MainWindow):
|
||||
"""
|
||||
Test that the screen changed modal latest shown timestamp is set after showing warning message, so
|
||||
that duplicate modals due to event spamming on 'config_screen_changed' in less than 5 seconds is mitigated.
|
||||
|
@ -790,7 +791,7 @@ def test_screen_changed_modal_sets_timestamp_after_blocking_on_modal(mocked_warn
|
|||
|
||||
# THEN: main_window.screen_change_timestamp should have a timestamp, indicating that timestamp is set after
|
||||
# the blocking modal is shown.
|
||||
mocked_warning.assert_called_once()
|
||||
mocked_information.assert_called_once()
|
||||
assert main_window.screen_change_timestamp is not None
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue