forked from openlp/openlp
Add proxy settings to ftw. Option to skip sample data
bzr-revno: 2853
This commit is contained in:
commit
98f7c28d65
@ -101,7 +101,7 @@ class OpenLP(QtWidgets.QApplication):
|
||||
ftw.initialize(screens)
|
||||
if ftw.exec() == QtWidgets.QDialog.Accepted:
|
||||
Settings().setValue('core/has run wizard', True)
|
||||
elif ftw.was_cancelled:
|
||||
else:
|
||||
QtCore.QCoreApplication.exit()
|
||||
sys.exit()
|
||||
# Correct stylesheet bugs
|
||||
|
@ -158,16 +158,20 @@ def get_web_page(url, headers=None, update_openlp=False, proxy=None):
|
||||
return response.text
|
||||
|
||||
|
||||
def get_url_file_size(url):
|
||||
def get_url_file_size(url, proxy=None):
|
||||
"""
|
||||
Get the size of a file.
|
||||
|
||||
:param url: The URL of the file we want to download.
|
||||
:param dict | ProxyMode | None proxy: ProxyMode enum or a dictionary containing the proxy servers, with their types
|
||||
as the key e.g. {'http': 'http://proxyserver:port', 'https': 'https://proxyserver:port'}
|
||||
"""
|
||||
retries = 0
|
||||
if not isinstance(proxy, dict):
|
||||
proxy = get_proxy_settings(mode=proxy)
|
||||
while True:
|
||||
try:
|
||||
response = requests.head(url, timeout=float(CONNECTION_TIMEOUT), allow_redirects=True)
|
||||
response = requests.head(url, proxies=proxy, timeout=float(CONNECTION_TIMEOUT), allow_redirects=True)
|
||||
return int(response.headers['Content-Length'])
|
||||
except OSError:
|
||||
if retries > CONNECTION_RETRIES:
|
||||
@ -178,7 +182,7 @@ def get_url_file_size(url):
|
||||
continue
|
||||
|
||||
|
||||
def download_file(update_object, url, file_path, sha256=None):
|
||||
def download_file(update_object, url, file_path, sha256=None, proxy=None):
|
||||
""""
|
||||
Download a file given a URL. The file is retrieved in chunks, giving the ability to cancel the download at any
|
||||
point. Returns False on download error.
|
||||
@ -187,15 +191,19 @@ def download_file(update_object, url, file_path, sha256=None):
|
||||
:param url: URL to download
|
||||
:param file_path: Destination file
|
||||
:param sha256: The check sum value to be checked against the download value
|
||||
:param dict | ProxyMode | None proxy: ProxyMode enum or a dictionary containing the proxy servers, with their types
|
||||
as the key e.g. {'http': 'http://proxyserver:port', 'https': 'https://proxyserver:port'}
|
||||
"""
|
||||
block_count = 0
|
||||
block_size = 4096
|
||||
retries = 0
|
||||
if not isinstance(proxy, dict):
|
||||
proxy = get_proxy_settings(mode=proxy)
|
||||
log.debug('url_get_file: %s', url)
|
||||
while retries < CONNECTION_RETRIES:
|
||||
try:
|
||||
with file_path.open('wb') as saved_file:
|
||||
response = requests.get(url, timeout=float(CONNECTION_TIMEOUT), stream=True)
|
||||
response = requests.get(url, proxies=proxy, timeout=float(CONNECTION_TIMEOUT), stream=True)
|
||||
if sha256:
|
||||
hasher = hashlib.sha256()
|
||||
# Download until finished or canceled.
|
||||
@ -244,21 +252,21 @@ class DownloadWorker(ThreadWorker):
|
||||
"""
|
||||
self._base_url = base_url
|
||||
self._file_name = file_name
|
||||
self._download_cancelled = False
|
||||
self.was_cancelled = False
|
||||
super().__init__()
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Download the url to the temporary directory
|
||||
"""
|
||||
if self._download_cancelled:
|
||||
if self.was_cancelled:
|
||||
self.quit.emit()
|
||||
return
|
||||
try:
|
||||
dest_path = Path(gettempdir()) / 'openlp' / self._file_name
|
||||
url = '{url}{name}'.format(url=self._base_url, name=self._file_name)
|
||||
is_success = download_file(self, url, dest_path)
|
||||
if is_success and not self._download_cancelled:
|
||||
if is_success and not self.was_cancelled:
|
||||
self.download_succeeded.emit(dest_path)
|
||||
else:
|
||||
self.download_failed.emit()
|
||||
@ -273,4 +281,4 @@ class DownloadWorker(ThreadWorker):
|
||||
"""
|
||||
A slot to allow the download to be cancelled from outside of the thread
|
||||
"""
|
||||
self._download_cancelled = True
|
||||
self.was_cancelled = True
|
||||
|
@ -43,8 +43,8 @@ from openlp.core.lib.formattingtags import FormattingTags
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
SLIM_CHARS = 'fiíIÍjlĺľrtť.,;/ ()|"\'!:\\'
|
||||
CHORD_LINE_MATCH = re.compile(r'\[(.*?)\]([\u0080-\uFFFF,\w]*)' # noqa
|
||||
'([\u0080-\uFFFF,\w,\s,\.,\,,\!,\?,\;,\:,\|,\",\',\-,\_]*)(\Z)?')
|
||||
CHORD_LINE_MATCH = re.compile(r'\[(.*?)\]([\u0080-\uFFFF,\w]*)'
|
||||
r'([\u0080-\uFFFF,\w,\s,\.,\,,\!,\?,\;,\:,\|,\",\',\-,\_]*)(\Z)?')
|
||||
CHORD_TEMPLATE = '<span class="chordline">{chord}</span>'
|
||||
FIRST_CHORD_TEMPLATE = '<span class="chordline firstchordline">{chord}</span>'
|
||||
CHORD_LINE_TEMPLATE = '<span class="chord"><span><strong>{chord}</strong></span></span>{tail}{whitespace}{remainder}'
|
||||
|
@ -76,11 +76,11 @@ def get_thread_worker(thread_name):
|
||||
Get the worker by the thread name
|
||||
|
||||
:param str thread_name: The name of the thread
|
||||
:returns: The worker for this thread name
|
||||
:returns: The worker for this thread name, or None
|
||||
"""
|
||||
thread_info = Registry().get('application').worker_threads.get(thread_name)
|
||||
if not thread_info:
|
||||
raise KeyError('No thread named "{}" exists'.format(thread_name))
|
||||
return
|
||||
return thread_info.get('worker')
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@ from tempfile import gettempdir
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common import clean_button_text, trace_error_handler
|
||||
from openlp.core.common import trace_error_handler
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.httputils import DownloadWorker, download_file, get_url_file_size, get_web_page
|
||||
from openlp.core.common.i18n import translate
|
||||
@ -46,6 +46,7 @@ from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.threading import get_thread_worker, is_thread_finished, run_thread
|
||||
from openlp.core.ui.firsttimewizard import FirstTimePage, UiFirstTimeWizard
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.widgets import ProxyDialog
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -91,7 +92,7 @@ class ThemeListWidgetItem(QtWidgets.QListWidgetItem):
|
||||
|
||||
class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
"""
|
||||
This is the Theme Import Wizard, which allows easy creation and editing of OpenLP themes.
|
||||
This is the FirstTimeWizard, designed to help new users to get up and running quickly.
|
||||
"""
|
||||
log.info('ThemeWizardForm loaded')
|
||||
|
||||
@ -103,6 +104,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self.web_access = True
|
||||
self.web = ''
|
||||
self.setup_ui(self)
|
||||
self.customButtonClicked.connect(self._on_custom_button_clicked)
|
||||
self.themes_list_widget.itemSelectionChanged.connect(self.on_themes_list_widget_selection_changed)
|
||||
self.themes_deselect_all_button.clicked.connect(self.themes_list_widget.clearSelection)
|
||||
self.themes_select_all_button.clicked.connect(self.themes_list_widget.selectAll)
|
||||
@ -111,13 +113,13 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
"""
|
||||
Returns the id of the next FirstTimePage to go to based on enabled plugins
|
||||
"""
|
||||
if FirstTimePage.ScreenConfig < self.currentId() < FirstTimePage.Songs and self.songs_check_box.isChecked():
|
||||
if FirstTimePage.Download < self.currentId() < FirstTimePage.Songs and self.songs_check_box.isChecked():
|
||||
# If the songs plugin is enabled then go to the songs page
|
||||
return FirstTimePage.Songs
|
||||
elif FirstTimePage.ScreenConfig < self.currentId() < FirstTimePage.Bibles and self.bible_check_box.isChecked():
|
||||
elif FirstTimePage.Download < self.currentId() < FirstTimePage.Bibles and self.bible_check_box.isChecked():
|
||||
# Otherwise, if the Bibles plugin is enabled then go to the Bibles page
|
||||
return FirstTimePage.Bibles
|
||||
elif FirstTimePage.ScreenConfig < self.currentId() < FirstTimePage.Themes:
|
||||
elif FirstTimePage.Download < self.currentId() < FirstTimePage.Themes:
|
||||
# Otherwise, if the current page is somewhere between the Welcome and the Themes pages, go to the themes
|
||||
return FirstTimePage.Themes
|
||||
else:
|
||||
@ -133,9 +135,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
if not self.web_access:
|
||||
return FirstTimePage.NoInternet
|
||||
else:
|
||||
return FirstTimePage.Plugins
|
||||
elif self.currentId() == FirstTimePage.Plugins:
|
||||
return self.get_next_page_id()
|
||||
return FirstTimePage.Songs
|
||||
elif self.currentId() == FirstTimePage.Progress:
|
||||
return -1
|
||||
elif self.currentId() == FirstTimePage.NoInternet:
|
||||
@ -147,7 +147,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
Run the wizard.
|
||||
"""
|
||||
self.set_defaults()
|
||||
return QtWidgets.QWizard.exec(self)
|
||||
return super().exec()
|
||||
|
||||
def initialize(self, screens):
|
||||
"""
|
||||
@ -227,17 +227,13 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
"""
|
||||
self.restart()
|
||||
self.web = 'https://get.openlp.org/ftw/'
|
||||
self.cancel_button.clicked.connect(self.on_cancel_button_clicked)
|
||||
self.no_internet_finish_button.clicked.connect(self.on_no_internet_finish_button_clicked)
|
||||
self.no_internet_cancel_button.clicked.connect(self.on_no_internet_cancel_button_clicked)
|
||||
self.currentIdChanged.connect(self.on_current_id_changed)
|
||||
Registry().register_function('config_screen_changed', self.screen_selection_widget.load)
|
||||
self.no_internet_finish_button.setVisible(False)
|
||||
self.no_internet_cancel_button.setVisible(False)
|
||||
# Check if this is a re-run of the wizard.
|
||||
self.has_run_wizard = Settings().value('core/has run wizard')
|
||||
create_paths(Path(gettempdir(), 'openlp'))
|
||||
self.theme_combo_box.clear()
|
||||
self.button(QtWidgets.QWizard.CustomButton1).setVisible(False)
|
||||
if self.has_run_wizard:
|
||||
self.songs_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songs').is_active())
|
||||
self.bible_check_box.setChecked(self.plugin_manager.get_plugin_by_name('bibles').is_active())
|
||||
@ -260,48 +256,62 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
"""
|
||||
Detects Page changes and updates as appropriate.
|
||||
"""
|
||||
# Keep track of the page we are at. Triggering "Cancel" causes page_id to be a -1.
|
||||
back_button = self.button(QtWidgets.QWizard.BackButton)
|
||||
cancel_button = self.button(QtWidgets.QWizard.CancelButton)
|
||||
internet_settings_button = self.button(QtWidgets.QWizard.CustomButton1)
|
||||
next_button = self.button(QtWidgets.QWizard.NextButton)
|
||||
back_button.setVisible(True)
|
||||
next_button.setVisible(True)
|
||||
internet_settings_button.setVisible(False)
|
||||
self.application.process_events()
|
||||
if page_id != -1:
|
||||
self.last_id = page_id
|
||||
if page_id == FirstTimePage.Download:
|
||||
self.back_button.setVisible(False)
|
||||
self.next_button.setVisible(False)
|
||||
# Set the no internet page text.
|
||||
if self.has_run_wizard:
|
||||
self.no_internet_label.setText(self.no_internet_text)
|
||||
else:
|
||||
self.no_internet_label.setText(self.no_internet_text + self.cancel_wizard_text)
|
||||
if page_id == FirstTimePage.SampleOption:
|
||||
internet_settings_button.setVisible(True)
|
||||
elif page_id == FirstTimePage.Download:
|
||||
back_button.setVisible(False)
|
||||
next_button.setVisible(False)
|
||||
self.application.set_busy_cursor()
|
||||
self._download_index()
|
||||
self.application.set_normal_cursor()
|
||||
self.back_button.setVisible(False)
|
||||
self.next_button.setVisible(True)
|
||||
self.next()
|
||||
elif page_id == FirstTimePage.NoInternet:
|
||||
self.back_button.setVisible(False)
|
||||
self.next_button.setVisible(False)
|
||||
self.cancel_button.setVisible(False)
|
||||
self.no_internet_finish_button.setVisible(True)
|
||||
if self.has_run_wizard:
|
||||
self.no_internet_cancel_button.setVisible(False)
|
||||
else:
|
||||
self.no_internet_cancel_button.setVisible(True)
|
||||
elif page_id == FirstTimePage.Plugins:
|
||||
self.back_button.setVisible(False)
|
||||
next_button.setVisible(False)
|
||||
cancel_button.setVisible(False)
|
||||
internet_settings_button.setVisible(True)
|
||||
elif page_id == FirstTimePage.Progress:
|
||||
back_button.setVisible(False)
|
||||
next_button.setVisible(False)
|
||||
self.application.set_busy_cursor()
|
||||
self._pre_wizard()
|
||||
self._perform_wizard()
|
||||
self._post_wizard()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def on_cancel_button_clicked(self):
|
||||
def accept(self):
|
||||
"""
|
||||
Process the triggering of the cancel button.
|
||||
Called when the user clicks 'Finish'. Reimplement it to to save the plugin status
|
||||
|
||||
:rtype: None
|
||||
"""
|
||||
self._set_plugin_status(self.songs_check_box, 'songs/status')
|
||||
self._set_plugin_status(self.bible_check_box, 'bibles/status')
|
||||
self._set_plugin_status(self.presentation_check_box, 'presentations/status')
|
||||
self._set_plugin_status(self.image_check_box, 'images/status')
|
||||
self._set_plugin_status(self.media_check_box, 'media/status')
|
||||
self._set_plugin_status(self.custom_check_box, 'custom/status')
|
||||
self._set_plugin_status(self.song_usage_check_box, 'songusage/status')
|
||||
self._set_plugin_status(self.alert_check_box, 'alerts/status')
|
||||
self.screen_selection_widget.save()
|
||||
if self.theme_combo_box.currentIndex() != -1:
|
||||
Settings().setValue('themes/global theme', self.theme_combo_box.currentText())
|
||||
super().accept()
|
||||
|
||||
def reject(self):
|
||||
"""
|
||||
Called when the user clicks the cancel button. Reimplement it to clean up the threads.
|
||||
|
||||
:rtype: None
|
||||
"""
|
||||
self.was_cancelled = True
|
||||
if self.thumbnail_download_threads: # TODO: Use main thread list
|
||||
for thread_name in self.thumbnail_download_threads:
|
||||
worker = get_thread_worker(thread_name)
|
||||
if worker:
|
||||
@ -311,6 +321,27 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
while any([not is_thread_finished(thread_name) for thread_name in self.thumbnail_download_threads]):
|
||||
time.sleep(0.1)
|
||||
self.application.set_normal_cursor()
|
||||
super().reject()
|
||||
|
||||
def _on_custom_button_clicked(self, which):
|
||||
"""
|
||||
Slot to handle the a click on one of the wizards custom buttons.
|
||||
|
||||
:param int QtWidgets.QWizard which: The button pressed
|
||||
:rtype: None
|
||||
"""
|
||||
# Internet settings button
|
||||
if which == QtWidgets.QWizard.CustomButton1:
|
||||
proxy_dialog = ProxyDialog(self)
|
||||
proxy_dialog.retranslate_ui()
|
||||
proxy_dialog.exec()
|
||||
|
||||
def on_projectors_check_box_clicked(self):
|
||||
# When clicking projectors_check box, change the visibility setting for Projectors panel.
|
||||
if Settings().value('projector/show after wizard'):
|
||||
Settings().setValue('projector/show after wizard', False)
|
||||
else:
|
||||
Settings().setValue('projector/show after wizard', True)
|
||||
|
||||
def on_themes_list_widget_selection_changed(self):
|
||||
"""
|
||||
@ -330,23 +361,6 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
elif not item.isSelected() and cbox_index != -1:
|
||||
self.theme_combo_box.removeItem(cbox_index)
|
||||
|
||||
def on_no_internet_finish_button_clicked(self):
|
||||
"""
|
||||
Process the triggering of the "Finish" button on the No Internet page.
|
||||
"""
|
||||
self.application.set_busy_cursor()
|
||||
self._perform_wizard()
|
||||
self.application.set_normal_cursor()
|
||||
Settings().setValue('core/has run wizard', True)
|
||||
self.close()
|
||||
|
||||
def on_no_internet_cancel_button_clicked(self):
|
||||
"""
|
||||
Process the triggering of the "Cancel" button on the No Internet page.
|
||||
"""
|
||||
self.was_cancelled = True
|
||||
self.close()
|
||||
|
||||
def update_progress(self, count, block_size):
|
||||
"""
|
||||
Calculate and display the download progress. This method is called by download_file().
|
||||
@ -373,7 +387,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
Prepare the UI for the process.
|
||||
"""
|
||||
self.max_progress = 0
|
||||
self.finish_button.setVisible(False)
|
||||
self.button(QtWidgets.QWizard.FinishButton).setEnabled(False)
|
||||
self.application.process_events()
|
||||
try:
|
||||
# Loop through the songs list and increase for each selected item
|
||||
@ -432,54 +446,31 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self.progress_bar.setValue(self.progress_bar.maximum())
|
||||
if self.has_run_wizard:
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the {button} button to return to OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText(text)
|
||||
'Download complete. Click the \'{finish_button}\' button to return to OpenLP.')
|
||||
else:
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the {button} button to start OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText(text)
|
||||
'Download complete. Click the \'{finish_button}\' button to start OpenLP.')
|
||||
else:
|
||||
if self.has_run_wizard:
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Click the {button} button to return to OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText(text)
|
||||
text = translate('OpenLP.FirstTimeWizard', 'Click the \'{finish_button}\' button to return to OpenLP.')
|
||||
else:
|
||||
text = translate('OpenLP.FirstTimeWizard',
|
||||
'Click the {button} button to start OpenLP.'
|
||||
).format(button=clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
self.progress_label.setText(text)
|
||||
self.finish_button.setVisible(True)
|
||||
self.finish_button.setEnabled(True)
|
||||
self.cancel_button.setVisible(False)
|
||||
self.next_button.setVisible(False)
|
||||
text = translate('OpenLP.FirstTimeWizard', 'Click the \'{finish_button}\' button to start OpenLP.')
|
||||
self.progress_label.setText(text.format(finish_button=self.finish_button_text))
|
||||
self.button(QtWidgets.QWizard.FinishButton).setEnabled(True)
|
||||
self.button(QtWidgets.QWizard.CancelButton).setVisible(False)
|
||||
self.application.process_events()
|
||||
|
||||
def _perform_wizard(self):
|
||||
"""
|
||||
Run the tasks in the wizard.
|
||||
"""
|
||||
# Set plugin states
|
||||
self._increment_progress_bar(translate('OpenLP.FirstTimeWizard', 'Enabling selected plugins...'))
|
||||
self._set_plugin_status(self.songs_check_box, 'songs/status')
|
||||
self._set_plugin_status(self.bible_check_box, 'bibles/status')
|
||||
self._set_plugin_status(self.presentation_check_box, 'presentations/status')
|
||||
self._set_plugin_status(self.image_check_box, 'images/status')
|
||||
self._set_plugin_status(self.media_check_box, 'media/status')
|
||||
self._set_plugin_status(self.custom_check_box, 'custom/status')
|
||||
self._set_plugin_status(self.song_usage_check_box, 'songusage/status')
|
||||
self._set_plugin_status(self.alert_check_box, 'alerts/status')
|
||||
|
||||
if self.web_access:
|
||||
if not self._download_selected():
|
||||
critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'),
|
||||
translate('OpenLP.FirstTimeWizard', 'There was a connection problem while '
|
||||
'downloading, so further downloads will be skipped. Try to re-run '
|
||||
'the First Time Wizard later.'))
|
||||
self.screen_selection_widget.save()
|
||||
if self.theme_combo_box.currentIndex() != -1:
|
||||
Settings().setValue('themes/global theme', self.theme_combo_box.currentText())
|
||||
|
||||
def _download_selected(self):
|
||||
"""
|
||||
|
@ -26,7 +26,6 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import clean_button_text, is_macosx
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib.ui import add_welcome_page
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
@ -39,14 +38,15 @@ class FirstTimePage(object):
|
||||
An enumeration class with each of the pages of the wizard.
|
||||
"""
|
||||
Welcome = 0
|
||||
ScreenConfig = 1
|
||||
Download = 2
|
||||
NoInternet = 3
|
||||
Plugins = 4
|
||||
Songs = 5
|
||||
Bibles = 6
|
||||
Themes = 7
|
||||
Progress = 8
|
||||
Plugins = 1
|
||||
ScreenConfig = 2
|
||||
SampleOption = 3
|
||||
Download = 4
|
||||
NoInternet = 5
|
||||
Songs = 6
|
||||
Bibles = 7
|
||||
Themes = 8
|
||||
Progress = 9
|
||||
|
||||
|
||||
class ThemeListWidget(QtWidgets.QListWidget):
|
||||
@ -97,20 +97,13 @@ class UiFirstTimeWizard(object):
|
||||
first_time_wizard.resize(550, 386)
|
||||
first_time_wizard.setModal(True)
|
||||
first_time_wizard.setOptions(QtWidgets.QWizard.IndependentPages | QtWidgets.QWizard.NoBackButtonOnStartPage |
|
||||
QtWidgets.QWizard.NoBackButtonOnLastPage | QtWidgets.QWizard.HaveCustomButton1 |
|
||||
QtWidgets.QWizard.HaveCustomButton2)
|
||||
QtWidgets.QWizard.NoBackButtonOnLastPage | QtWidgets.QWizard.HaveCustomButton1)
|
||||
if is_macosx(): # pragma: nocover
|
||||
first_time_wizard.setPixmap(QtWidgets.QWizard.BackgroundPixmap,
|
||||
QtGui.QPixmap(':/wizards/openlp-osx-wizard.png'))
|
||||
first_time_wizard.resize(634, 386)
|
||||
else:
|
||||
first_time_wizard.setWizardStyle(QtWidgets.QWizard.ModernStyle)
|
||||
self.finish_button = self.button(QtWidgets.QWizard.FinishButton)
|
||||
self.no_internet_finish_button = self.button(QtWidgets.QWizard.CustomButton1)
|
||||
self.cancel_button = self.button(QtWidgets.QWizard.CancelButton)
|
||||
self.no_internet_cancel_button = self.button(QtWidgets.QWizard.CustomButton2)
|
||||
self.next_button = self.button(QtWidgets.QWizard.NextButton)
|
||||
self.back_button = self.button(QtWidgets.QWizard.BackButton)
|
||||
add_welcome_page(first_time_wizard, ':/wizards/wizard_firsttime.bmp')
|
||||
# The screen config page
|
||||
self.screen_page = QtWidgets.QWizardPage()
|
||||
@ -121,6 +114,18 @@ class UiFirstTimeWizard(object):
|
||||
self.screen_selection_widget.load()
|
||||
self.screen_page_layout.addRow(self.screen_selection_widget)
|
||||
first_time_wizard.setPage(FirstTimePage.ScreenConfig, self.screen_page)
|
||||
# Download Samples page
|
||||
self.resource_page = QtWidgets.QWizardPage()
|
||||
self.resource_page.setObjectName('resource_page')
|
||||
self.resource_page.setFinalPage(True)
|
||||
self.resource_layout = QtWidgets.QVBoxLayout(self.resource_page)
|
||||
self.resource_layout.setContentsMargins(50, 20, 50, 20)
|
||||
self.resource_layout.setObjectName('resource_layout')
|
||||
self.resource_label = QtWidgets.QLabel(self.resource_page)
|
||||
self.resource_label.setObjectName('resource_label')
|
||||
self.resource_label.setWordWrap(True)
|
||||
self.resource_layout.addWidget(self.resource_label)
|
||||
first_time_wizard.setPage(FirstTimePage.SampleOption, self.resource_page)
|
||||
# The download page
|
||||
self.download_page = QtWidgets.QWizardPage()
|
||||
self.download_page.setObjectName('download_page')
|
||||
@ -134,6 +139,7 @@ class UiFirstTimeWizard(object):
|
||||
# The "you don't have an internet connection" page.
|
||||
self.no_internet_page = QtWidgets.QWizardPage()
|
||||
self.no_internet_page.setObjectName('no_internet_page')
|
||||
self.no_internet_page.setFinalPage(True)
|
||||
self.no_internet_layout = QtWidgets.QVBoxLayout(self.no_internet_page)
|
||||
self.no_internet_layout.setContentsMargins(50, 30, 50, 40)
|
||||
self.no_internet_layout.setObjectName('no_internet_layout')
|
||||
@ -242,27 +248,32 @@ class UiFirstTimeWizard(object):
|
||||
self.progress_bar.setObjectName('progress_bar')
|
||||
self.progress_layout.addWidget(self.progress_bar)
|
||||
first_time_wizard.setPage(FirstTimePage.Progress, self.progress_page)
|
||||
self.retranslate_ui(first_time_wizard)
|
||||
self.retranslate_ui()
|
||||
|
||||
def retranslate_ui(self, first_time_wizard):
|
||||
def retranslate_ui(self):
|
||||
"""
|
||||
Translate the UI on the fly
|
||||
|
||||
:param first_time_wizard: The wizard form
|
||||
"""
|
||||
first_time_wizard.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'First Time Wizard'))
|
||||
self.finish_button_text = clean_button_text(self.buttonText(QtWidgets.QWizard.FinishButton))
|
||||
back_button_text = clean_button_text(self.buttonText(QtWidgets.QWizard.BackButton))
|
||||
next_button_text = clean_button_text(self.buttonText(QtWidgets.QWizard.NextButton))
|
||||
|
||||
self.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'First Time Wizard'))
|
||||
text = translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard')
|
||||
first_time_wizard.title_label.setText('<span style="font-size:14pt; font-weight:600;">{text}'
|
||||
'</span>'.format(text=text))
|
||||
button = clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.NextButton))
|
||||
first_time_wizard.information_label.setText(
|
||||
self.title_label.setText('<span style="font-size:14pt; font-weight:600;">{text}</span>'.format(text=text))
|
||||
self.information_label.setText(
|
||||
translate('OpenLP.FirstTimeWizard', 'This wizard will help you to configure OpenLP for initial use. '
|
||||
'Click the {button} button below to start.').format(button=button))
|
||||
'Click the \'{next_button}\' button below to start.'
|
||||
).format(next_button=next_button_text))
|
||||
self.setButtonText(
|
||||
QtWidgets.QWizard.CustomButton1, translate('OpenLP.FirstTimeWizard', 'Internet Settings'))
|
||||
self.download_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Downloading Resource Index'))
|
||||
self.download_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Please wait while the resource index is '
|
||||
'downloaded.'))
|
||||
self.download_label.setText(translate('OpenLP.FirstTimeWizard', 'Please wait while OpenLP downloads the '
|
||||
'resource index file...'))
|
||||
self.download_page.setSubTitle(translate('OpenLP.FirstTimeWizard',
|
||||
'Please wait while the resource index is downloaded.'))
|
||||
self.download_label.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Please wait while OpenLP downloads the resource index file...'))
|
||||
self.plugin_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Select parts of the program you wish to use'))
|
||||
self.plugin_page.setSubTitle(translate('OpenLP.FirstTimeWizard',
|
||||
'You can also change these settings after the Wizard.'))
|
||||
@ -270,11 +281,10 @@ class UiFirstTimeWizard(object):
|
||||
self.screen_page.setSubTitle(translate('OpenLP.FirstTimeWizard',
|
||||
'Choose the main display screen for OpenLP.'))
|
||||
self.songs_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Songs'))
|
||||
self.custom_check_box.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Custom Slides – Easier to manage than songs and they have their own'
|
||||
' list of slides'))
|
||||
self.bible_check_box.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Bibles – Import and show Bibles'))
|
||||
self.custom_check_box.setText(
|
||||
translate('OpenLP.FirstTimeWizard',
|
||||
'Custom Slides – Easier to manage than songs and they have their own list of slides'))
|
||||
self.bible_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Bibles – Import and show Bibles'))
|
||||
self.image_check_box.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Images – Show images or replace background with them'))
|
||||
self.presentation_check_box.setText(translate('OpenLP.FirstTimeWizard',
|
||||
@ -283,22 +293,25 @@ class UiFirstTimeWizard(object):
|
||||
self.song_usage_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Song Usage Monitor'))
|
||||
self.alert_check_box.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Alerts – Display informative messages while showing other slides'))
|
||||
self.resource_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Resource Data'))
|
||||
self.resource_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Can OpenLP download some resource data?'))
|
||||
self.resource_label.setText(
|
||||
translate('OpenLP.FirstTimeWizard',
|
||||
'OpenLP has collected some resources that we have permission to distribute.\n\n'
|
||||
'If you would like to download some of these resources click the \'{next_button}\' button, '
|
||||
'otherwise click the \'{finish_button}\' button.'
|
||||
).format(next_button=next_button_text, finish_button=self.finish_button_text))
|
||||
self.no_internet_page.setTitle(translate('OpenLP.FirstTimeWizard', 'No Internet Connection'))
|
||||
self.no_internet_page.setSubTitle(
|
||||
translate('OpenLP.FirstTimeWizard', 'Unable to detect an Internet connection.'))
|
||||
button = clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.FinishButton))
|
||||
self.no_internet_text = translate('OpenLP.FirstTimeWizard',
|
||||
'No Internet connection was found. The First Time Wizard needs an Internet '
|
||||
'connection in order to be able to download sample songs, Bibles and themes.'
|
||||
' Click the {button} button now to start OpenLP with initial settings and '
|
||||
'no sample data.\n\nTo re-run the First Time Wizard and import this sample '
|
||||
'data at a later time, check your Internet connection and re-run this '
|
||||
'wizard by selecting "Tools/Re-run First Time Wizard" from OpenLP.'
|
||||
).format(button=button)
|
||||
button = clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.CancelButton))
|
||||
self.cancel_wizard_text = translate('OpenLP.FirstTimeWizard',
|
||||
'\n\nTo cancel the First Time Wizard completely (and not start OpenLP), '
|
||||
'click the {button} button now.').format(button=button)
|
||||
self.no_internet_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Cannot connect to the internet.'))
|
||||
self.no_internet_label.setText(
|
||||
translate('OpenLP.FirstTimeWizard',
|
||||
'OpenLP could not connect to the internet to get information about the sample data available.\n\n'
|
||||
'Please check your internet connection. If your church uses a proxy server click the '
|
||||
'\'Internet Settings\' button below and enter the server details there.\n\nClick the '
|
||||
'\'{back_button}\' button to try again.\n\nIf you click the \'{finish_button}\' '
|
||||
'button you can download the data at a later time by selecting \'Re-run First Time Wizard\' '
|
||||
'from the \'Tools\' menu in OpenLP.'
|
||||
).format(back_button=back_button_text, finish_button=self.finish_button_text))
|
||||
self.songs_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Songs'))
|
||||
self.songs_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download public domain songs.'))
|
||||
self.bibles_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Bibles'))
|
||||
@ -310,17 +323,5 @@ class UiFirstTimeWizard(object):
|
||||
self.themes_select_all_button.setToolTip(translate('OpenLP.FirstTimeWizard', 'Select all'))
|
||||
self.themes_deselect_all_button.setToolTip(translate('OpenLP.FirstTimeWizard', 'Deselect all'))
|
||||
self.progress_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Downloading and Configuring'))
|
||||
self.progress_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Please wait while resources are downloaded '
|
||||
'and OpenLP is configured.'))
|
||||
self.progress_label.setText(translate('OpenLP.FirstTimeWizard', 'Starting configuration process...'))
|
||||
first_time_wizard.setButtonText(QtWidgets.QWizard.CustomButton1,
|
||||
clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.FinishButton)))
|
||||
first_time_wizard.setButtonText(QtWidgets.QWizard.CustomButton2,
|
||||
clean_button_text(first_time_wizard.buttonText(QtWidgets.QWizard.CancelButton)))
|
||||
|
||||
def on_projectors_check_box_clicked(self):
|
||||
# When clicking projectors_check box, change the visibility setting for Projectors panel.
|
||||
if Settings().value('projector/show after wizard'):
|
||||
Settings().setValue('projector/show after wizard', False)
|
||||
else:
|
||||
Settings().setValue('projector/show after wizard', True)
|
||||
self.progress_page.setSubTitle(
|
||||
translate('OpenLP.FirstTimeWizard', 'Please wait while resources are downloaded and OpenLP is configured.'))
|
||||
|
@ -681,8 +681,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
||||
return
|
||||
first_run_wizard = FirstTimeForm(self)
|
||||
first_run_wizard.initialize(ScreenList())
|
||||
first_run_wizard.exec()
|
||||
if first_run_wizard.was_cancelled:
|
||||
if first_run_wizard.exec() == QtWidgets.QDialog.Rejected:
|
||||
return
|
||||
self.application.set_busy_cursor()
|
||||
self.first_time()
|
||||
|
@ -150,6 +150,34 @@ class ProxyWidget(QtWidgets.QGroupBox):
|
||||
settings.setValue('advanced/proxy password', self.password_edit.text())
|
||||
|
||||
|
||||
class ProxyDialog(QtWidgets.QDialog):
|
||||
"""
|
||||
A basic dialog to show proxy settingd
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.layout = QtWidgets.QVBoxLayout(self)
|
||||
self.proxy_widget = ProxyWidget(self)
|
||||
self.layout.addWidget(self.proxy_widget)
|
||||
self.button_box = \
|
||||
QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel, self)
|
||||
self.layout.addWidget(self.button_box)
|
||||
self.button_box.accepted.connect(self.accept)
|
||||
self.button_box.rejected.connect(self.reject)
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
Reimplement the the accept slot so that the ProxyWidget settings can be saved.
|
||||
:rtype: None
|
||||
"""
|
||||
self.proxy_widget.save()
|
||||
super().accept()
|
||||
|
||||
def retranslate_ui(self):
|
||||
self.proxy_widget.retranslate_ui()
|
||||
self.setWindowTitle(translate('OpenLP.ProxyDialog', 'Proxy Server Settings'))
|
||||
|
||||
|
||||
class ScreenButton(QtWidgets.QPushButton):
|
||||
"""
|
||||
A special button class that holds the screen information about it
|
||||
|
@ -106,7 +106,7 @@ class OpenLPSongImport(SongImport):
|
||||
pass
|
||||
|
||||
# Check the file type
|
||||
if not isinstance(self.import_source, str) or not self.import_source.endswith('.sqlite'):
|
||||
if self.import_source.suffix != '.sqlite':
|
||||
self.log_error(self.import_source, translate('SongsPlugin.OpenLPSongImport',
|
||||
'Not a valid OpenLP 2 song database.'))
|
||||
return
|
||||
|
@ -49,13 +49,6 @@ def report_song_list():
|
||||
Path(translate('SongPlugin.ReportSongList', 'song_extract.csv')),
|
||||
translate('SongPlugin.ReportSongList', 'CSV format (*.csv)'))
|
||||
|
||||
if report_file_path is None:
|
||||
main_window.error_message(
|
||||
translate('SongPlugin.ReportSongList', 'Output Path Not Selected'),
|
||||
translate('SongPlugin.ReportSongList', 'You have not set a valid output location for your report. \n'
|
||||
'Please select an existing path on your computer.')
|
||||
)
|
||||
return
|
||||
report_file_path.with_suffix('.csv')
|
||||
Registry().get('application').set_busy_cursor()
|
||||
try:
|
||||
|
0
run_openlp.py
Executable file → Normal file
0
run_openlp.py
Executable file → Normal file
@ -224,7 +224,7 @@ class TestHttpUtils(TestCase, TestMixin):
|
||||
file_size = get_url_file_size(fake_url)
|
||||
|
||||
# THEN: The correct methods are called with the correct arguments and a web page is returned
|
||||
mocked_requests.head.assert_called_once_with(fake_url, allow_redirects=True, timeout=30.0)
|
||||
mocked_requests.head.assert_called_once_with(fake_url, allow_redirects=True, proxies=None, timeout=30.0)
|
||||
assert file_size == 100
|
||||
|
||||
@patch('openlp.core.common.httputils.requests')
|
||||
@ -249,34 +249,30 @@ class TestGetProxySettings(TestCase, TestMixin):
|
||||
self.addCleanup(self.destroy_settings)
|
||||
|
||||
@patch('openlp.core.common.httputils.Settings')
|
||||
def test_mode_arg_specified(self, MockSettings):
|
||||
def test_mode_arg_specified(self, mocked_settings):
|
||||
"""
|
||||
Test that the argument is used rather than reading the 'advanced/proxy mode' setting
|
||||
"""
|
||||
# GIVEN: Mocked settings
|
||||
mocked_settings = MagicMock()
|
||||
MockSettings.return_value = mocked_settings
|
||||
|
||||
# WHEN: Calling `get_proxy_settings` with the mode arg specified
|
||||
get_proxy_settings(mode=ProxyMode.NO_PROXY)
|
||||
|
||||
# THEN: The mode arg should have been used rather than looking it up in the settings
|
||||
mocked_settings.value.assert_not_called()
|
||||
mocked_settings().value.assert_not_called()
|
||||
|
||||
@patch('openlp.core.common.httputils.Settings')
|
||||
def test_mode_incorrect_arg_specified(self, MockSettings):
|
||||
def test_mode_incorrect_arg_specified(self, mocked_settings):
|
||||
"""
|
||||
Test that the system settings are used when the mode arg specieied is invalid
|
||||
"""
|
||||
# GIVEN: Mocked settings
|
||||
mocked_settings = MagicMock()
|
||||
MockSettings.return_value = mocked_settings
|
||||
|
||||
# WHEN: Calling `get_proxy_settings` with an invalid mode arg specified
|
||||
result = get_proxy_settings(mode='qwerty')
|
||||
|
||||
# THEN: An None should be returned
|
||||
mocked_settings.value.assert_not_called()
|
||||
mocked_settings().value.assert_not_called()
|
||||
assert result is None
|
||||
|
||||
def test_no_proxy_mode(self):
|
||||
|
@ -133,15 +133,11 @@ def test_get_thread_worker_mising(MockRegistry):
|
||||
# GIVEN: A mocked thread worker
|
||||
MockRegistry.return_value.get.return_value.worker_threads = {}
|
||||
|
||||
try:
|
||||
# WHEN: get_thread_worker() is called
|
||||
get_thread_worker('test_thread')
|
||||
assert False, 'A KeyError should have been raised'
|
||||
except KeyError:
|
||||
# THEN: The mocked worker is returned
|
||||
pass
|
||||
except Exception:
|
||||
assert False, 'A KeyError should have been raised'
|
||||
result = get_thread_worker('test_thread')
|
||||
|
||||
# THEN: None should have been returned
|
||||
assert result is None
|
||||
|
||||
|
||||
@patch('openlp.core.threading.Registry')
|
||||
|
@ -27,6 +27,8 @@ import tempfile
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call, patch, DEFAULT
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.path import Path
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.ui.firsttimeform import FirstTimeForm, ThemeListWidgetItem
|
||||
@ -45,6 +47,7 @@ class TestThemeListWidgetItem(TestCase):
|
||||
"""
|
||||
Test the :class:`ThemeListWidgetItem` class
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.sample_theme_data = {'file_name': 'BlueBurst.otz', 'sha256': 'sha_256_hash',
|
||||
'thumbnail': 'BlueBurst.png', 'title': 'Blue Burst'}
|
||||
@ -59,7 +62,7 @@ class TestThemeListWidgetItem(TestCase):
|
||||
"""
|
||||
Test that the theme data is loaded correctly in to a ThemeListWidgetItem object when instantiated
|
||||
"""
|
||||
# GIVEN: A sample theme dictanary object
|
||||
# GIVEN: A sample theme dictionary object
|
||||
# WHEN: Creating an instance of `ThemeListWidgetItem`
|
||||
instance = ThemeListWidgetItem('url', self.sample_theme_data, MagicMock())
|
||||
|
||||
@ -74,7 +77,7 @@ class TestThemeListWidgetItem(TestCase):
|
||||
"""
|
||||
Test that the `DownloadWorker` worker is set up correctly and that the thread is started.
|
||||
"""
|
||||
# GIVEN: A sample theme dictanary object
|
||||
# GIVEN: A sample theme dictionary object
|
||||
mocked_ftw = MagicMock(spec=FirstTimeForm)
|
||||
mocked_ftw.thumbnail_download_threads = []
|
||||
|
||||
@ -120,10 +123,23 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
# THEN: The screens should be set up, and the default values initialised
|
||||
assert expected_screens == frw.screens, 'The screens should be correct'
|
||||
assert frw.web_access is True, 'The default value of self.web_access should be True'
|
||||
assert frw.was_cancelled is False, 'The default value of self.was_cancelled should be False'
|
||||
assert [] == frw.thumbnail_download_threads, 'The list of threads should be empty'
|
||||
assert frw.has_run_wizard is False, 'has_run_wizard should be False'
|
||||
|
||||
@patch('openlp.core.ui.firsttimeform.QtWidgets.QWizard.exec')
|
||||
def test_exec(self, mocked_qwizard_exec):
|
||||
|
||||
# GIVEN: An instance of FirstTimeForm
|
||||
frw = FirstTimeForm(None)
|
||||
with patch.object(frw, 'set_defaults') as mocked_set_defaults:
|
||||
|
||||
# WHEN: exec is called
|
||||
frw.exec()
|
||||
|
||||
# THEN: The wizard should be reset and the exec methon on the super class should have been called
|
||||
mocked_set_defaults.assert_called_once()
|
||||
mocked_qwizard_exec.assert_called_once()
|
||||
|
||||
def test_set_defaults(self):
|
||||
"""
|
||||
Test that the default values are set when set_defaults() is run
|
||||
@ -134,8 +150,6 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.side_effect = lambda key: {'core/has run wizard': False}[key]
|
||||
with patch.object(frw, 'restart') as mocked_restart, \
|
||||
patch.object(frw, 'cancel_button') as mocked_cancel_button, \
|
||||
patch.object(frw, 'no_internet_finish_button') as mocked_no_internet_finish_btn, \
|
||||
patch.object(frw, 'currentIdChanged') as mocked_currentIdChanged, \
|
||||
patch.object(frw, 'theme_combo_box') as mocked_theme_combo_box, \
|
||||
patch.object(frw, 'songs_check_box') as mocked_songs_check_box, \
|
||||
@ -153,12 +167,8 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
# THEN: The default values should have been set
|
||||
mocked_restart.assert_called_once()
|
||||
assert 'https://get.openlp.org/ftw/' == frw.web, 'The default URL should be set'
|
||||
mocked_cancel_button.clicked.connect.assert_called_once_with(frw.on_cancel_button_clicked)
|
||||
mocked_no_internet_finish_btn.clicked.connect.assert_called_once_with(
|
||||
frw.on_no_internet_finish_button_clicked)
|
||||
mocked_currentIdChanged.connect.assert_called_once_with(frw.on_current_id_changed)
|
||||
mocked_register_function.assert_called_once_with('config_screen_changed', frw.screen_selection_widget.load)
|
||||
mocked_no_internet_finish_btn.setVisible.assert_called_once_with(False)
|
||||
mocked_settings.value.assert_has_calls([call('core/has run wizard')])
|
||||
mocked_gettempdir.assert_called_once()
|
||||
mocked_create_paths.assert_called_once_with(Path('temp', 'openlp'))
|
||||
@ -177,8 +187,6 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
mocked_settings.value.side_effect = \
|
||||
lambda key: {'core/has run wizard': True, 'themes/global theme': 'Default Theme'}[key]
|
||||
with patch.object(frw, 'restart') as mocked_restart, \
|
||||
patch.object(frw, 'cancel_button') as mocked_cancel_button, \
|
||||
patch.object(frw, 'no_internet_finish_button') as mocked_no_internet_finish_btn, \
|
||||
patch.object(frw, 'currentIdChanged') as mocked_currentIdChanged, \
|
||||
patch.object(frw, 'theme_combo_box', **{'findText.return_value': 3}) as mocked_theme_combo_box, \
|
||||
patch.multiple(frw, songs_check_box=DEFAULT, bible_check_box=DEFAULT, presentation_check_box=DEFAULT,
|
||||
@ -200,12 +208,8 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
# THEN: The default values should have been set
|
||||
mocked_restart.assert_called_once()
|
||||
assert 'https://get.openlp.org/ftw/' == frw.web, 'The default URL should be set'
|
||||
mocked_cancel_button.clicked.connect.assert_called_once_with(frw.on_cancel_button_clicked)
|
||||
mocked_no_internet_finish_btn.clicked.connect.assert_called_once_with(
|
||||
frw.on_no_internet_finish_button_clicked)
|
||||
mocked_currentIdChanged.connect.assert_called_once_with(frw.on_current_id_changed)
|
||||
mocked_register_function.assert_called_once_with('config_screen_changed', frw.screen_selection_widget.load)
|
||||
mocked_no_internet_finish_btn.setVisible.assert_called_once_with(False)
|
||||
mocked_settings.value.assert_has_calls([call('core/has run wizard'), call('themes/global theme')])
|
||||
mocked_gettempdir.assert_called_once()
|
||||
mocked_create_paths.assert_called_once_with(Path('temp', 'openlp'))
|
||||
@ -219,12 +223,78 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
mocked_theme_combo_box.findText.assert_called_once_with('Default Theme')
|
||||
mocked_theme_combo_box.setCurrentIndex(3)
|
||||
|
||||
@patch('openlp.core.ui.firsttimeform.Settings')
|
||||
@patch('openlp.core.ui.firsttimeform.QtWidgets.QWizard.accept')
|
||||
def test_accept_method(self, mocked_qwizard_accept, *args):
|
||||
"""
|
||||
Test the FirstTimeForm.accept method
|
||||
"""
|
||||
# GIVEN: An instance of FirstTimeForm
|
||||
frw = FirstTimeForm(None)
|
||||
with patch.object(frw, '_set_plugin_status') as mocked_set_plugin_status, \
|
||||
patch.multiple(frw, songs_check_box=DEFAULT, bible_check_box=DEFAULT, presentation_check_box=DEFAULT,
|
||||
image_check_box=DEFAULT, media_check_box=DEFAULT, custom_check_box=DEFAULT,
|
||||
song_usage_check_box=DEFAULT, alert_check_box=DEFAULT) as mocked_check_boxes, \
|
||||
patch.object(frw, 'screen_selection_widget') as mocked_screen_selection_widget:
|
||||
|
||||
# WHEN: Calling accept
|
||||
frw.accept()
|
||||
|
||||
# THEN: The selected plugins should be enabled, the screen selection saved and the super method called
|
||||
mocked_set_plugin_status.assert_has_calls([
|
||||
call(mocked_check_boxes['songs_check_box'], 'songs/status'),
|
||||
call(mocked_check_boxes['bible_check_box'], 'bibles/status'),
|
||||
call(mocked_check_boxes['presentation_check_box'], 'presentations/status'),
|
||||
call(mocked_check_boxes['image_check_box'], 'images/status'),
|
||||
call(mocked_check_boxes['media_check_box'], 'media/status'),
|
||||
call(mocked_check_boxes['custom_check_box'], 'custom/status'),
|
||||
call(mocked_check_boxes['song_usage_check_box'], 'songusage/status'),
|
||||
call(mocked_check_boxes['alert_check_box'], 'alerts/status')])
|
||||
mocked_screen_selection_widget.save.assert_called_once()
|
||||
mocked_qwizard_accept.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.firsttimeform.Settings')
|
||||
def test_accept_method_theme_not_selected(self, mocked_settings):
|
||||
"""
|
||||
Test the FirstTimeForm.accept method when there is no default theme selected
|
||||
"""
|
||||
# GIVEN: An instance of FirstTimeForm
|
||||
frw = FirstTimeForm(None)
|
||||
with patch.object(frw, '_set_plugin_status'), patch.object(frw, 'screen_selection_widget'), \
|
||||
patch.object(frw, 'theme_combo_box', **{'currentIndex.return_value': -1}):
|
||||
|
||||
# WHEN: Calling accept and the currentIndex method of the theme_combo_box returns -1
|
||||
frw.accept()
|
||||
|
||||
# THEN: OpenLP should not try to save a theme name
|
||||
mocked_settings().setValue.assert_not_called()
|
||||
|
||||
@patch('openlp.core.ui.firsttimeform.Settings')
|
||||
def test_accept_method_theme_selected(self, mocked_settings):
|
||||
"""
|
||||
Test the FirstTimeForm.accept method when a default theme is selected
|
||||
"""
|
||||
# GIVEN: An instance of FirstTimeForm
|
||||
frw = FirstTimeForm(None)
|
||||
with patch.object(frw, '_set_plugin_status'), \
|
||||
patch.object(frw, 'screen_selection_widget'), \
|
||||
patch.object(
|
||||
frw, 'theme_combo_box', **{'currentIndex.return_value': 0, 'currentText.return_value': 'Test Item'}):
|
||||
|
||||
# WHEN: Calling accept and the currentIndex method of the theme_combo_box returns 0
|
||||
frw.accept()
|
||||
|
||||
# THEN: The 'currentItem' in the combobox should have been set as the default theme.
|
||||
mocked_settings().setValue.assert_called_once_with('themes/global theme', 'Test Item')
|
||||
|
||||
@patch('openlp.core.ui.firsttimeform.QtWidgets.QWizard.reject')
|
||||
@patch('openlp.core.ui.firsttimeform.time')
|
||||
@patch('openlp.core.ui.firsttimeform.get_thread_worker')
|
||||
@patch('openlp.core.ui.firsttimeform.is_thread_finished')
|
||||
def test_on_cancel_button_clicked(self, mocked_is_thread_finished, mocked_get_thread_worker, mocked_time):
|
||||
def test_reject_method(
|
||||
self, mocked_is_thread_finished, mocked_get_thread_worker, mocked_time, mocked_qwizard_reject):
|
||||
"""
|
||||
Test that the cancel button click slot shuts down the threads correctly
|
||||
Test that the reject method shuts down the threads correctly
|
||||
"""
|
||||
# GIVEN: A FRW, some mocked threads and workers (that isn't quite done) and other mocked stuff
|
||||
mocked_worker = MagicMock()
|
||||
@ -235,17 +305,47 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
frw.thumbnail_download_threads = ['test_thread']
|
||||
with patch.object(frw.application, 'set_normal_cursor') as mocked_set_normal_cursor:
|
||||
|
||||
# WHEN: on_cancel_button_clicked() is called
|
||||
frw.on_cancel_button_clicked()
|
||||
# WHEN: the reject method is called
|
||||
frw.reject()
|
||||
|
||||
# THEN: The right things should be called in the right order
|
||||
assert frw.was_cancelled is True, 'The was_cancelled property should have been set to True'
|
||||
mocked_get_thread_worker.assert_called_once_with('test_thread')
|
||||
mocked_worker.cancel_download.assert_called_once()
|
||||
mocked_is_thread_finished.assert_called_with('test_thread')
|
||||
assert mocked_is_thread_finished.call_count == 2, 'isRunning() should have been called twice'
|
||||
mocked_time.sleep.assert_called_once_with(0.1)
|
||||
mocked_set_normal_cursor.assert_called_once_with()
|
||||
mocked_set_normal_cursor.assert_called_once()
|
||||
mocked_qwizard_reject.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.firsttimeform.ProxyDialog')
|
||||
def test_on_custom_button_clicked(self, mocked_proxy_dialog):
|
||||
"""
|
||||
Test _on_custom_button when it is called whe the 'internet settings' (CustomButton1) button is not clicked.
|
||||
"""
|
||||
# GIVEN: An instance of the FirstTimeForm
|
||||
frw = FirstTimeForm(None)
|
||||
|
||||
# WHEN: Calling _on_custom_button_clicked with a different button to the 'internet settings button.
|
||||
frw._on_custom_button_clicked(QtWidgets.QWizard.CustomButton2)
|
||||
|
||||
# THEN: The ProxyDialog should not be shown.
|
||||
mocked_proxy_dialog.assert_not_called()
|
||||
|
||||
@patch('openlp.core.ui.firsttimeform.ProxyDialog')
|
||||
def test_on_custom_button_clicked_internet_settings(self, mocked_proxy_dialog):
|
||||
"""
|
||||
Test _on_custom_button when it is called when the 'internet settings' (CustomButton1) button is clicked.
|
||||
"""
|
||||
# GIVEN: An instance of the FirstTimeForm
|
||||
frw = FirstTimeForm(None)
|
||||
|
||||
# WHEN: Calling _on_custom_button_clicked with the constant for the 'internet settings' button (CustomButton1)
|
||||
frw._on_custom_button_clicked(QtWidgets.QWizard.CustomButton1)
|
||||
|
||||
# THEN: The ProxyDialog should be shown.
|
||||
mocked_proxy_dialog.assert_called_with(frw)
|
||||
mocked_proxy_dialog().retranslate_ui.assert_called_once()
|
||||
mocked_proxy_dialog().exec.assert_called_once()
|
||||
|
||||
@patch('openlp.core.ui.firsttimeform.critical_error_message_box')
|
||||
def test__parse_config_invalid_config(self, mocked_critical_error_message_box):
|
||||
@ -279,10 +379,10 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
|
||||
# THEN: the critical_error_message_box should have been called
|
||||
mocked_message_box.critical.assert_called_once_with(
|
||||
first_time_form, 'Network Error', 'There was a network error attempting to connect to retrieve '
|
||||
'initial configuration information', 'OK')
|
||||
first_time_form, 'Network Error',
|
||||
'There was a network error attempting to connect to retrieve initial configuration information', 'OK')
|
||||
|
||||
@patch('openlp.core.ui.firsttimewizard.Settings')
|
||||
@patch('openlp.core.ui.firsttimeform.Settings')
|
||||
def test_on_projectors_check_box_checked(self, MockSettings):
|
||||
"""
|
||||
Test that the projector panel is shown when the checkbox in the first time wizard is checked
|
||||
@ -300,7 +400,7 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
mocked_settings.value.assert_called_once_with('projector/show after wizard')
|
||||
mocked_settings.setValue.assert_called_once_with('projector/show after wizard', False)
|
||||
|
||||
@patch('openlp.core.ui.firsttimewizard.Settings')
|
||||
@patch('openlp.core.ui.firsttimeform.Settings')
|
||||
def test_on_projectors_check_box_unchecked(self, MockSettings):
|
||||
"""
|
||||
Test that the projector panel is shown when the checkbox in the first time wizard is checked
|
||||
|
@ -22,6 +22,7 @@
|
||||
"""
|
||||
This module contains tests for the OpenLP song importer.
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
@ -66,8 +67,7 @@ class TestOpenLPImport(TestCase):
|
||||
importer.stop_import_flag = True
|
||||
|
||||
# WHEN: Import source is not a list
|
||||
for source in ['not a list', 0]:
|
||||
importer.import_source = source
|
||||
importer.import_source = Path()
|
||||
|
||||
# THEN: do_import should return none and the progress bar maximum should not be set.
|
||||
assert importer.do_import() is None, 'do_import should return None when import_source is not a list'
|
||||
|
Loading…
Reference in New Issue
Block a user