Merge branch 'issue-886-confirm-delete-from-service' into 'master'

Confirm deleting item from service

Closes #886

See merge request openlp/openlp!427
This commit is contained in:
Tomas Groth 2022-02-24 22:03:25 +00:00
commit f988c6bb9c
4 changed files with 132 additions and 1 deletions

View File

@ -186,6 +186,7 @@ class Settings(QtCore.QSettings):
'advanced/x11 bypass wm': X11_BYPASS_DEFAULT,
'advanced/search as type': True,
'advanced/ui_theme_name': UiThemes.Automatic,
'advanced/delete service item confirmation': False,
'alerts/font face': QtGui.QFont().family(),
'alerts/font size': 40,
'alerts/db type': 'sqlite',

View File

@ -359,6 +359,18 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
self.service_item_edit_form = ServiceItemEditForm()
self.start_time_form = StartTimeForm()
def _delete_confirmation_dialog(self):
msg_box = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Question,
translate('OpenLP.ServiceManager', 'Delete item from service'),
translate('OpenLP.ServiceManager', 'Are you sure you want to delete '
'this item from the service?'),
QtWidgets.QMessageBox.StandardButtons(
QtWidgets.QMessageBox.Close | QtWidgets.QMessageBox.Cancel), self)
del_button = msg_box.button(QtWidgets.QMessageBox.Close)
del_button.setText(translate('OpenLP.ServiceManager', '&Delete item'))
msg_box.setDefaultButton(QtWidgets.QMessageBox.Close)
return msg_box.exec()
def add_media_suffixes(self):
"""
Add the suffixes supported by :mod:`openlp.core.ui.media.vlcplayer`
@ -1276,7 +1288,8 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
Remove the current ServiceItem from the list.
"""
item = self.find_service_item()[0]
if item != -1:
if item != -1 and (not self.settings.value('advanced/delete service item confirmation') or
self._delete_confirmation_dialog() == QtWidgets.QMessageBox.Close):
self.service_items.remove(self.service_items[item])
self.repaint_service_list(item - 1, -1)
self.set_modified()

View File

@ -133,6 +133,15 @@ class ServiceTab(SettingsTab):
self.next_item_radio_button.setObjectName('next_item_radio_button')
self.slide_layout.addWidget(self.next_item_radio_button)
self.right_layout.addWidget(self.slide_group_box)
# Service Editing
self.service_editing_groupbox = QtWidgets.QGroupBox(self.left_column)
self.service_editing_groupbox.setObjectName('service_editing_groupbox')
self.service_editing_layout = QtWidgets.QFormLayout(self.service_editing_groupbox)
self.service_editing_layout.setObjectName('service_editing_layout')
self.service_editing_check_box = QtWidgets.QCheckBox(self.service_editing_groupbox)
self.service_editing_check_box.setObjectName('service_editing_check_box')
self.service_editing_layout.addRow(self.service_editing_check_box)
self.right_layout.addWidget(self.service_editing_groupbox)
# Push everything in both columns to the top
self.left_layout.addStretch()
self.right_layout.addStretch()
@ -189,6 +198,10 @@ class ServiceTab(SettingsTab):
self.end_slide_radio_button.setText(translate('OpenLP.ServiceTab', '&Remain on Slide'))
self.wrap_slide_radio_button.setText(translate('OpenLP.ServiceTab', '&Wrap around'))
self.next_item_radio_button.setText(translate('OpenLP.ServiceTab', '&Move to next/previous service item'))
# Service Editing
self.service_editing_groupbox.setTitle(translate('OpenLP.ServiceTab', 'Service Editing'))
self.service_editing_check_box.setText(translate('OpenLP.ServiceTab', 'Show confirmation box when deleting '
'item from service'))
def load(self):
"""
@ -216,6 +229,8 @@ class ServiceTab(SettingsTab):
self.wrap_slide_radio_button.setChecked(True)
else:
self.next_item_radio_button.setChecked(True)
# Service Editing
self.service_editing_check_box.setChecked(self.settings.value('advanced/delete service item confirmation'))
def save(self):
"""
@ -242,6 +257,8 @@ class ServiceTab(SettingsTab):
# Service Item Wrapping
self.settings.setValue('advanced/slide limits', self.slide_limits)
self.settings_form.register_post_process('slidecontroller_update_slide_limits')
# Service Editing
self.settings.setValue('advanced/delete service item confirmation', self.service_editing_check_box.isChecked())
self.post_set_up()
def post_set_up(self):

View File

@ -25,6 +25,7 @@ from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
import pytest
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import ThemeLevel
@ -1097,6 +1098,105 @@ def test_on_new_service_clicked_unmodified_blank_service(MockQMessageBox, regist
service_manager.new_file.assert_called_once_with()
def _create_mock_action(parent, name, **kwargs):
"""
Create a fake action with some "real" attributes
"""
action = QtWidgets.QAction(parent)
action.setObjectName(name)
if kwargs.get('triggers'):
action.triggered.connect(kwargs.pop('triggers'))
return action
def _add_service_item(s_manager):
"adds a mocked service item to the passed service manager"
mocked_plugin = MagicMock()
mocked_plugin.name = 'songs'
service_item = ServiceItem(mocked_plugin)
service_item.add_icon()
slide = "Test slide"
service_item.add_from_text(slide)
service_item.title = "Test item"
s_manager.add_service_item(service_item, rebuild=True, selected=True)
@pytest.fixture()
def service_manager(registry, settings):
"""Setup a service manager with a service item and a few mocked registry entries"""
# Mocked registry entries
Registry().register('main_window', MagicMock())
Registry().register('live_controller', MagicMock())
Registry().register('renderer', MagicMock())
# Service manager
service_manager = ServiceManager()
add_toolbar_action_patcher = patch('openlp.core.ui.servicemanager.OpenLPToolbar.add_toolbar_action')
mocked_add_toolbar_action = add_toolbar_action_patcher.start()
mocked_add_toolbar_action.side_effect = \
lambda name, **kwargs: _create_mock_action(service_manager.toolbar, name, **kwargs)
service_manager.setup_ui(service_manager)
yield service_manager
del service_manager
add_toolbar_action_patcher.stop()
def test_on_delete_from_service_confirmation_disabled(settings, service_manager):
"""
Test that when the on_delete_from_service function is called and
confirmation for deleting items is disabled, the currently selected
item is removed.
"""
# GIVEN delete item confirmation is disabled and a mock service item
settings.setValue('advanced/delete service item confirmation', False)
_add_service_item(service_manager)
# WHEN the on_delete_from_service function is called
service_manager.on_delete_from_service()
# THEN the service_items list should be empty
assert len(service_manager.service_items) == 0
def test_on_delete_from_service_confirmation_enabled_choose_delete(settings, service_manager):
"""
Test that when the on_delete_from_service function is called and
confirmation for deleting items is enabled, and the user confirms
deletion, the currently selected item is removed from the service.
"""
# GIVEN delete item confirmation is enabled and a mock service item
settings.setValue('advanced/delete service item confirmation', True)
_add_service_item(service_manager)
# WHEN the on_delete_from_service function is called and the user chooses to delete
service_manager._delete_confirmation_dialog = MagicMock(return_value=QtWidgets.QMessageBox.Close)
service_manager.on_delete_from_service()
# THEN the service_items list should be empty
assert len(service_manager.service_items) == 0
def test_on_delete_from_service_confirmation_enabled_choose_cancel(settings, service_manager):
"""
Test that when the on_delete_from_service function is called and
confirmation for deleting items is enabled, and the user confirms
deletion, the service remains unchanged.
"""
# GIVEN delete item confirmation is enabled a mock service item
settings.setValue('advanced/delete service item confirmation', True)
_add_service_item(service_manager)
service_items_copy = service_manager.service_items.copy()
# WHEN the on_delete_from_service function is called and the user cancels
service_manager._delete_confirmation_dialog = MagicMock(return_value=QtWidgets.QMessageBox.Cancel)
service_manager.on_delete_from_service()
# THEN the service_items list should be unchanged
assert service_manager.service_items == service_items_copy
def test_on_load_service_clicked(registry):
"""Test that a service is loaded when you click the button"""
# GIVEN: A service manager