mirror of https://gitlab.com/openlp/openlp.git
Merge branch 'issue-1383' into 'master'
Try to fix an issue that only seems to happen on macOS Closes #1383 See merge request openlp/openlp!640
This commit is contained in:
commit
e4a6d647dc
|
@ -21,6 +21,7 @@
|
|||
"""
|
||||
This is the main window, where all the action happens.
|
||||
"""
|
||||
import json
|
||||
import shutil
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime, date
|
||||
|
@ -36,6 +37,7 @@ from openlp.core.common import add_actions
|
|||
from openlp.core.common.actions import ActionList, CategoryOrder
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.i18n import LanguageManager, UiStrings, translate
|
||||
from openlp.core.common.json import OpenLPJSONDecoder
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
from openlp.core.common.path import create_paths, resolve
|
||||
from openlp.core.common.platform import is_macosx, is_win
|
||||
|
@ -531,7 +533,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
self.screen_updating_lock = Lock()
|
||||
|
||||
@contextmanager
|
||||
def _show_wait_dialog(self, title, message):
|
||||
def _show_wait_dialog(self, title: str, message: str):
|
||||
"""
|
||||
Show a wait dialog, wait for some tasks to complete, and then close it.
|
||||
"""
|
||||
|
@ -612,7 +614,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
if widget:
|
||||
widget.on_focus()
|
||||
|
||||
def on_media_tool_box_changed(self, index):
|
||||
def on_media_tool_box_changed(self, index: int):
|
||||
"""
|
||||
Focus a widget when the media toolbox changes.
|
||||
"""
|
||||
|
@ -620,7 +622,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
if widget:
|
||||
widget.on_focus()
|
||||
|
||||
def on_new_version(self, version):
|
||||
def on_new_version(self, version: str):
|
||||
"""
|
||||
Notifies the user that a newer version of OpenLP is available. Triggered by delay thread and cannot display
|
||||
popup.
|
||||
|
@ -632,7 +634,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
'https://openlp.org/.').format(new=version, current=get_version()[u'full'])
|
||||
QtWidgets.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Version Updated'), version_text)
|
||||
|
||||
def on_new_remote_version(self, version):
|
||||
def on_new_remote_version(self, version: str):
|
||||
"""
|
||||
Notifies the user that a newer version of the web remote is available. Triggered by delay thread and cannot
|
||||
display popup.
|
||||
|
@ -755,7 +757,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
QtWidgets.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Main Display Blanked'),
|
||||
translate('OpenLP.MainWindow', 'The Main Display has been blanked out'))
|
||||
|
||||
def error_message(self, title, message):
|
||||
def error_message(self, title: str, message: str):
|
||||
"""
|
||||
Display an error message
|
||||
|
||||
|
@ -766,7 +768,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
self.application.splash.close()
|
||||
QtWidgets.QMessageBox.critical(self, title, message)
|
||||
|
||||
def warning_message(self, title, message):
|
||||
def warning_message(self, title: str, message: str):
|
||||
"""
|
||||
Display a warning message
|
||||
|
||||
|
@ -777,7 +779,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
self.application.splash.close()
|
||||
QtWidgets.QMessageBox.warning(self, title, message)
|
||||
|
||||
def information_message(self, title, message):
|
||||
def information_message(self, title: str, message: str):
|
||||
"""
|
||||
Display an informational message
|
||||
|
||||
|
@ -1011,8 +1013,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
self.settings.setValue('user interface/is preset layout', True)
|
||||
self.settings.setValue('projector/show after wizard', True)
|
||||
|
||||
def set_view_mode(self, media=True, service=True, theme=True, preview=True,
|
||||
live=True, projector=True, mode='') -> None:
|
||||
def set_view_mode(self, media: bool = True, service: bool = True, theme: bool = True, preview: bool = True,
|
||||
live: bool = True, projector: bool = True, mode: str = '') -> None:
|
||||
"""
|
||||
Set OpenLP to a different view mode.
|
||||
"""
|
||||
|
@ -1059,7 +1061,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
finally:
|
||||
self.screen_updating_lock.release()
|
||||
|
||||
def closeEvent(self, event):
|
||||
def closeEvent(self, event: QtGui.QCloseEvent):
|
||||
"""
|
||||
Hook to close the main window and display windows on exit
|
||||
"""
|
||||
|
@ -1104,7 +1106,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
# If we just did a settings import, close without saving changes.
|
||||
self.clean_up(save_settings=not self.settings_imported)
|
||||
|
||||
def eventFilter(self, obj, event):
|
||||
def eventFilter(self, obj, event: QtCore.QEvent):
|
||||
if event.type() == QtCore.QEvent.FileOpen:
|
||||
file_name = event.file()
|
||||
self.log_debug('Got open file event for {name}!'.format(name=file_name))
|
||||
|
@ -1125,7 +1127,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
|
||||
return super(MainWindow, self).eventFilter(obj, event)
|
||||
|
||||
def clean_up(self, save_settings=True):
|
||||
def clean_up(self, save_settings: bool = True):
|
||||
"""
|
||||
Runs all the cleanup code before OpenLP shuts down.
|
||||
|
||||
|
@ -1153,7 +1155,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
# Needed for Windows to stop crashes on exit
|
||||
Registry().remove('application')
|
||||
|
||||
def set_service_modified(self, modified, file_name):
|
||||
def set_service_modified(self, modified: bool, file_name: Path | str):
|
||||
"""
|
||||
This method is called from the ServiceManager to set the title of the main window.
|
||||
|
||||
|
@ -1166,7 +1168,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
title = '{title} - {name}'.format(title=UiStrings().OpenLP, name=file_name)
|
||||
self.setWindowTitle(title)
|
||||
|
||||
def show_status_message(self, message):
|
||||
def show_status_message(self, message: str):
|
||||
"""
|
||||
Show a message in the status bar
|
||||
"""
|
||||
|
@ -1225,25 +1227,25 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
self.settings.setValue('user interface/is preset layout', False)
|
||||
self.settings.setValue('user interface/show themes', self.theme_manager_dock.isVisible())
|
||||
|
||||
def set_preview_panel_visibility(self, visible):
|
||||
def set_preview_panel_visibility(self, is_visible: bool):
|
||||
"""
|
||||
Sets the visibility of the preview panel including saving the setting and updating the menu.
|
||||
|
||||
:param visible: A bool giving the state to set the panel to
|
||||
:param is_visible: A bool giving the state to set the panel to
|
||||
True - Visible
|
||||
False - Hidden
|
||||
|
||||
"""
|
||||
self.preview_controller.panel.setVisible(visible)
|
||||
self.settings.setValue('user interface/preview panel', visible)
|
||||
self.view_preview_panel.setChecked(visible)
|
||||
self.preview_controller.panel.setVisible(is_visible)
|
||||
self.settings.setValue('user interface/preview panel', is_visible)
|
||||
self.view_preview_panel.setChecked(is_visible)
|
||||
self.settings.setValue('user interface/is preset layout', False)
|
||||
|
||||
def set_lock_panel(self, lock):
|
||||
def set_lock_panel(self, is_locked: bool):
|
||||
"""
|
||||
Sets the ability to stop the toolbars being changed.
|
||||
"""
|
||||
if lock:
|
||||
if is_locked:
|
||||
self.theme_manager_dock.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.NoDockWidgetFeatures)
|
||||
self.service_manager_dock.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.NoDockWidgetFeatures)
|
||||
self.media_manager_dock.setFeatures(QtWidgets.QDockWidget.DockWidgetFeature.NoDockWidgetFeatures)
|
||||
|
@ -1267,20 +1269,19 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
self.view_projector_manager_item.setEnabled(True)
|
||||
self.view_preview_panel.setEnabled(True)
|
||||
self.view_live_panel.setEnabled(True)
|
||||
self.settings.setValue('user interface/lock panel', lock)
|
||||
self.settings.setValue('user interface/lock panel', is_locked)
|
||||
|
||||
def set_live_panel_visibility(self, visible):
|
||||
def set_live_panel_visibility(self, is_visible: bool):
|
||||
"""
|
||||
Sets the visibility of the live panel including saving the setting and updating the menu.
|
||||
|
||||
|
||||
:param visible: A bool giving the state to set the panel to
|
||||
:param is_visible: A bool giving the state to set the panel to
|
||||
True - Visible
|
||||
False - Hidden
|
||||
"""
|
||||
self.live_controller.panel.setVisible(visible)
|
||||
self.settings.setValue('user interface/live panel', visible)
|
||||
self.view_live_panel.setChecked(visible)
|
||||
self.live_controller.panel.setVisible(is_visible)
|
||||
self.settings.setValue('user interface/live panel', is_visible)
|
||||
self.view_live_panel.setChecked(is_visible)
|
||||
self.settings.setValue('user interface/is preset layout', False)
|
||||
|
||||
def load_settings(self):
|
||||
|
@ -1303,7 +1304,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
# which was True (by default) < OpenLP 2.1.
|
||||
self.control_splitter.setChildrenCollapsible(False)
|
||||
|
||||
def _window_position_is_valid(self, position, geometry):
|
||||
def _window_position_is_valid(self, position: QtCore.QPoint, geometry: QtCore.QRect):
|
||||
"""
|
||||
Checks if the saved window position is still valid by checking if the bar at the top of the window
|
||||
(which allows the user to move the window) appears on one of the screens.
|
||||
|
@ -1347,6 +1348,23 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
Updates the recent file menu with the latest list of service files accessed.
|
||||
"""
|
||||
recent_file_count = self.settings.value('advanced/recent file count')
|
||||
# This is to get around a weird issue that we're seeing on macOS. We've not been able to reproduce it
|
||||
# ourselves, but hopefully this will catch the issue.
|
||||
# See https://gitlab.com/openlp/openlp/-/issues/1383
|
||||
if isinstance(self.recent_files, str):
|
||||
try:
|
||||
self.recent_files = json.loads(self.recent_files, cls=OpenLPJSONDecoder)
|
||||
except json.JSONDecodeError as e:
|
||||
self.log_exception(e)
|
||||
self.recent_files = []
|
||||
elif isinstance(self.recent_files, list) and self.recent_files and isinstance(self.recent_files[0], str) and \
|
||||
self.recent_files[0].startswith('['):
|
||||
try:
|
||||
self.recent_files = json.loads(self.recent_files[0], cls=OpenLPJSONDecoder)
|
||||
except json.JSONDecodeError as e:
|
||||
self.log_exception(e)
|
||||
self.recent_files = []
|
||||
# Now continue as usual...
|
||||
self.recent_files_menu.clear()
|
||||
count = 0
|
||||
for recent_path in self.recent_files:
|
||||
|
@ -1369,7 +1387,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
enabled=bool(self.recent_files), triggers=self.clear_recent_file_menu)
|
||||
add_actions(self.recent_files_menu, (None, clear_recent_files_action))
|
||||
|
||||
def add_recent_file(self, filename):
|
||||
def add_recent_file(self, filename: Path | str):
|
||||
"""
|
||||
Adds a service to the list of recently used files.
|
||||
|
||||
|
@ -1393,7 +1411,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
"""
|
||||
self.recent_files = []
|
||||
|
||||
def display_progress_bar(self, size):
|
||||
def display_progress_bar(self, size: int):
|
||||
"""
|
||||
Make Progress bar visible and set size
|
||||
"""
|
||||
|
@ -1402,7 +1420,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
self.load_progress_bar.setValue(0)
|
||||
self.application.process_events()
|
||||
|
||||
def increment_progress_bar(self, increment=1):
|
||||
def increment_progress_bar(self, increment: int = 1):
|
||||
"""
|
||||
Increase the Progress Bar by the value in increment.
|
||||
|
||||
|
@ -1417,7 +1435,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
"""
|
||||
self.timer_id = self.startTimer(2500)
|
||||
|
||||
def timerEvent(self, event):
|
||||
def timerEvent(self, event: QtCore.QTimerEvent):
|
||||
"""
|
||||
Remove the Progress bar from view.
|
||||
"""
|
||||
|
|
|
@ -40,6 +40,10 @@ from openlp.core.ui.mainwindow import MainWindow
|
|||
from tests.utils.constants import TEST_RESOURCES_PATH, RESOURCE_PATH
|
||||
|
||||
|
||||
JSON_RECENT_FILES = ('[{"parts": ["/", "path", "to", "service-1.osz"], "json_meta": {"class": "Path", "version": 1}},'
|
||||
'{"parts": ["/", "path", "to", "service-2.osz"], "json_meta": {"class": "Path", "version": 1}}]')
|
||||
|
||||
|
||||
def _create_mock_action(parent, name, **kwargs):
|
||||
"""
|
||||
Create a fake action with some "real" attributes
|
||||
|
@ -823,7 +827,45 @@ def test_update_recent_files_menu(mocked_create_action, mocked_add_actions, Mock
|
|||
# GIVEN: A mocked settings object, and some other fixtures
|
||||
MockPath.return_value.is_file.side_effect = [False, True]
|
||||
settings.setValue('advanced/recent file count', 5)
|
||||
main_window_reduced.recent_files = [None, '/fake/path', '/path/to/real/file']
|
||||
main_window_reduced.recent_files = [None, '/fake/path', Path('/path/to/real/file')]
|
||||
main_window_reduced.recent_files_menu = MagicMock()
|
||||
|
||||
# WHEN: update_recent_files_menu() is called
|
||||
main_window_reduced.update_recent_files_menu()
|
||||
|
||||
# THEN: There should be no errors
|
||||
assert mocked_create_action.call_count == 2
|
||||
|
||||
|
||||
@patch('openlp.core.ui.mainwindow.Path')
|
||||
@patch('openlp.core.ui.mainwindow.add_actions')
|
||||
@patch('openlp.core.ui.mainwindow.create_action')
|
||||
def test_update_recent_files_menu_as_string(mocked_create_action, mocked_add_actions, MockPath, settings, registry,
|
||||
main_window_reduced):
|
||||
"""Test that the update_recent_files_menu() method works correctly when the entry is a string instead of a list"""
|
||||
# GIVEN: A mocked settings object, and some other fixtures
|
||||
MockPath.return_value.is_file.side_effect = [False, True]
|
||||
settings.setValue('advanced/recent file count', 5)
|
||||
main_window_reduced.recent_files = JSON_RECENT_FILES
|
||||
main_window_reduced.recent_files_menu = MagicMock()
|
||||
|
||||
# WHEN: update_recent_files_menu() is called
|
||||
main_window_reduced.update_recent_files_menu()
|
||||
|
||||
# THEN: There should be no errors
|
||||
assert mocked_create_action.call_count == 2
|
||||
|
||||
|
||||
@patch('openlp.core.ui.mainwindow.Path')
|
||||
@patch('openlp.core.ui.mainwindow.add_actions')
|
||||
@patch('openlp.core.ui.mainwindow.create_action')
|
||||
def test_update_recent_files_menu_as_list_with_string(mocked_create_action, mocked_add_actions, MockPath, settings,
|
||||
registry, main_window_reduced):
|
||||
"""Test that the update_recent_files_menu() method works correctly when the entry is a string instead of a list"""
|
||||
# GIVEN: A mocked settings object, and some other fixtures
|
||||
MockPath.return_value.is_file.side_effect = [False, True]
|
||||
settings.setValue('advanced/recent file count', 5)
|
||||
main_window_reduced.recent_files = [JSON_RECENT_FILES]
|
||||
main_window_reduced.recent_files_menu = MagicMock()
|
||||
|
||||
# WHEN: update_recent_files_menu() is called
|
||||
|
|
Loading…
Reference in New Issue