forked from openlp/openlp
Merge fixes
This commit is contained in:
parent
11a9f58cb6
commit
e6faf233ed
@ -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
|
||||
|
@ -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 <https://bugs.launchpad.net/openlp/+bug/1209515>
|
||||
"""
|
||||
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
|
@ -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):
|
||||
|
@ -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]
|
@ -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)
|
||||
|
||||
|
@ -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__)
|
||||
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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):
|
||||
"""
|
||||
|
@ -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)
|
||||
|
@ -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])
|
||||
|
@ -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')
|
||||
|
@ -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')
|
@ -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'):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user