Confirmation form

This commit is contained in:
robbie jackson 2021-04-15 17:33:10 +00:00 committed by Raoul Snyman
parent 61d6cddd0a
commit d7fe052afc
4 changed files with 236 additions and 7 deletions

View File

@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2021 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
from PyQt5 import QtGui, QtWidgets, Qt
from openlp.core.ui.icons import UiIcons
class Ui_ConfirmationDialog():
"""
The UI for the Confirmation dialog.
"""
def setup_ui(self, confirmation_dialog, title, items, message, width=400, height=600):
"""
Set up the UI for the confirmation dialog.
:param confirmation_dialog: The QDialog object to set up.
:param items: A list (or other iterable) containing the items
:param message: The confirmation message to display
:param width: Width of the dialog window
:param height: Height of the dialog window
:return: None
"""
# overall aspects for confirmation dialog
confirmation_dialog.setObjectName('confirmation_dialog')
confirmation_dialog.setWindowIcon(UiIcons().main_icon)
confirmation_dialog.resize(width, height)
confirmation_dialog.setWindowTitle(title)
self.confirmation_layout = QtWidgets.QVBoxLayout(confirmation_dialog)
self.confirmation_layout.setObjectName('confirmation_layout')
# listview to display the items
self.listview = QtWidgets.QListView(self)
self.listview.setObjectName("confirmation listview")
# make the entries read-only
self.listview.setEditTriggers(Qt.QAbstractItemView.NoEditTriggers)
self.confirmation_layout.addWidget(self.listview)
# add the items to the listview model
model = QtGui.QStandardItemModel()
self.listview.setModel(model)
for item in items:
model.appendRow(QtGui.QStandardItem(item))
# confirmation message and Yes/No buttons
self.message_and_buttons = QtWidgets.QWidget(confirmation_dialog)
self.message_and_buttons.setObjectName('message and buttons')
self.message_and_buttons_layout = QtWidgets.QHBoxLayout(self.message_and_buttons)
self.message_and_buttons_layout.setObjectName('message and buttons layout')
self.message_label = QtWidgets.QLabel(message)
self.message_label.setObjectName('message')
self.message_label.setWordWrap(True)
self.message_and_buttons_layout.addWidget(self.message_label)
button_types = QtWidgets.QDialogButtonBox.Yes | QtWidgets.QDialogButtonBox.No
self.buttonBox = QtWidgets.QDialogButtonBox(button_types)
self.buttonBox.setObjectName('buttons')
self.message_and_buttons_layout.addWidget(self.buttonBox)
self.confirmation_layout.addWidget(self.message_and_buttons)
# slot connections
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2021 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
A general-purpose confirmation form. This can be used to obtain confirmation
that the user wants to delete a list of items, for example.
It is implemented as a QDialog containing:
- a QListView to display the list of items (eg the items to be deleted)
- a message which asks the user for confirmation
- Yes and No buttons, with Yes being the default
After instantiating a ConfirmationForm object the calling code must call exec() on the instance.
This runs the Qt dialog, which returns the usual 0 (for No) or 1 (for Yes)
"""
from PyQt5 import QtCore, QtWidgets
from openlp.core.ui.confirmationdialog import Ui_ConfirmationDialog
class ConfirmationForm(QtWidgets.QDialog, Ui_ConfirmationDialog):
"""
The Confirmation form
"""
def __init__(self, parent, title, items, message, width=400, height=600):
"""
:param parent: The parent QWidget
:param title: The title to be applied to the QDialog window
:param items: A list (or other iterable) of Strings for the items
:param message: The confirmation message to display
:param width: Width of the dialog window
:param height: Height of the dialog window
"""
super(ConfirmationForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint |
QtCore.Qt.WindowCloseButtonHint)
self.setup_ui(self, title, items, message, width, height)

View File

@ -38,6 +38,7 @@ from openlp.core.lib.plugin import PluginStatus
from openlp.core.lib.serviceitem import ItemCapabilities from openlp.core.lib.serviceitem import ItemCapabilities
from openlp.core.lib.ui import create_widget_action, critical_error_message_box from openlp.core.lib.ui import create_widget_action, critical_error_message_box
from openlp.core.ui.icons import UiIcons from openlp.core.ui.icons import UiIcons
from openlp.core.ui.confirmationform import ConfirmationForm
from openlp.plugins.songs.forms.editsongform import EditSongForm from openlp.plugins.songs.forms.editsongform import EditSongForm
from openlp.plugins.songs.forms.songexportform import SongExportForm from openlp.plugins.songs.forms.songexportform import SongExportForm
from openlp.plugins.songs.forms.songimportform import SongImportForm from openlp.plugins.songs.forms.songimportform import SongImportForm
@ -490,16 +491,15 @@ class SongMediaItem(MediaManagerItem):
def on_delete_click(self): def on_delete_click(self):
""" """
Remove a song from the list and database Remove a song or songs from the list and database
""" """
if check_item_selected(self.list_view, UiStrings().SelectDelete): if check_item_selected(self.list_view, UiStrings().SelectDelete):
items = self.list_view.selectedItems() items = self.list_view.selectedItems()
if QtWidgets.QMessageBox.question( item_strings = map(lambda i: i.text(), items)
self, UiStrings().ConfirmDelete, delete_confirmed = ConfirmationForm(self, UiStrings().ConfirmDelete, item_strings,
translate('SongsPlugin.MediaItem', translate('SongsPlugin.MediaItem',
'Are you sure you want to delete the following songs?') + 'Are you sure you want to delete these songs?')).exec()
'\n\n- {songs}'.format(songs='\n- '.join([item.text() for item in items])), if not delete_confirmed:
defaultButton=QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.No:
return return
self.application.set_busy_cursor() self.application.set_busy_cursor()
self.main_window.display_progress_bar(len(items)) self.main_window.display_progress_bar(len(items))

View File

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2021 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
Test the Confirmation Form
"""
from unittest.mock import patch
from PyQt5 import QtWidgets, QtTest, QtCore
from openlp.core.ui.confirmationform import ConfirmationForm
def test_confirmation_form_ui_setup(settings):
"""
Test checking the UI elements are set up correctly
"""
# GIVEN: A ConfirmationForm class
# WHEN: A ConfirmationForm object is created
form = ConfirmationForm(None, "title", ["item1", "item2", "item3"], "confirm?")
# THEN: The UI elements should reflect the parameters passed
assert form.windowTitle() == "title"
assert form.findChild(QtWidgets.QListView, "confirmation listview").model().rowCount() == 3
assert form.findChild(QtWidgets.QListView, "confirmation listview").model().item(0).text() == "item1"
assert form.findChild(QtWidgets.QListView, "confirmation listview").model().item(1).text() == "item2"
assert form.findChild(QtWidgets.QListView, "confirmation listview").model().item(2).text() == "item3"
assert form.findChild(QtWidgets.QLabel, "message").text() == "confirm?"
@patch('openlp.core.ui.confirmationform.ConfirmationForm.accept')
@patch('openlp.core.ui.confirmationform.ConfirmationForm.reject')
def test_confirmation_form_yes_button(mocked_reject, mocked_accept, settings):
"""
Test when the Yes button is clicked
"""
# GIVEN: A ConfirmationForm
form = ConfirmationForm(None, "title", ["item1", "item2", "item3"], "confirm?")
form.accept = mocked_accept
form.reject = mocked_reject
# WHEN: The Yes button is clicked
buttons = form.findChildren(QtWidgets.QPushButton)
for button in buttons:
if 'Yes' in button.text():
QtTest.QTest.mouseClick(button, QtCore.Qt.LeftButton)
break
# THEN: accept is called
assert form.accept.call_count == 1
assert form.reject.call_count == 0
@patch('openlp.core.ui.confirmationform.ConfirmationForm.accept')
@patch('openlp.core.ui.confirmationform.ConfirmationForm.reject')
def test_confirmation_form_no_button(mocked_reject, mocked_accept, settings):
"""
Test when the No button is clicked
"""
# GIVEN: A ConfirmationForm
form = ConfirmationForm(None, "title", ["item1", "item2", "item3"], "confirm?")
form.accept = mocked_accept
form.reject = mocked_reject
# WHEN: The No button is clicked
buttons = form.findChildren(QtWidgets.QPushButton)
for button in buttons:
if 'No' in button.text():
QtTest.QTest.mouseClick(button, QtCore.Qt.LeftButton)
break
# THEN: reject is called
assert form.accept.call_count == 0
assert form.reject.call_count == 1