diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 86eac88ee..329eb0149 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -644,7 +644,6 @@ def replace_params(args, kwargs, params): from .exceptions import ValidationError -from .filedialog import FileDialog from .screen import ScreenList from .formattingtags import FormattingTags from .plugin import PluginStatus, StringContent, Plugin diff --git a/openlp/core/lib/filedialog.py b/openlp/core/lib/filedialog.py deleted file mode 100644 index 5fd8015e3..000000000 --- a/openlp/core/lib/filedialog.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2017 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; version 2 of the License. # -# # -# 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, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### -""" -Provide a work around for a bug in QFileDialog -""" -import logging -import os -from urllib import parse - -from PyQt5 import QtWidgets - -from openlp.core.common import UiStrings - -log = logging.getLogger(__name__) - - -class FileDialog(QtWidgets.QFileDialog): - """ - Subclass QFileDialog to work round a bug - """ - @staticmethod - def getOpenFileNames(parent, *args, **kwargs): - """ - Reimplement getOpenFileNames to fix the way it returns some file names that url encoded when selecting multiple - files - """ - files, filter_used = QtWidgets.QFileDialog.getOpenFileNames(parent, *args, **kwargs) - file_list = [] - for file in files: - if not os.path.exists(file): - log.info('File not found. Attempting to unquote.') - file = parse.unquote(file) - if not os.path.exists(file): - log.error('File {text} not found.'.format(text=file)) - QtWidgets.QMessageBox.information(parent, UiStrings().FileNotFound, - UiStrings().FileNotFoundMessage.format(name=file)) - continue - file_list.append(file) - return file_list diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 0adb471f4..6b04d076b 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -26,12 +26,14 @@ import logging import os import re -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt5 import QtCore, QtWidgets from openlp.core.common import Registry, RegistryProperties, Settings, UiStrings, translate -from openlp.core.lib import FileDialog, ServiceItem, StringContent, ServiceItemContext +from openlp.core.common.path import path_to_str, str_to_path +from openlp.core.lib import ServiceItem, StringContent, ServiceItemContext from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.ui import create_widget_action, critical_error_message_box +from openlp.core.ui.lib.filedialog import FileDialog from openlp.core.ui.lib.listwidgetwithdnd import ListWidgetWithDnD from openlp.core.ui.lib.toolbar import OpenLPToolbar @@ -309,13 +311,14 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): """ Add a file to the list widget to make it available for showing """ - files = FileDialog.getOpenFileNames(self, self.on_new_prompt, - Settings().value(self.settings_section + '/last directory'), - self.on_new_file_masks) - log.info('New files(s) {files}'.format(files=files)) - if files: + file_paths, selected_filter = FileDialog.getOpenFileNames( + self, self.on_new_prompt, + str_to_path(Settings().value(self.settings_section + '/last directory')), + self.on_new_file_masks) + log.info('New files(s) {file_paths}'.format(file_paths=file_paths)) + if file_paths: self.application.set_busy_cursor() - self.validate_and_load(files) + self.validate_and_load([path_to_str(path) for path in file_paths]) self.application.set_normal_cursor() def load_file(self, data): diff --git a/openlp/core/ui/lib/filedialogpatches.py b/openlp/core/ui/lib/filedialogpatches.py deleted file mode 100755 index 8b8b9a105..000000000 --- a/openlp/core/ui/lib/filedialogpatches.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2017 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; version 2 of the License. # -# # -# 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, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### -""" Patch the QFileDialog so it accepts and returns Path objects""" -from functools import wraps -from pathlib import Path - -from PyQt5 import QtWidgets - -from openlp.core.common.path import path_to_str, str_to_path -from openlp.core.lib import replace_params - - -class PQFileDialog(QtWidgets.QFileDialog): - @classmethod - @wraps(QtWidgets.QFileDialog.getExistingDirectory) - def getExistingDirectory(cls, *args, **kwargs): - """ - Reimplement `getExistingDirectory` so that it can be called with, and return Path objects - - :type parent: QtWidgets.QWidget or None - :type caption: str - :type directory: pathlib.Path - :type options: QtWidgets.QFileDialog.Options - :rtype: tuple[Path, str] - """ - - args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),)) - - return_value = super().getExistingDirectory(*args, **kwargs) - - # getExistingDirectory returns a str that represents the path. The string is empty if the user cancels the - # dialog. - return str_to_path(return_value) - - @classmethod - @wraps(QtWidgets.QFileDialog.getOpenFileName) - def getOpenFileName(cls, *args, **kwargs): - """ - Reimplement `getOpenFileName` so that it can be called with, and return Path objects - - :type parent: QtWidgets.QWidget or None - :type caption: str - :type directory: pathlib.Path - :type filter: str - :type initialFilter: str - :type options: QtWidgets.QFileDialog.Options - :rtype: tuple[Path, str] - """ - - args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),)) - - return_value = super().getOpenFileName(*args, **kwargs) - - # getOpenFileName returns a tuple. The first item is a of str's that represents the path. The string is empty if - # the user cancels the dialog. - return str_to_path(return_value[0]), return_value[1] - - @classmethod - def getOpenFileNames(cls, *args, **kwargs): - """ - Reimplement `getOpenFileNames` so that it can be called with, and return Path objects - - :type parent: QtWidgets.QWidget or None - :type caption: str - :type directory: pathlib.Path - :type filter: str - :type initialFilter: str - :type options: QtWidgets.QFileDialog.Options - :rtype: tuple[list[Path], str] - """ - args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),)) - - return_value = super().getOpenFileNames(*args, **kwargs) - - # getSaveFileName returns a tuple. The first item is a list of str's that represents the path. The list is - # empty if the user cancels the dialog. - paths = [str_to_path(path) for path in return_value[0]] - return paths, return_value[1] - - @classmethod - def getSaveFileName(cls, *args, **kwargs): - """ - Reimplement `getSaveFileName` so that it can be called with, and return Path objects - - :type parent: QtWidgets.QWidget or None - :type caption: str - :type directory: pathlib.Path - :type filter: str - :type initialFilter: str - :type options: QtWidgets.QFileDialog.Options - :rtype: tuple[Path or None, str] - """ - args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),)) - - return_value = super().getSaveFileName(*args, **kwargs) - - # getSaveFileName returns a tuple. The first item represents the path as a str. The string is empty if the user - # cancels the dialog. - return str_to_path(return_value[0]), return_value[1] diff --git a/openlp/core/ui/lib/pathedit.py b/openlp/core/ui/lib/pathedit.py index abcd56fef..dd6066931 100644 --- a/openlp/core/ui/lib/pathedit.py +++ b/openlp/core/ui/lib/pathedit.py @@ -27,7 +27,7 @@ from PyQt5 import QtCore, QtWidgets from openlp.core.common import UiStrings, translate from openlp.core.common.path import path_to_str, str_to_path from openlp.core.lib import build_icon -from openlp.core.ui.lib.filedialogpatches import PQFileDialog +from openlp.core.ui.lib.filedialog import FileDialog class PathType(Enum): @@ -40,7 +40,6 @@ class PathEdit(QtWidgets.QWidget): The :class:`~openlp.core.ui.lib.pathedit.PathEdit` class subclasses QWidget to create a custom widget for use when a file or directory needs to be selected. """ - pathChanged = QtCore.pyqtSignal(Path) def __init__(self, parent=None, path_type=PathType.Files, default_path=None, dialog_caption=None, show_revert=True): @@ -176,11 +175,11 @@ class PathEdit(QtWidgets.QWidget): if self._path_type == PathType.Directories: if not caption: caption = translate('OpenLP.PathEdit', 'Select Directory') - path = PQFileDialog.getExistingDirectory(self, caption, self._path, PQFileDialog.ShowDirsOnly) + path = FileDialog.getExistingDirectory(self, caption, self._path, FileDialog.ShowDirsOnly) elif self._path_type == PathType.Files: if not caption: caption = self.dialog_caption = translate('OpenLP.PathEdit', 'Select File') - path, filter_used = PQFileDialog.getOpenFileName(self, caption, self._path, self.filters) + path, filter_used = FileDialog.getOpenFileName(self, caption, self._path, self.filters) if path: self.on_new_path(path) diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index ed490ab62..bb471d0f1 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -35,7 +35,6 @@ from openlp.core.ui import ThemeLayoutForm from openlp.core.ui.media.webkitplayer import VIDEO_EXT from .themewizard import Ui_ThemeWizard - log = logging.getLogger(__name__) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index b1033646f..d7338db91 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -22,7 +22,6 @@ """ The Theme Manager manages adding, deleteing and modifying of themes. """ -import json import os import zipfile import shutil @@ -32,12 +31,14 @@ from PyQt5 import QtCore, QtGui, QtWidgets from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, OpenLPMixin, RegistryMixin, \ UiStrings, check_directory_exists, translate, is_win, get_filesystem_encoding, delete_file -from openlp.core.lib import FileDialog, ImageSource, ValidationError, get_text_file_string, build_icon, \ +from openlp.core.common.path import path_to_str, str_to_path +from openlp.core.lib import ImageSource, ValidationError, get_text_file_string, build_icon, \ check_item_selected, create_thumb, validate_thumb from openlp.core.lib.theme import Theme, BackgroundType from openlp.core.lib.ui import critical_error_message_box, create_widget_action from openlp.core.ui import FileRenameForm, ThemeForm from openlp.core.ui.lib import OpenLPToolbar +from openlp.core.ui.lib.filedialog import FileDialog from openlp.core.common.languagemanager import get_locale_key @@ -424,15 +425,17 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage those files. This process will only load version 2 themes. :param field: """ - files = FileDialog.getOpenFileNames(self, - translate('OpenLP.ThemeManager', 'Select Theme Import File'), - Settings().value(self.settings_section + '/last directory import'), - translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)')) - self.log_info('New Themes {name}'.format(name=str(files))) - if not files: + file_paths, selected_filter = FileDialog.getOpenFileNames( + self, + translate('OpenLP.ThemeManager', 'Select Theme Import File'), + str_to_path(Settings().value(self.settings_section + '/last directory import')), + translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)')) + self.log_info('New Themes {file_paths}'.format(file_paths=file_paths)) + if not file_paths: return self.application.set_busy_cursor() - for file_name in files: + for file_path in file_paths: + file_name = path_to_str(file_path) Settings().setValue(self.settings_section + '/last directory import', str(file_name)) self.unzip_theme(file_name, self.path) self.load_themes() diff --git a/openlp/core/ui/themewizard.py b/openlp/core/ui/themewizard.py index 3a1eba9f0..cd1748aae 100644 --- a/openlp/core/ui/themewizard.py +++ b/openlp/core/ui/themewizard.py @@ -22,6 +22,8 @@ """ The Create/Edit theme wizard """ +from pathlib import Path + from PyQt5 import QtCore, QtGui, QtWidgets from openlp.core.common import UiStrings, translate, is_macosx @@ -30,8 +32,6 @@ from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGrad from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets from openlp.core.ui.lib import ColorButton, PathEdit -from pathlib import Path - class Ui_ThemeWizard(object): """ diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 61d5b1ddd..77573c5ac 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -28,12 +28,15 @@ import logging import re import os import shutil +from pathlib import Path from PyQt5 import QtCore, QtWidgets from openlp.core.common import Registry, RegistryProperties, AppLocation, UiStrings, check_directory_exists, translate -from openlp.core.lib import FileDialog, PluginStatus, MediaType, create_separated_list +from openlp.core.common.path import path_to_str +from openlp.core.lib import PluginStatus, MediaType, create_separated_list from openlp.core.lib.ui import set_case_insensitive_completer, critical_error_message_box, find_and_set_in_combo_box +from openlp.core.ui.lib.filedialog import FileDialog from openlp.core.common.languagemanager import get_natural_key from openlp.plugins.songs.lib import VerseType, clean_song from openlp.plugins.songs.lib.db import Book, Song, Author, AuthorType, Topic, MediaFile, SongBookEntry @@ -925,9 +928,10 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties): Loads file(s) from the filesystem. """ filters = '{text} (*)'.format(text=UiStrings().AllFiles) - file_names = FileDialog.getOpenFileNames(self, translate('SongsPlugin.EditSongForm', 'Open File(s)'), '', - filters) - for filename in file_names: + file_paths, selected_filter = FileDialog.getOpenFileNames( + self, translate('SongsPlugin.EditSongForm', 'Open File(s)'), Path(), filters) + for file_path in file_paths: + filename = path_to_str(file_path) item = QtWidgets.QListWidgetItem(os.path.split(str(filename))[1]) item.setData(QtCore.Qt.UserRole, filename) self.audio_list_widget.addItem(item) diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py index 3547521c9..e3c0eb620 100644 --- a/openlp/plugins/songs/forms/songimportform.py +++ b/openlp/plugins/songs/forms/songimportform.py @@ -29,8 +29,9 @@ import os from PyQt5 import QtCore, QtWidgets from openlp.core.common import RegistryProperties, Settings, UiStrings, translate -from openlp.core.lib import FileDialog +from openlp.core.common.path import path_to_str, str_to_path from openlp.core.lib.ui import critical_error_message_box +from openlp.core.ui.lib.filedialog import FileDialog from openlp.core.ui.lib.wizard import OpenLPWizard, WizardStrings from openlp.plugins.songs.lib.importer import SongFormat, SongFormatSelect @@ -237,10 +238,11 @@ class SongImportForm(OpenLPWizard, RegistryProperties): if filters: filters += ';;' filters += '{text} (*)'.format(text=UiStrings().AllFiles) - file_names = FileDialog.getOpenFileNames( + file_paths, selected_filter = FileDialog.getOpenFileNames( self, title, - Settings().value(self.plugin.settings_section + '/last directory import'), filters) - if file_names: + str_to_path(Settings().value(self.plugin.settings_section + '/last directory import')), filters) + if file_paths: + file_names = [path_to_str(file_path) for file_path in file_paths] listbox.addItems(file_names) Settings().setValue(self.plugin.settings_section + '/last directory import', os.path.split(str(file_names[0]))[0]) diff --git a/tests/functional/openlp_core_lib/test_file_dialog.py b/tests/functional/openlp_core_lib/test_file_dialog.py index 488900fc7..13d833fcc 100644 --- a/tests/functional/openlp_core_lib/test_file_dialog.py +++ b/tests/functional/openlp_core_lib/test_file_dialog.py @@ -25,7 +25,6 @@ Package to test the openlp.core.lib.filedialog package. from unittest import TestCase from unittest.mock import MagicMock, call, patch -from openlp.core.lib.filedialog import FileDialog class TestFileDialog(TestCase): @@ -45,52 +44,3 @@ class TestFileDialog(TestCase): self.os_patcher.stop() self.qt_gui_patcher.stop() self.ui_strings_patcher.stop() - - def test_get_open_file_names_canceled(self): - """ - Test that FileDialog.getOpenFileNames() returns and empty QStringList when QFileDialog is canceled - (returns an empty QStringList) - """ - self.mocked_os.reset_mock() - - # GIVEN: An empty QStringList as a return value from QFileDialog.getOpenFileNames - self.mocked_qt_gui.QFileDialog.getOpenFileNames.return_value = ([], []) - - # WHEN: FileDialog.getOpenFileNames is called - result = FileDialog.getOpenFileNames(self.mocked_parent) - - # THEN: The returned value should be an empty QStringList and os.path.exists should not have been called - assert not self.mocked_os.path.exists.called - self.assertEqual(result, [], - 'FileDialog.getOpenFileNames should return and empty list when QFileDialog.getOpenFileNames ' - 'is canceled') - - def test_returned_file_list(self): - """ - Test that FileDialog.getOpenFileNames handles a list of files properly when QFileList.getOpenFileNames - returns a good file name, a url encoded file name and a non-existing file - """ - self.mocked_os.rest_mock() - self.mocked_qt_gui.reset_mock() - - # GIVEN: A List of known values as a return value from QFileDialog.getOpenFileNames and a list of valid file - # names. - self.mocked_qt_gui.QFileDialog.getOpenFileNames.return_value = ([ - '/Valid File', '/url%20encoded%20file%20%231', '/non-existing'], []) - self.mocked_os.path.exists.side_effect = lambda file_name: file_name in [ - '/Valid File', '/url encoded file #1'] - self.mocked_ui_strings().FileNotFound = 'File Not Found' - self.mocked_ui_strings().FileNotFoundMessage = 'File {name} not found.\nPlease try selecting it individually.' - - # WHEN: FileDialog.getOpenFileNames is called - result = FileDialog.getOpenFileNames(self.mocked_parent) - - # THEN: os.path.exists should have been called with known args. QmessageBox.information should have been - # called. The returned result should correlate with the input. - call_list = [call('/Valid File'), call('/url%20encoded%20file%20%231'), call('/url encoded file #1'), - call('/non-existing'), call('/non-existing')] - self.mocked_os.path.exists.assert_has_calls(call_list) - self.mocked_qt_gui.QMessageBox.information.assert_called_with( - self.mocked_parent, 'File Not Found', - 'File /non-existing not found.\nPlease try selecting it individually.') - self.assertEqual(result, ['/Valid File', '/url encoded file #1'], 'The returned file list is incorrect') diff --git a/tests/functional/openlp_core_ui_lib/test_filedialogpatches.py b/tests/functional/openlp_core_ui_lib/test_filedialogpatches.py deleted file mode 100755 index af5c466d2..000000000 --- a/tests/functional/openlp_core_ui_lib/test_filedialogpatches.py +++ /dev/null @@ -1,189 +0,0 @@ -import os -import sys -from unittest import TestCase -from unittest.mock import patch -from pathlib import Path - -from PyQt5 import QtWidgets - -from openlp.core.ui.lib.filedialogpatches import PQFileDialog - - -class TestFileDialogPatches(TestCase): - """ - Tests for the :mod:`openlp.core.ui.lib.filedialogpatches` module - """ - - def test_pq_file_dialog(self): - """ - Test that the :class:`PQFileDialog` instantiates correctly - """ - # GIVEN: The PQFileDialog class - # WHEN: Creating an instance - instance = PQFileDialog() - - # THEN: The instance should be an instance of QFileDialog - self.assertIsInstance(instance, QtWidgets.QFileDialog) - - def test_get_existing_directory_user_abort(self): - """ - Test that `getExistingDirectory` handles the case when the user cancels the dialog - """ - # GIVEN: PQFileDialog with a mocked QDialog.getExistingDirectory method - # WHEN: Calling PQFileDialog.getExistingDirectory and the user cancels the dialog returns a empty string - with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=''): - result = PQFileDialog.getExistingDirectory() - - # THEN: The result should be None - self.assertEqual(result, None) - - def test_get_existing_directory_user_accepts(self): - """ - Test that `getExistingDirectory` handles the case when the user accepts the dialog - """ - # GIVEN: PQFileDialog with a mocked QDialog.getExistingDirectory method - # WHEN: Calling PQFileDialog.getExistingDirectory, the user chooses a file and accepts the dialog (it returns a - # string pointing to the directory) - with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=os.path.join('test', 'dir')): - result = PQFileDialog.getExistingDirectory() - - # THEN: getExistingDirectory() should return a Path object pointing to the chosen file - self.assertEqual(result, Path('test', 'dir')) - - def test_get_existing_directory_param_order(self): - """ - Test that `getExistingDirectory` passes the parameters to `QFileDialog.getExistingDirectory` in the correct - order - """ - # GIVEN: PQFileDialog - with patch('openlp.core.ui.lib.filedialogpatches.QtWidgets.QFileDialog.getExistingDirectory', return_value='') \ - as mocked_get_existing_directory: - - # WHEN: Calling the getExistingDirectory method with all parameters set - PQFileDialog.getExistingDirectory('Parent', 'Caption', Path('test', 'dir'), 'Options') - - # THEN: The `QFileDialog.getExistingDirectory` should have been called with the parameters in the correct - # order - mocked_get_existing_directory.assert_called_once_with('Parent', 'Caption', os.path.join('test', 'dir'), - 'Options') - - def test_get_open_file_name_user_abort(self): - """ - Test that `getOpenFileName` handles the case when the user cancels the dialog - """ - # GIVEN: PQFileDialog with a mocked QDialog.getOpenFileName method - # WHEN: Calling PQFileDialog.getOpenFileName and the user cancels the dialog (it returns a tuple with the first - # value set as an empty string) - with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')): - result = PQFileDialog.getOpenFileName() - - # THEN: First value should be None - self.assertEqual(result[0], None) - - def test_get_open_file_name_user_accepts(self): - """ - Test that `getOpenFileName` handles the case when the user accepts the dialog - """ - # GIVEN: PQFileDialog with a mocked QDialog.getOpenFileName method - # WHEN: Calling PQFileDialog.getOpenFileName, the user chooses a file and accepts the dialog (it returns a - # tuple with the first value set as an string pointing to the file) - with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', - return_value=(os.path.join('test', 'chosen.file'), '')): - result = PQFileDialog.getOpenFileName() - - # THEN: getOpenFileName() should return a tuple with the first value set to a Path object pointing to the - # chosen file - self.assertEqual(result[0], Path('test', 'chosen.file')) - - def test_get_open_file_name_selected_filter(self): - """ - Test that `getOpenFileName` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileName` - """ - # GIVEN: PQFileDialog with a mocked QDialog.get_save_file_name method - # WHEN: Calling PQFileDialog.getOpenFileName, and `QFileDialog.getOpenFileName` returns a known `selectedFilter` - with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', 'selected filter')): - result = PQFileDialog.getOpenFileName() - - # THEN: getOpenFileName() should return a tuple with the second value set to a the selected filter - self.assertEqual(result[1], 'selected filter') - - def test_get_open_file_names_user_abort(self): - """ - Test that `getOpenFileNames` handles the case when the user cancels the dialog - """ - # GIVEN: PQFileDialog with a mocked QDialog.getOpenFileNames method - # WHEN: Calling PQFileDialog.getOpenFileNames and the user cancels the dialog (it returns a tuple with the first - # value set as an empty list) - with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], '')): - result = PQFileDialog.getOpenFileNames() - - # THEN: First value should be an empty list - self.assertEqual(result[0], []) - - def test_get_open_file_names_user_accepts(self): - """ - Test that `getOpenFileNames` handles the case when the user accepts the dialog - """ - # GIVEN: PQFileDialog with a mocked QDialog.getOpenFileNames method - # WHEN: Calling PQFileDialog.getOpenFileNames, the user chooses some files and accepts the dialog (it returns a - # tuple with the first value set as a list of strings pointing to the file) - with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', - return_value=([os.path.join('test', 'chosen.file1'), os.path.join('test', 'chosen.file2')], '')): - result = PQFileDialog.getOpenFileNames() - - # THEN: getOpenFileNames() should return a tuple with the first value set to a list of Path objects pointing - # to the chosen file - self.assertEqual(result[0], [Path('test', 'chosen.file1'), Path('test', 'chosen.file2')]) - - def test_get_open_file_names_selected_filter(self): - """ - Test that `getOpenFileNames` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileNames` - """ - # GIVEN: PQFileDialog with a mocked QDialog.getOpenFileNames method - # WHEN: Calling PQFileDialog.getOpenFileNames, and `QFileDialog.getOpenFileNames` returns a known - # `selectedFilter` - with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], 'selected filter')): - result = PQFileDialog.getOpenFileNames() - - # THEN: getOpenFileNames() should return a tuple with the second value set to a the selected filter - self.assertEqual(result[1], 'selected filter') - - def test_get_save_file_name_user_abort(self): - """ - Test that `getSaveFileName` handles the case when the user cancels the dialog - """ - # GIVEN: PQFileDialog with a mocked QDialog.get_save_file_name method - # WHEN: Calling PQFileDialog.getSaveFileName and the user cancels the dialog (it returns a tuple with the first - # value set as an empty string) - with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', '')): - result = PQFileDialog.getSaveFileName() - - # THEN: First value should be None - self.assertEqual(result[0], None) - - def test_get_save_file_name_user_accepts(self): - """ - Test that `getSaveFileName` handles the case when the user accepts the dialog - """ - # GIVEN: PQFileDialog with a mocked QDialog.getSaveFileName method - # WHEN: Calling PQFileDialog.getSaveFileName, the user chooses a file and accepts the dialog (it returns a - # tuple with the first value set as an string pointing to the file) - with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', - return_value=(os.path.join('test', 'chosen.file'), '')): - result = PQFileDialog.getSaveFileName() - - # THEN: getSaveFileName() should return a tuple with the first value set to a Path object pointing to the - # chosen file - self.assertEqual(result[0], Path('test', 'chosen.file')) - - def test_get_save_file_name_selected_filter(self): - """ - Test that `getSaveFileName` does not modify the selectedFilter as returned by `QFileDialog.getSaveFileName` - """ - # GIVEN: PQFileDialog with a mocked QDialog.get_save_file_name method - # WHEN: Calling PQFileDialog.getSaveFileName, and `QFileDialog.getSaveFileName` returns a known `selectedFilter` - with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', 'selected filter')): - result = PQFileDialog.getSaveFileName() - - # THEN: getSaveFileName() should return a tuple with the second value set to a the selected filter - self.assertEqual(result[1], 'selected filter') diff --git a/tests/functional/openlp_core_ui_lib/test_pathedit.py b/tests/functional/openlp_core_ui_lib/test_pathedit.py index e4ce99c41..9ef4dff4b 100755 --- a/tests/functional/openlp_core_ui_lib/test_pathedit.py +++ b/tests/functional/openlp_core_ui_lib/test_pathedit.py @@ -28,7 +28,7 @@ from unittest import TestCase from unittest.mock import MagicMock, PropertyMock, patch from openlp.core.ui.lib import PathEdit, PathType -from openlp.core.ui.lib.filedialogpatches import PQFileDialog +from openlp.core.ui.lib.filedialog import FileDialog class TestPathEdit(TestCase): @@ -126,9 +126,9 @@ class TestPathEdit(TestCase): """ # GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked # QFileDialog.getExistingDirectory - with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getExistingDirectory', return_value=None) as \ + with patch('openlp.core.ui.lib.pathedit.FileDialog.getExistingDirectory', return_value=None) as \ mocked_get_existing_directory, \ - patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName') as mocked_get_open_file_name: + patch('openlp.core.ui.lib.pathedit.FileDialog.getOpenFileName') as mocked_get_open_file_name: self.widget._path_type = PathType.Directories self.widget._path = Path('test', 'path') @@ -138,7 +138,7 @@ class TestPathEdit(TestCase): # THEN: The FileDialog.getExistingDirectory should have been called with the default caption mocked_get_existing_directory.assert_called_once_with(self.widget, 'Select Directory', Path('test', 'path'), - PQFileDialog.ShowDirsOnly) + FileDialog.ShowDirsOnly) self.assertFalse(mocked_get_open_file_name.called) def test_on_browse_button_clicked_directory_custom_caption(self): @@ -148,9 +148,9 @@ class TestPathEdit(TestCase): """ # GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked # QFileDialog.getExistingDirectory with `default_caption` set. - with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getExistingDirectory', return_value=None) as \ + with patch('openlp.core.ui.lib.pathedit.FileDialog.getExistingDirectory', return_value=None) as \ mocked_get_existing_directory, \ - patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName') as mocked_get_open_file_name: + patch('openlp.core.ui.lib.pathedit.FileDialog.getOpenFileName') as mocked_get_open_file_name: self.widget._path_type = PathType.Directories self.widget._path = Path('test', 'path') self.widget.dialog_caption = 'Directory Caption' @@ -161,7 +161,7 @@ class TestPathEdit(TestCase): # THEN: The FileDialog.getExistingDirectory should have been called with the custom caption mocked_get_existing_directory.assert_called_once_with(self.widget, 'Directory Caption', Path('test', 'path'), - PQFileDialog.ShowDirsOnly) + FileDialog.ShowDirsOnly) self.assertFalse(mocked_get_open_file_name.called) def test_on_browse_button_clicked_file(self): @@ -169,8 +169,8 @@ class TestPathEdit(TestCase): Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files. """ # GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName - with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getExistingDirectory') as mocked_get_existing_directory, \ - patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName', return_value=(None, '')) as \ + with patch('openlp.core.ui.lib.pathedit.FileDialog.getExistingDirectory') as mocked_get_existing_directory, \ + patch('openlp.core.ui.lib.pathedit.FileDialog.getOpenFileName', return_value=(None, '')) as \ mocked_get_open_file_name: self.widget._path_type = PathType.Files self.widget._path = Path('test', 'pat.h') @@ -190,8 +190,8 @@ class TestPathEdit(TestCase): """ # GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName # with `default_caption` set. - with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getExistingDirectory') as mocked_get_existing_directory, \ - patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName', return_value=(None, '')) as \ + with patch('openlp.core.ui.lib.pathedit.FileDialog.getExistingDirectory') as mocked_get_existing_directory, \ + patch('openlp.core.ui.lib.pathedit.FileDialog.getOpenFileName', return_value=(None, '')) as \ mocked_get_open_file_name: self.widget._path_type = PathType.Files self.widget._path = Path('test', 'pat.h') @@ -212,7 +212,7 @@ class TestPathEdit(TestCase): """ # GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns an empty str for the # file path. - with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName', return_value=(None, '')) as \ + with patch('openlp.core.ui.lib.pathedit.FileDialog.getOpenFileName', return_value=(None, '')) as \ mocked_get_open_file_name: # WHEN: Calling on_browse_button_clicked @@ -228,7 +228,7 @@ class TestPathEdit(TestCase): """ # GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns a str for the file # path. - with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName', + with patch('openlp.core.ui.lib.pathedit.FileDialog.getOpenFileName', return_value=(Path('test', 'pat.h'), '')) as mocked_get_open_file_name, \ patch.object(self.widget, 'on_new_path'):