Confirm deleting item from service

This commit is contained in:
Edward Birchall 2022-02-24 22:03:25 +00:00 committed by Tomas Groth
parent 9d598773ef
commit 66032f854a
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/x11 bypass wm': X11_BYPASS_DEFAULT,
'advanced/search as type': True, 'advanced/search as type': True,
'advanced/ui_theme_name': UiThemes.Automatic, 'advanced/ui_theme_name': UiThemes.Automatic,
'advanced/delete service item confirmation': False,
'alerts/font face': QtGui.QFont().family(), 'alerts/font face': QtGui.QFont().family(),
'alerts/font size': 40, 'alerts/font size': 40,
'alerts/db type': 'sqlite', '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.service_item_edit_form = ServiceItemEditForm()
self.start_time_form = StartTimeForm() 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): def add_media_suffixes(self):
""" """
Add the suffixes supported by :mod:`openlp.core.ui.media.vlcplayer` 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. Remove the current ServiceItem from the list.
""" """
item = self.find_service_item()[0] 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.service_items.remove(self.service_items[item])
self.repaint_service_list(item - 1, -1) self.repaint_service_list(item - 1, -1)
self.set_modified() self.set_modified()

View File

@ -133,6 +133,15 @@ class ServiceTab(SettingsTab):
self.next_item_radio_button.setObjectName('next_item_radio_button') self.next_item_radio_button.setObjectName('next_item_radio_button')
self.slide_layout.addWidget(self.next_item_radio_button) self.slide_layout.addWidget(self.next_item_radio_button)
self.right_layout.addWidget(self.slide_group_box) 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 # Push everything in both columns to the top
self.left_layout.addStretch() self.left_layout.addStretch()
self.right_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.end_slide_radio_button.setText(translate('OpenLP.ServiceTab', '&Remain on Slide'))
self.wrap_slide_radio_button.setText(translate('OpenLP.ServiceTab', '&Wrap around')) 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')) 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): def load(self):
""" """
@ -216,6 +229,8 @@ class ServiceTab(SettingsTab):
self.wrap_slide_radio_button.setChecked(True) self.wrap_slide_radio_button.setChecked(True)
else: else:
self.next_item_radio_button.setChecked(True) 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): def save(self):
""" """
@ -242,6 +257,8 @@ class ServiceTab(SettingsTab):
# Service Item Wrapping # Service Item Wrapping
self.settings.setValue('advanced/slide limits', self.slide_limits) self.settings.setValue('advanced/slide limits', self.slide_limits)
self.settings_form.register_post_process('slidecontroller_update_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() self.post_set_up()
def post_set_up(self): def post_set_up(self):

View File

@ -25,6 +25,7 @@ from pathlib import Path
from unittest import TestCase from unittest import TestCase
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
import pytest
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import ThemeLevel 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() 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): def test_on_load_service_clicked(registry):
"""Test that a service is loaded when you click the button""" """Test that a service is loaded when you click the button"""
# GIVEN: A service manager # GIVEN: A service manager