diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 261bdbbbe..e2d3e2c68 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -324,11 +324,13 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R :param str new_theme_name: The new theme name of the theme :rtype: None """ + old_background = None if theme_data.background_type == 'image' or theme_data.background_type == 'video': + old_background = theme_data.background_filename theme_data.background_filename = self.theme_path / new_theme_name / theme_data.background_filename.name theme_data.theme_name = new_theme_name theme_data.extend_image_filename(self.theme_path) - self.save_theme(theme_data) + self.save_theme(theme_data, background_override=old_background) self.load_themes() def on_edit_theme(self, field=None): @@ -644,12 +646,13 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R return False return True - def save_theme(self, theme, image=None): + def save_theme(self, theme, image=None, background_override=None): """ Writes the theme to the disk and including the background image and thumbnail if necessary :param Theme theme: The theme data object. :param image: The theme thumbnail. Optionally. + :param background_override: Background to use rather than background_source. Optionally. :rtype: None """ name = theme.theme_name @@ -662,13 +665,17 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R except OSError: self.log_exception('Saving theme to file failed') if theme.background_source and theme.background_filename: + background_file = background_override + # Use theme source image if override doesn't exist + if not background_file or not background_file.exists(): + background_file = theme.background_source if self.old_background_image_path and theme.background_filename != self.old_background_image_path: delete_file(self.old_background_image_path) - if not theme.background_source.exists(): + if not background_file.exists(): self.log_warning('Background does not exist, retaining cached background') - elif theme.background_source != theme.background_filename: + elif background_file != theme.background_filename: try: - shutil.copyfile(theme.background_source, theme.background_filename) + shutil.copyfile(background_file, theme.background_filename) except OSError: self.log_exception('Failed to save theme image') if image: diff --git a/tests/functional/openlp_core/ui/test_thememanager.py b/tests/functional/openlp_core/ui/test_thememanager.py index 230c3014e..b7aae7c2c 100644 --- a/tests/functional/openlp_core/ui/test_thememanager.py +++ b/tests/functional/openlp_core/ui/test_thememanager.py @@ -219,6 +219,35 @@ class TestThemeManager(TestCase): # THEN: A warning should have happened due to attempting to copy a missing file mocked_log_warning.assert_called_once_with('Background does not exist, retaining cached background') + @patch('openlp.core.ui.thememanager.shutil') + @patch('openlp.core.ui.thememanager.delete_file') + @patch('openlp.core.ui.thememanager.create_paths') + def test_save_theme_background_override(self, mocked_paths, mocked_delete, mocked_shutil): + """ + Test that we log a warning if the new background is missing + """ + # GIVEN: A new theme manager instance, with invalid files. Setup as if the user + # has changed the background to a invalid path. + # Not using resource dir because I could potentially copy a file + folder_path = Path(mkdtemp()) + theme_manager = ThemeManager(None) + theme_manager.old_background_image_path = folder_path / 'old.png' + theme_manager.update_preview_images = MagicMock() + theme_manager.theme_path = MagicMock() + mocked_theme = MagicMock() + mocked_theme.theme_name = 'themename' + mocked_theme.background_filename = folder_path / 'new_cached.png' + # mocked_theme.background_source.exists() will return True + mocked_theme.background_source = MagicMock() + # override_background.exists() will return True + override_background = MagicMock() + + # WHEN: Calling save_theme with a background override + theme_manager.save_theme(mocked_theme, background_override=override_background) + + # THEN: The override_background should have been copied rather than the background_source + mocked_shutil.copyfile.assert_called_once_with(override_background, mocked_theme.background_filename) + def test_save_theme_special_char_name(self): """ Test that we can save themes with special characters in the name