forked from openlp/openlp
head
This commit is contained in:
commit
c9e1dcceff
@ -122,6 +122,9 @@ class OpenLP(OpenLPMixin, QtGui.QApplication):
|
|||||||
ftw.initialize(screens)
|
ftw.initialize(screens)
|
||||||
if ftw.exec_() == QtGui.QDialog.Accepted:
|
if ftw.exec_() == QtGui.QDialog.Accepted:
|
||||||
Settings().setValue('core/has run wizard', True)
|
Settings().setValue('core/has run wizard', True)
|
||||||
|
elif ftw.was_cancelled:
|
||||||
|
QtCore.QCoreApplication.exit()
|
||||||
|
sys.exit()
|
||||||
# Correct stylesheet bugs
|
# Correct stylesheet bugs
|
||||||
application_stylesheet = ''
|
application_stylesheet = ''
|
||||||
if not Settings().value('advanced/alternate rows'):
|
if not Settings().value('advanced/alternate rows'):
|
||||||
|
@ -115,7 +115,7 @@ class UiStrings(object):
|
|||||||
self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
|
self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
|
||||||
self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
|
self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
|
||||||
self.OLPV2 = translate('OpenLP.Ui', 'OpenLP 2')
|
self.OLPV2 = translate('OpenLP.Ui', 'OpenLP 2')
|
||||||
self.OLPV2x = translate('OpenLP.Ui', 'OpenLP 2.1')
|
self.OLPV2x = translate('OpenLP.Ui', 'OpenLP 2.2')
|
||||||
self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?')
|
self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you wish to continue?')
|
||||||
self.OpenService = translate('OpenLP.Ui', 'Open service.')
|
self.OpenService = translate('OpenLP.Ui', 'Open service.')
|
||||||
self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')
|
self.PlaySlidesInLoop = translate('OpenLP.Ui', 'Play Slides in Loop')
|
||||||
|
@ -31,7 +31,6 @@ This module contains the first time wizard.
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import time
|
import time
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
@ -51,30 +50,48 @@ from .firsttimewizard import UiFirstTimeWizard, FirstTimePage
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ThemeScreenshotThread(QtCore.QThread):
|
class ThemeScreenshotWorker(QtCore.QObject):
|
||||||
"""
|
"""
|
||||||
This thread downloads the theme screenshots.
|
This thread downloads a theme's screenshot
|
||||||
"""
|
"""
|
||||||
|
screenshot_downloaded = QtCore.pyqtSignal(str, str)
|
||||||
|
finished = QtCore.pyqtSignal()
|
||||||
|
|
||||||
|
def __init__(self, themes_url, title, filename, screenshot):
|
||||||
|
"""
|
||||||
|
Set up the worker object
|
||||||
|
"""
|
||||||
|
self.was_download_cancelled = False
|
||||||
|
self.themes_url = themes_url
|
||||||
|
self.title = title
|
||||||
|
self.filename = filename
|
||||||
|
self.screenshot = screenshot
|
||||||
|
super(ThemeScreenshotWorker, self).__init__()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""
|
"""
|
||||||
Overridden method to run the thread.
|
Overridden method to run the thread.
|
||||||
"""
|
"""
|
||||||
themes = self.parent().config.get('themes', 'files')
|
if self.was_download_cancelled:
|
||||||
themes = themes.split(',')
|
return
|
||||||
config = self.parent().config
|
try:
|
||||||
for theme in themes:
|
urllib.request.urlretrieve('%s%s' % (self.themes_url, self.screenshot),
|
||||||
# Stop if the wizard has been cancelled.
|
os.path.join(gettempdir(), 'openlp', self.screenshot))
|
||||||
if self.parent().was_download_cancelled:
|
# Signal that the screenshot has been downloaded
|
||||||
return
|
self.screenshot_downloaded.emit(self.title, self.filename)
|
||||||
title = config.get('theme_%s' % theme, 'title')
|
except:
|
||||||
filename = config.get('theme_%s' % theme, 'filename')
|
log.exception('Unable to download screenshot')
|
||||||
screenshot = config.get('theme_%s' % theme, 'screenshot')
|
finally:
|
||||||
urllib.request.urlretrieve('%s%s' % (self.parent().themes_url, screenshot),
|
self.finished.emit()
|
||||||
os.path.join(gettempdir(), 'openlp', screenshot))
|
|
||||||
item = QtGui.QListWidgetItem(title, self.parent().themes_list_widget)
|
@QtCore.pyqtSlot(bool)
|
||||||
item.setData(QtCore.Qt.UserRole, filename)
|
def set_download_canceled(self, toggle):
|
||||||
item.setCheckState(QtCore.Qt.Unchecked)
|
"""
|
||||||
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
Externally set if the download was canceled
|
||||||
|
|
||||||
|
:param toggle: Set if the download was canceled or not
|
||||||
|
"""
|
||||||
|
self.was_download_cancelled = toggle
|
||||||
|
|
||||||
|
|
||||||
class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||||
@ -88,22 +105,25 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
Create and set up the first time wizard.
|
Create and set up the first time wizard.
|
||||||
"""
|
"""
|
||||||
super(FirstTimeForm, self).__init__(parent)
|
super(FirstTimeForm, self).__init__(parent)
|
||||||
|
self.web_access = True
|
||||||
|
self.web = ''
|
||||||
self.setup_ui(self)
|
self.setup_ui(self)
|
||||||
|
|
||||||
def get_next_page_id(self):
|
def get_next_page_id(self):
|
||||||
"""
|
"""
|
||||||
Returns the id of the next FirstTimePage to go to based on enabled plugins
|
Returns the id of the next FirstTimePage to go to based on enabled plugins
|
||||||
"""
|
"""
|
||||||
# The songs plugin is enabled
|
|
||||||
if FirstTimePage.Welcome < self.currentId() < FirstTimePage.Songs and self.songs_check_box.isChecked():
|
if FirstTimePage.Welcome < self.currentId() < FirstTimePage.Songs and self.songs_check_box.isChecked():
|
||||||
print('Go for songs! %r' % self.songs_check_box.isChecked())
|
# If the songs plugin is enabled then go to the songs page
|
||||||
return FirstTimePage.Songs
|
return FirstTimePage.Songs
|
||||||
# The Bibles plugin is enabled
|
|
||||||
elif FirstTimePage.Welcome < self.currentId() < FirstTimePage.Bibles and self.bible_check_box.isChecked():
|
elif FirstTimePage.Welcome < 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
|
return FirstTimePage.Bibles
|
||||||
elif FirstTimePage.Welcome < self.currentId() < FirstTimePage.Themes:
|
elif FirstTimePage.Welcome < 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
|
return FirstTimePage.Themes
|
||||||
else:
|
else:
|
||||||
|
# If all else fails, go to the next page
|
||||||
return self.currentId() + 1
|
return self.currentId() + 1
|
||||||
|
|
||||||
def nextId(self):
|
def nextId(self):
|
||||||
@ -111,18 +131,20 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
Determine the next page in the Wizard to go to.
|
Determine the next page in the Wizard to go to.
|
||||||
"""
|
"""
|
||||||
self.application.process_events()
|
self.application.process_events()
|
||||||
if self.currentId() == FirstTimePage.Plugins:
|
if self.currentId() == FirstTimePage.Download:
|
||||||
if not self.web_access:
|
if not self.web_access:
|
||||||
return FirstTimePage.NoInternet
|
return FirstTimePage.NoInternet
|
||||||
else:
|
else:
|
||||||
return self.get_next_page_id()
|
return FirstTimePage.Plugins
|
||||||
|
elif self.currentId() == FirstTimePage.Plugins:
|
||||||
|
return self.get_next_page_id()
|
||||||
elif self.currentId() == FirstTimePage.Progress:
|
elif self.currentId() == FirstTimePage.Progress:
|
||||||
return -1
|
return -1
|
||||||
elif self.currentId() == FirstTimePage.NoInternet:
|
elif self.currentId() == FirstTimePage.NoInternet:
|
||||||
return FirstTimePage.Progress
|
return FirstTimePage.Progress
|
||||||
elif self.currentId() == FirstTimePage.Themes:
|
elif self.currentId() == FirstTimePage.Themes:
|
||||||
self.application.set_busy_cursor()
|
self.application.set_busy_cursor()
|
||||||
while not self.theme_screenshot_thread.isFinished():
|
while not all([thread.isFinished() for thread in self.theme_screenshot_threads]):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
self.application.process_events()
|
self.application.process_events()
|
||||||
# Build the screenshot icons, as this can not be done in the thread.
|
# Build the screenshot icons, as this can not be done in the thread.
|
||||||
@ -146,11 +168,20 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
:param screens: The screens detected by OpenLP
|
:param screens: The screens detected by OpenLP
|
||||||
"""
|
"""
|
||||||
self.screens = screens
|
self.screens = screens
|
||||||
|
self.was_cancelled = False
|
||||||
|
self.theme_screenshot_threads = []
|
||||||
|
self.theme_screenshot_workers = []
|
||||||
|
self.has_run_wizard = False
|
||||||
|
|
||||||
|
def _download_index(self):
|
||||||
|
"""
|
||||||
|
Download the configuration file and kick off the theme screenshot download threads
|
||||||
|
"""
|
||||||
# check to see if we have web access
|
# check to see if we have web access
|
||||||
self.web_access = False
|
self.web_access = False
|
||||||
self.web = 'http://openlp.org/files/frw/'
|
|
||||||
self.config = ConfigParser()
|
self.config = ConfigParser()
|
||||||
user_agent = 'OpenLP/' + Registry().get('application').applicationVersion()
|
user_agent = 'OpenLP/' + Registry().get('application').applicationVersion()
|
||||||
|
self.application.process_events()
|
||||||
web_config = get_web_page('%s%s' % (self.web, 'download.cfg'), header=('User-Agent', user_agent))
|
web_config = get_web_page('%s%s' % (self.web, 'download.cfg'), header=('User-Agent', user_agent))
|
||||||
if web_config:
|
if web_config:
|
||||||
files = web_config.read()
|
files = web_config.read()
|
||||||
@ -165,24 +196,8 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
log.debug('A problem occured while parsing the downloaded config file')
|
log.debug('A problem occured while parsing the downloaded config file')
|
||||||
trace_error_handler(log)
|
trace_error_handler(log)
|
||||||
self.update_screen_list_combo()
|
self.update_screen_list_combo()
|
||||||
self.was_download_cancelled = False
|
self.application.process_events()
|
||||||
self.theme_screenshot_thread = None
|
|
||||||
self.has_run_wizard = False
|
|
||||||
self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading %s...')
|
self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading %s...')
|
||||||
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.currentIdChanged.connect(self.on_current_id_changed)
|
|
||||||
Registry().register_function('config_screen_changed', self.update_screen_list_combo)
|
|
||||||
|
|
||||||
def set_defaults(self):
|
|
||||||
"""
|
|
||||||
Set up display at start of theme edit.
|
|
||||||
"""
|
|
||||||
self.restart()
|
|
||||||
check_directory_exists(os.path.join(gettempdir(), 'openlp'))
|
|
||||||
self.no_internet_finish_button.setVisible(False)
|
|
||||||
# Check if this is a re-run of the wizard.
|
|
||||||
self.has_run_wizard = Settings().value('core/has run wizard')
|
|
||||||
if self.has_run_wizard:
|
if self.has_run_wizard:
|
||||||
self.songs_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songs').is_active())
|
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())
|
self.bible_check_box.setChecked(self.plugin_manager.get_plugin_by_name('bibles').is_active())
|
||||||
@ -199,6 +214,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
songs = self.config.get('songs', 'languages')
|
songs = self.config.get('songs', 'languages')
|
||||||
songs = songs.split(',')
|
songs = songs.split(',')
|
||||||
for song in songs:
|
for song in songs:
|
||||||
|
self.application.process_events()
|
||||||
title = self.config.get('songs_%s' % song, 'title')
|
title = self.config.get('songs_%s' % song, 'title')
|
||||||
filename = self.config.get('songs_%s' % song, 'filename')
|
filename = self.config.get('songs_%s' % song, 'filename')
|
||||||
item = QtGui.QListWidgetItem(title, self.songs_list_widget)
|
item = QtGui.QListWidgetItem(title, self.songs_list_widget)
|
||||||
@ -208,11 +224,13 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
bible_languages = self.config.get('bibles', 'languages')
|
bible_languages = self.config.get('bibles', 'languages')
|
||||||
bible_languages = bible_languages.split(',')
|
bible_languages = bible_languages.split(',')
|
||||||
for lang in bible_languages:
|
for lang in bible_languages:
|
||||||
|
self.application.process_events()
|
||||||
language = self.config.get('bibles_%s' % lang, 'title')
|
language = self.config.get('bibles_%s' % lang, 'title')
|
||||||
lang_item = QtGui.QTreeWidgetItem(self.bibles_tree_widget, [language])
|
lang_item = QtGui.QTreeWidgetItem(self.bibles_tree_widget, [language])
|
||||||
bibles = self.config.get('bibles_%s' % lang, 'translations')
|
bibles = self.config.get('bibles_%s' % lang, 'translations')
|
||||||
bibles = bibles.split(',')
|
bibles = bibles.split(',')
|
||||||
for bible in bibles:
|
for bible in bibles:
|
||||||
|
self.application.process_events()
|
||||||
title = self.config.get('bible_%s' % bible, 'title')
|
title = self.config.get('bible_%s' % bible, 'title')
|
||||||
filename = self.config.get('bible_%s' % bible, 'filename')
|
filename = self.config.get('bible_%s' % bible, 'filename')
|
||||||
item = QtGui.QTreeWidgetItem(lang_item, [title])
|
item = QtGui.QTreeWidgetItem(lang_item, [title])
|
||||||
@ -220,9 +238,38 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
item.setCheckState(0, QtCore.Qt.Unchecked)
|
item.setCheckState(0, QtCore.Qt.Unchecked)
|
||||||
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
||||||
self.bibles_tree_widget.expandAll()
|
self.bibles_tree_widget.expandAll()
|
||||||
# Download the theme screenshots.
|
self.application.process_events()
|
||||||
self.theme_screenshot_thread = ThemeScreenshotThread(self)
|
# Download the theme screenshots
|
||||||
self.theme_screenshot_thread.start()
|
themes = self.config.get('themes', 'files').split(',')
|
||||||
|
for theme in themes:
|
||||||
|
self.application.process_events()
|
||||||
|
title = self.config.get('theme_%s' % theme, 'title')
|
||||||
|
filename = self.config.get('theme_%s' % theme, 'filename')
|
||||||
|
screenshot = self.config.get('theme_%s' % theme, 'screenshot')
|
||||||
|
worker = ThemeScreenshotWorker(self.themes_url, title, filename, screenshot)
|
||||||
|
self.theme_screenshot_workers.append(worker)
|
||||||
|
worker.screenshot_downloaded.connect(self.on_screenshot_downloaded)
|
||||||
|
thread = QtCore.QThread(self)
|
||||||
|
self.theme_screenshot_threads.append(thread)
|
||||||
|
thread.started.connect(worker.run)
|
||||||
|
worker.finished.connect(thread.quit)
|
||||||
|
worker.moveToThread(thread)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
def set_defaults(self):
|
||||||
|
"""
|
||||||
|
Set up display at start of theme edit.
|
||||||
|
"""
|
||||||
|
self.restart()
|
||||||
|
self.web = 'http://openlp.org/files/frw/'
|
||||||
|
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.currentIdChanged.connect(self.on_current_id_changed)
|
||||||
|
Registry().register_function('config_screen_changed', self.update_screen_list_combo)
|
||||||
|
self.no_internet_finish_button.setVisible(False)
|
||||||
|
# Check if this is a re-run of the wizard.
|
||||||
|
self.has_run_wizard = Settings().value('core/has run wizard')
|
||||||
|
check_directory_exists(os.path.join(gettempdir(), 'openlp'))
|
||||||
|
|
||||||
def update_screen_list_combo(self):
|
def update_screen_list_combo(self):
|
||||||
"""
|
"""
|
||||||
@ -241,12 +288,20 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
self.application.process_events()
|
self.application.process_events()
|
||||||
if page_id != -1:
|
if page_id != -1:
|
||||||
self.last_id = page_id
|
self.last_id = page_id
|
||||||
if page_id == FirstTimePage.Plugins:
|
if page_id == FirstTimePage.Download:
|
||||||
|
self.back_button.setVisible(False)
|
||||||
|
self.next_button.setVisible(False)
|
||||||
# Set the no internet page text.
|
# Set the no internet page text.
|
||||||
if self.has_run_wizard:
|
if self.has_run_wizard:
|
||||||
self.no_internet_label.setText(self.no_internet_text)
|
self.no_internet_label.setText(self.no_internet_text)
|
||||||
else:
|
else:
|
||||||
self.no_internet_label.setText(self.no_internet_text + self.cancel_wizard_text)
|
self.no_internet_label.setText(self.no_internet_text + self.cancel_wizard_text)
|
||||||
|
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.Defaults:
|
elif page_id == FirstTimePage.Defaults:
|
||||||
self.theme_combo_box.clear()
|
self.theme_combo_box.clear()
|
||||||
for index in range(self.themes_list_widget.count()):
|
for index in range(self.themes_list_widget.count()):
|
||||||
@ -266,15 +321,12 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
elif page_id == FirstTimePage.NoInternet:
|
elif page_id == FirstTimePage.NoInternet:
|
||||||
self.back_button.setVisible(False)
|
self.back_button.setVisible(False)
|
||||||
self.next_button.setVisible(False)
|
self.next_button.setVisible(False)
|
||||||
|
self.cancel_button.setVisible(False)
|
||||||
self.no_internet_finish_button.setVisible(True)
|
self.no_internet_finish_button.setVisible(True)
|
||||||
if self.has_run_wizard:
|
elif page_id == FirstTimePage.Plugins:
|
||||||
self.cancel_button.setVisible(False)
|
self.back_button.setVisible(False)
|
||||||
elif page_id == FirstTimePage.Progress:
|
elif page_id == FirstTimePage.Progress:
|
||||||
self.application.set_busy_cursor()
|
self.application.set_busy_cursor()
|
||||||
self.repaint()
|
|
||||||
self.application.process_events()
|
|
||||||
# Try to give the wizard a chance to redraw itself
|
|
||||||
time.sleep(0.2)
|
|
||||||
self._pre_wizard()
|
self._pre_wizard()
|
||||||
self._perform_wizard()
|
self._perform_wizard()
|
||||||
self._post_wizard()
|
self._post_wizard()
|
||||||
@ -284,17 +336,28 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
Process the triggering of the cancel button.
|
Process the triggering of the cancel button.
|
||||||
"""
|
"""
|
||||||
if self.last_id == FirstTimePage.NoInternet or \
|
self.was_cancelled = True
|
||||||
(self.last_id <= FirstTimePage.Plugins and not self.has_run_wizard):
|
if self.theme_screenshot_workers:
|
||||||
QtCore.QCoreApplication.exit()
|
for worker in self.theme_screenshot_workers:
|
||||||
sys.exit()
|
worker.set_download_canceled(True)
|
||||||
self.was_download_cancelled = True
|
|
||||||
# Was the thread created.
|
# Was the thread created.
|
||||||
if self.theme_screenshot_thread:
|
if self.theme_screenshot_threads:
|
||||||
while self.theme_screenshot_thread.isRunning():
|
while any([thread.isRunning() for thread in self.theme_screenshot_threads]):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
|
|
||||||
|
def on_screenshot_downloaded(self, title, filename):
|
||||||
|
"""
|
||||||
|
Add an item to the list when a theme has been downloaded
|
||||||
|
|
||||||
|
:param title: The title of the theme
|
||||||
|
:param filename: The filename of the theme
|
||||||
|
"""
|
||||||
|
item = QtGui.QListWidgetItem(title, self.themes_list_widget)
|
||||||
|
item.setData(QtCore.Qt.UserRole, filename)
|
||||||
|
item.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
||||||
|
|
||||||
def on_no_internet_finish_button_clicked(self):
|
def on_no_internet_finish_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Process the triggering of the "Finish" button on the No Internet page.
|
Process the triggering of the "Finish" button on the No Internet page.
|
||||||
@ -321,7 +384,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
url_file = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
|
url_file = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
|
||||||
filename = open(f_path, "wb")
|
filename = open(f_path, "wb")
|
||||||
# Download until finished or canceled.
|
# Download until finished or canceled.
|
||||||
while not self.was_download_cancelled:
|
while not self.was_cancelled:
|
||||||
data = url_file.read(block_size)
|
data = url_file.read(block_size)
|
||||||
if not data:
|
if not data:
|
||||||
break
|
break
|
||||||
@ -341,7 +404,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
# Delete file if cancelled, it may be a partial file.
|
# Delete file if cancelled, it may be a partial file.
|
||||||
if self.was_download_cancelled:
|
if self.was_cancelled:
|
||||||
os.remove(f_path)
|
os.remove(f_path)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -354,6 +417,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
|||||||
for index, theme in enumerate(themes):
|
for index, theme in enumerate(themes):
|
||||||
screenshot = self.config.get('theme_%s' % theme, 'screenshot')
|
screenshot = self.config.get('theme_%s' % theme, 'screenshot')
|
||||||
item = self.themes_list_widget.item(index)
|
item = self.themes_list_widget.item(index)
|
||||||
|
# if item:
|
||||||
item.setIcon(build_icon(os.path.join(gettempdir(), 'openlp', screenshot)))
|
item.setIcon(build_icon(os.path.join(gettempdir(), 'openlp', screenshot)))
|
||||||
|
|
||||||
def _get_file_size(self, url):
|
def _get_file_size(self, url):
|
||||||
|
@ -41,13 +41,14 @@ class FirstTimePage(object):
|
|||||||
An enumeration class with each of the pages of the wizard.
|
An enumeration class with each of the pages of the wizard.
|
||||||
"""
|
"""
|
||||||
Welcome = 0
|
Welcome = 0
|
||||||
Plugins = 1
|
Download = 1
|
||||||
NoInternet = 2
|
NoInternet = 2
|
||||||
Songs = 3
|
Plugins = 3
|
||||||
Bibles = 4
|
Songs = 4
|
||||||
Themes = 5
|
Bibles = 5
|
||||||
Defaults = 6
|
Themes = 6
|
||||||
Progress = 7
|
Defaults = 7
|
||||||
|
Progress = 8
|
||||||
|
|
||||||
|
|
||||||
class UiFirstTimeWizard(object):
|
class UiFirstTimeWizard(object):
|
||||||
@ -78,6 +79,27 @@ class UiFirstTimeWizard(object):
|
|||||||
self.next_button = self.button(QtGui.QWizard.NextButton)
|
self.next_button = self.button(QtGui.QWizard.NextButton)
|
||||||
self.back_button = self.button(QtGui.QWizard.BackButton)
|
self.back_button = self.button(QtGui.QWizard.BackButton)
|
||||||
add_welcome_page(first_time_wizard, ':/wizards/wizard_firsttime.bmp')
|
add_welcome_page(first_time_wizard, ':/wizards/wizard_firsttime.bmp')
|
||||||
|
# The download page
|
||||||
|
self.download_page = QtGui.QWizardPage()
|
||||||
|
self.download_page.setObjectName('download_page')
|
||||||
|
self.download_layout = QtGui.QVBoxLayout(self.download_page)
|
||||||
|
self.download_layout.setMargin(48)
|
||||||
|
self.download_layout.setObjectName('download_layout')
|
||||||
|
self.download_label = QtGui.QLabel(self.download_page)
|
||||||
|
self.download_label.setObjectName('download_label')
|
||||||
|
self.download_layout.addWidget(self.download_label)
|
||||||
|
first_time_wizard.setPage(FirstTimePage.Download, self.download_page)
|
||||||
|
# The "you don't have an internet connection" page.
|
||||||
|
self.no_internet_page = QtGui.QWizardPage()
|
||||||
|
self.no_internet_page.setObjectName('no_internet_page')
|
||||||
|
self.no_internet_layout = QtGui.QVBoxLayout(self.no_internet_page)
|
||||||
|
self.no_internet_layout.setContentsMargins(50, 30, 50, 40)
|
||||||
|
self.no_internet_layout.setObjectName('no_internet_layout')
|
||||||
|
self.no_internet_label = QtGui.QLabel(self.no_internet_page)
|
||||||
|
self.no_internet_label.setWordWrap(True)
|
||||||
|
self.no_internet_label.setObjectName('no_internet_label')
|
||||||
|
self.no_internet_layout.addWidget(self.no_internet_label)
|
||||||
|
first_time_wizard.setPage(FirstTimePage.NoInternet, self.no_internet_page)
|
||||||
# The plugins page
|
# The plugins page
|
||||||
self.plugin_page = QtGui.QWizardPage()
|
self.plugin_page = QtGui.QWizardPage()
|
||||||
self.plugin_page.setObjectName('plugin_page')
|
self.plugin_page.setObjectName('plugin_page')
|
||||||
@ -120,17 +142,6 @@ class UiFirstTimeWizard(object):
|
|||||||
self.alert_check_box.setObjectName('alert_check_box')
|
self.alert_check_box.setObjectName('alert_check_box')
|
||||||
self.plugin_layout.addWidget(self.alert_check_box)
|
self.plugin_layout.addWidget(self.alert_check_box)
|
||||||
first_time_wizard.setPage(FirstTimePage.Plugins, self.plugin_page)
|
first_time_wizard.setPage(FirstTimePage.Plugins, self.plugin_page)
|
||||||
# The "you don't have an internet connection" page.
|
|
||||||
self.no_internet_page = QtGui.QWizardPage()
|
|
||||||
self.no_internet_page.setObjectName('no_internet_page')
|
|
||||||
self.no_internet_layout = QtGui.QVBoxLayout(self.no_internet_page)
|
|
||||||
self.no_internet_layout.setContentsMargins(50, 30, 50, 40)
|
|
||||||
self.no_internet_layout.setObjectName('no_internet_layout')
|
|
||||||
self.no_internet_label = QtGui.QLabel(self.no_internet_page)
|
|
||||||
self.no_internet_label.setWordWrap(True)
|
|
||||||
self.no_internet_label.setObjectName('no_internet_label')
|
|
||||||
self.no_internet_layout.addWidget(self.no_internet_label)
|
|
||||||
first_time_wizard.setPage(FirstTimePage.NoInternet, self.no_internet_page)
|
|
||||||
# The song samples page
|
# The song samples page
|
||||||
self.songs_page = QtGui.QWizardPage()
|
self.songs_page = QtGui.QWizardPage()
|
||||||
self.songs_page.setObjectName('songs_page')
|
self.songs_page.setObjectName('songs_page')
|
||||||
@ -221,6 +232,11 @@ class UiFirstTimeWizard(object):
|
|||||||
translate('OpenLP.FirstTimeWizard', 'This wizard will help you to configure OpenLP for initial use. '
|
translate('OpenLP.FirstTimeWizard', 'This wizard will help you to configure OpenLP for initial use. '
|
||||||
'Click the %s button below to start.') %
|
'Click the %s button below to start.') %
|
||||||
clean_button_text(first_time_wizard.buttonText(QtGui.QWizard.NextButton)))
|
clean_button_text(first_time_wizard.buttonText(QtGui.QWizard.NextButton)))
|
||||||
|
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.plugin_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Activate required Plugins'))
|
self.plugin_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Activate required Plugins'))
|
||||||
self.plugin_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select the Plugins you wish to use. '))
|
self.plugin_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select the Plugins you wish to use. '))
|
||||||
self.songs_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Songs'))
|
self.songs_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Songs'))
|
||||||
@ -257,5 +273,8 @@ class UiFirstTimeWizard(object):
|
|||||||
'Set up default settings to be used by OpenLP.'))
|
'Set up default settings to be used by OpenLP.'))
|
||||||
self.display_label.setText(translate('OpenLP.FirstTimeWizard', 'Default output display:'))
|
self.display_label.setText(translate('OpenLP.FirstTimeWizard', 'Default output display:'))
|
||||||
self.theme_label.setText(translate('OpenLP.FirstTimeWizard', 'Select default theme:'))
|
self.theme_label.setText(translate('OpenLP.FirstTimeWizard', 'Select default theme:'))
|
||||||
|
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...'))
|
self.progress_label.setText(translate('OpenLP.FirstTimeWizard', 'Starting configuration process...'))
|
||||||
first_time_wizard.setButtonText(QtGui.QWizard.CustomButton1, translate('OpenLP.FirstTimeWizard', 'Finish'))
|
first_time_wizard.setButtonText(QtGui.QWizard.CustomButton1, translate('OpenLP.FirstTimeWizard', 'Finish'))
|
||||||
|
@ -690,7 +690,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
|
|||||||
first_run_wizard = FirstTimeForm(self)
|
first_run_wizard = FirstTimeForm(self)
|
||||||
first_run_wizard.initialize(ScreenList())
|
first_run_wizard.initialize(ScreenList())
|
||||||
first_run_wizard.exec_()
|
first_run_wizard.exec_()
|
||||||
if first_run_wizard.was_download_cancelled:
|
if first_run_wizard.was_cancelled:
|
||||||
return
|
return
|
||||||
self.application.set_busy_cursor()
|
self.application.set_busy_cursor()
|
||||||
self.first_time()
|
self.first_time()
|
||||||
|
@ -152,16 +152,19 @@ def set_button_tooltip(bar):
|
|||||||
"""
|
"""
|
||||||
for button in bar.buttons():
|
for button in bar.buttons():
|
||||||
if bar.standardButton(button) == QDialogButtonBox.Cancel:
|
if bar.standardButton(button) == QDialogButtonBox.Cancel:
|
||||||
tip = "Ignoring current changes and return to OpenLP"
|
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||||
|
'Ignoring current changes and return to OpenLP'))
|
||||||
elif bar.standardButton(button) == QDialogButtonBox.Reset:
|
elif bar.standardButton(button) == QDialogButtonBox.Reset:
|
||||||
tip = "Delete all user-defined text and revert to PJLink default text"
|
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||||
|
'Delete all user-defined text and revert to PJLink default text'))
|
||||||
elif bar.standardButton(button) == QDialogButtonBox.Discard:
|
elif bar.standardButton(button) == QDialogButtonBox.Discard:
|
||||||
tip = "Discard changes and reset to previous user-defined text"
|
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||||
|
'Discard changes and reset to previous user-defined text'))
|
||||||
elif bar.standardButton(button) == QDialogButtonBox.Ok:
|
elif bar.standardButton(button) == QDialogButtonBox.Ok:
|
||||||
tip = "Save changes and return to OpenLP"
|
button.setToolTip(translate('OpenLP.SourceSelectForm',
|
||||||
|
'Save changes and return to OpenLP'))
|
||||||
else:
|
else:
|
||||||
tip = ""
|
log.debug('No tooltip for button {}'.format(button.text()))
|
||||||
button.setToolTip(tip)
|
|
||||||
|
|
||||||
|
|
||||||
class FingerTabBarWidget(QTabBar):
|
class FingerTabBarWidget(QTabBar):
|
||||||
@ -237,12 +240,13 @@ class SourceSelectTabs(QDialog):
|
|||||||
"""
|
"""
|
||||||
log.debug('Initializing SourceSelectTabs()')
|
log.debug('Initializing SourceSelectTabs()')
|
||||||
super(SourceSelectTabs, self).__init__(parent)
|
super(SourceSelectTabs, self).__init__(parent)
|
||||||
|
self.setMinimumWidth(350)
|
||||||
self.projectordb = projectordb
|
self.projectordb = projectordb
|
||||||
self.edit = edit
|
self.edit = edit
|
||||||
if self.edit:
|
if self.edit:
|
||||||
title = translate('OpenLP.SourceSelectForm', 'Select Projector Source')
|
|
||||||
else:
|
|
||||||
title = translate('OpenLP.SourceSelectForm', 'Edit Projector Source Text')
|
title = translate('OpenLP.SourceSelectForm', 'Edit Projector Source Text')
|
||||||
|
else:
|
||||||
|
title = translate('OpenLP.SourceSelectForm', 'Select Projector Source')
|
||||||
self.setWindowTitle(title)
|
self.setWindowTitle(title)
|
||||||
self.setObjectName('source_select_tabs')
|
self.setObjectName('source_select_tabs')
|
||||||
self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png'))
|
self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png'))
|
||||||
@ -286,6 +290,10 @@ class SourceSelectTabs(QDialog):
|
|||||||
thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key])
|
thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key])
|
||||||
if buttonchecked:
|
if buttonchecked:
|
||||||
self.tabwidget.setCurrentIndex(thistab)
|
self.tabwidget.setCurrentIndex(thistab)
|
||||||
|
self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Reset |
|
||||||
|
QtGui.QDialogButtonBox.Discard |
|
||||||
|
QtGui.QDialogButtonBox.Ok |
|
||||||
|
QtGui.QDialogButtonBox.Cancel)
|
||||||
else:
|
else:
|
||||||
for key in keys:
|
for key in keys:
|
||||||
(tab, button_count, buttonchecked) = Build_Tab(group=self.button_group,
|
(tab, button_count, buttonchecked) = Build_Tab(group=self.button_group,
|
||||||
@ -297,10 +305,8 @@ class SourceSelectTabs(QDialog):
|
|||||||
thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key])
|
thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key])
|
||||||
if buttonchecked:
|
if buttonchecked:
|
||||||
self.tabwidget.setCurrentIndex(thistab)
|
self.tabwidget.setCurrentIndex(thistab)
|
||||||
self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Reset |
|
self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Ok |
|
||||||
QtGui.QDialogButtonBox.Discard |
|
QtGui.QDialogButtonBox.Cancel)
|
||||||
QtGui.QDialogButtonBox.Ok |
|
|
||||||
QtGui.QDialogButtonBox.Cancel)
|
|
||||||
self.button_box.clicked.connect(self.button_clicked)
|
self.button_box.clicked.connect(self.button_clicked)
|
||||||
self.layout.addWidget(self.button_box)
|
self.layout.addWidget(self.button_box)
|
||||||
set_button_tooltip(self.button_box)
|
set_button_tooltip(self.button_box)
|
||||||
@ -321,9 +327,9 @@ class SourceSelectTabs(QDialog):
|
|||||||
if self.button_box.standardButton(button) == self.button_box.Cancel:
|
if self.button_box.standardButton(button) == self.button_box.Cancel:
|
||||||
self.done(0)
|
self.done(0)
|
||||||
elif self.button_box.standardButton(button) == self.button_box.Reset:
|
elif self.button_box.standardButton(button) == self.button_box.Reset:
|
||||||
self.delete_sources()
|
|
||||||
elif self.button_box.standardButton(button) == self.button_box.Discard:
|
|
||||||
self.done(100)
|
self.done(100)
|
||||||
|
elif self.button_box.standardButton(button) == self.button_box.Discard:
|
||||||
|
self.delete_sources()
|
||||||
elif self.button_box.standardButton(button) == self.button_box.Ok:
|
elif self.button_box.standardButton(button) == self.button_box.Ok:
|
||||||
return self.accept_me()
|
return self.accept_me()
|
||||||
else:
|
else:
|
||||||
@ -331,9 +337,11 @@ class SourceSelectTabs(QDialog):
|
|||||||
|
|
||||||
def delete_sources(self):
|
def delete_sources(self):
|
||||||
msg = QtGui.QMessageBox()
|
msg = QtGui.QMessageBox()
|
||||||
msg.setText('Delete entries for this projector')
|
msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector'))
|
||||||
msg.setInformativeText('Are you sure you want to delete ALL user-defined '
|
msg.setInformativeText(translate('OpenLP.SourceSelectForm',
|
||||||
'source input text for this projector?')
|
'Are you sure you want to delete ALL user-defined '),
|
||||||
|
translate('OpenLP.SourceSelectForm',
|
||||||
|
'source input text for this projector?'))
|
||||||
msg.setStandardButtons(msg.Cancel | msg.Ok)
|
msg.setStandardButtons(msg.Cancel | msg.Ok)
|
||||||
msg.setDefaultButton(msg.Cancel)
|
msg.setDefaultButton(msg.Cancel)
|
||||||
ans = msg.exec_()
|
ans = msg.exec_()
|
||||||
@ -382,7 +390,11 @@ class SourceSelectSingle(QDialog):
|
|||||||
log.debug('Initializing SourceSelectSingle()')
|
log.debug('Initializing SourceSelectSingle()')
|
||||||
self.projectordb = projectordb
|
self.projectordb = projectordb
|
||||||
super(SourceSelectSingle, self).__init__(parent)
|
super(SourceSelectSingle, self).__init__(parent)
|
||||||
self.setWindowTitle(translate('OpenLP.SourceSelectSingle', 'Select Projector Source'))
|
self.edit = edit
|
||||||
|
if self.edit:
|
||||||
|
title = translate('OpenLP.SourceSelectForm', 'Edit Projector Source Text')
|
||||||
|
else:
|
||||||
|
title = translate('OpenLP.SourceSelectForm', 'Select Projector Source')
|
||||||
self.setObjectName('source_select_single')
|
self.setObjectName('source_select_single')
|
||||||
self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png'))
|
self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png'))
|
||||||
self.setModal(True)
|
self.setModal(True)
|
||||||
@ -418,6 +430,10 @@ class SourceSelectSingle(QDialog):
|
|||||||
item.setText(source_item.text)
|
item.setText(source_item.text)
|
||||||
self.layout.addRow(PJLINK_DEFAULT_CODES[key], item)
|
self.layout.addRow(PJLINK_DEFAULT_CODES[key], item)
|
||||||
self.button_group.append(item)
|
self.button_group.append(item)
|
||||||
|
self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Reset |
|
||||||
|
QtGui.QDialogButtonBox.Discard |
|
||||||
|
QtGui.QDialogButtonBox.Ok |
|
||||||
|
QtGui.QDialogButtonBox.Cancel)
|
||||||
else:
|
else:
|
||||||
for key in keys:
|
for key in keys:
|
||||||
source_text = self.projectordb.get_source_by_code(code=key, projector_id=self.projector.db_item.id)
|
source_text = self.projectordb.get_source_by_code(code=key, projector_id=self.projector.db_item.id)
|
||||||
@ -427,10 +443,8 @@ class SourceSelectSingle(QDialog):
|
|||||||
self.layout.addWidget(button)
|
self.layout.addWidget(button)
|
||||||
self.button_group.addButton(button, int(key))
|
self.button_group.addButton(button, int(key))
|
||||||
button_list.append(key)
|
button_list.append(key)
|
||||||
self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Reset |
|
self.button_box = QDialogButtonBox(QtGui.QDialogButtonBox.Ok |
|
||||||
QtGui.QDialogButtonBox.Discard |
|
QtGui.QDialogButtonBox.Cancel)
|
||||||
QtGui.QDialogButtonBox.Ok |
|
|
||||||
QtGui.QDialogButtonBox.Cancel)
|
|
||||||
self.button_box.clicked.connect(self.button_clicked)
|
self.button_box.clicked.connect(self.button_clicked)
|
||||||
self.layout.addWidget(self.button_box)
|
self.layout.addWidget(self.button_box)
|
||||||
self.setMinimumHeight(key_count*25)
|
self.setMinimumHeight(key_count*25)
|
||||||
@ -452,9 +466,9 @@ class SourceSelectSingle(QDialog):
|
|||||||
if self.button_box.standardButton(button) == self.button_box.Cancel:
|
if self.button_box.standardButton(button) == self.button_box.Cancel:
|
||||||
self.done(0)
|
self.done(0)
|
||||||
elif self.button_box.standardButton(button) == self.button_box.Reset:
|
elif self.button_box.standardButton(button) == self.button_box.Reset:
|
||||||
self.delete_sources()
|
|
||||||
elif self.button_box.standardButton(button) == self.button_box.Discard:
|
|
||||||
self.done(100)
|
self.done(100)
|
||||||
|
elif self.button_box.standardButton(button) == self.button_box.Discard:
|
||||||
|
self.delete_sources()
|
||||||
elif self.button_box.standardButton(button) == self.button_box.Ok:
|
elif self.button_box.standardButton(button) == self.button_box.Ok:
|
||||||
return self.accept_me()
|
return self.accept_me()
|
||||||
else:
|
else:
|
||||||
@ -462,9 +476,11 @@ class SourceSelectSingle(QDialog):
|
|||||||
|
|
||||||
def delete_sources(self):
|
def delete_sources(self):
|
||||||
msg = QtGui.QMessageBox()
|
msg = QtGui.QMessageBox()
|
||||||
msg.setText('Delete entries for this projector')
|
msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector'))
|
||||||
msg.setInformativeText('Are you sure you want to delete ALL user-defined '
|
msg.setInformativeText(translate('OpenLP.SourceSelectForm',
|
||||||
'source input text for this projector?')
|
'Are you sure you want to delete ALL user-defined '),
|
||||||
|
translate('OpenLP.SourceSelectForm',
|
||||||
|
'source input text for this projector?'))
|
||||||
msg.setStandardButtons(msg.Cancel | msg.Ok)
|
msg.setStandardButtons(msg.Cancel | msg.Ok)
|
||||||
msg.setDefaultButton(msg.Cancel)
|
msg.setDefaultButton(msg.Cancel)
|
||||||
ans = msg.exec_()
|
ans = msg.exec_()
|
||||||
|
@ -96,7 +96,6 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.search_text_label.setText('%s:' % UiStrings().Search)
|
self.search_text_label.setText('%s:' % UiStrings().Search)
|
||||||
self.search_text_button.setText(UiStrings().Search)
|
self.search_text_button.setText(UiStrings().Search)
|
||||||
@ -134,6 +133,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
# Called to redisplay the custom list screen edith from a search
|
# Called to redisplay the custom list screen edith from a search
|
||||||
# or from the exit of the Custom edit dialog. If remote editing is
|
# or from the exit of the Custom edit dialog. If remote editing is
|
||||||
# active trigger it and clean up so it will not update again.
|
# active trigger it and clean up so it will not update again.
|
||||||
|
self.check_search_result()
|
||||||
|
|
||||||
def on_new_click(self):
|
def on_new_click(self):
|
||||||
"""
|
"""
|
||||||
@ -287,10 +287,15 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
log.debug('service_load')
|
log.debug('service_load')
|
||||||
if self.plugin.status != PluginStatus.Active:
|
if self.plugin.status != PluginStatus.Active:
|
||||||
return
|
return
|
||||||
custom = self.plugin.db_manager.get_object_filtered(CustomSlide, and_(CustomSlide.title == item.title,
|
if item.theme:
|
||||||
CustomSlide.theme_name == item.theme,
|
custom = self.plugin.db_manager.get_object_filtered(CustomSlide, and_(CustomSlide.title == item.title,
|
||||||
CustomSlide.credits ==
|
CustomSlide.theme_name == item.theme,
|
||||||
item.raw_footer[0][len(item.title) + 1:]))
|
CustomSlide.credits ==
|
||||||
|
item.raw_footer[0][len(item.title) + 1:]))
|
||||||
|
else:
|
||||||
|
custom = self.plugin.db_manager.get_object_filtered(CustomSlide, and_(CustomSlide.title == item.title,
|
||||||
|
CustomSlide.credits ==
|
||||||
|
item.raw_footer[0][len(item.title) + 1:]))
|
||||||
if custom:
|
if custom:
|
||||||
item.edit_id = custom.id
|
item.edit_id = custom.id
|
||||||
return item
|
return item
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from datetime import time
|
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
@ -126,18 +125,18 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||||||
Adds buttons to the start of the header bar.
|
Adds buttons to the start of the header bar.
|
||||||
"""
|
"""
|
||||||
if 'vlc' in get_media_players()[0]:
|
if 'vlc' in get_media_players()[0]:
|
||||||
diable_optical_button_text = False
|
disable_optical_button_text = False
|
||||||
optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
|
optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
|
||||||
optical_button_tooltip = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
|
optical_button_tooltip = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
|
||||||
else:
|
else:
|
||||||
diable_optical_button_text = True
|
disable_optical_button_text = True
|
||||||
optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
|
optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
|
||||||
optical_button_tooltip = translate('MediaPlugin.MediaItem',
|
optical_button_tooltip = translate('MediaPlugin.MediaItem',
|
||||||
'Load CD/DVD - only supported when VLC is installed and enabled')
|
'Load CD/DVD - only supported when VLC is installed and enabled')
|
||||||
self.load_optical = self.toolbar.add_toolbar_action('load_optical', icon=OPTICAL_ICON, text=optical_button_text,
|
self.load_optical = self.toolbar.add_toolbar_action('load_optical', icon=OPTICAL_ICON, text=optical_button_text,
|
||||||
tooltip=optical_button_tooltip,
|
tooltip=optical_button_tooltip,
|
||||||
triggers=self.on_load_optical)
|
triggers=self.on_load_optical)
|
||||||
if diable_optical_button_text:
|
if disable_optical_button_text:
|
||||||
self.load_optical.setDisabled(True)
|
self.load_optical.setDisabled(True)
|
||||||
|
|
||||||
def add_end_header_bar(self):
|
def add_end_header_bar(self):
|
||||||
@ -282,7 +281,6 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||||||
Initialize media item.
|
Initialize media item.
|
||||||
"""
|
"""
|
||||||
self.list_view.clear()
|
self.list_view.clear()
|
||||||
self.list_view.setIconSize(QtCore.QSize(88, 50))
|
|
||||||
self.service_path = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
|
self.service_path = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
|
||||||
check_directory_exists(self.service_path)
|
check_directory_exists(self.service_path)
|
||||||
self.load_list(Settings().value(self.settings_section + '/media files'))
|
self.load_list(Settings().value(self.settings_section + '/media files'))
|
||||||
|
@ -306,9 +306,9 @@ class HttpRouter(RegistryProperties):
|
|||||||
Translate various strings in the mobile app.
|
Translate various strings in the mobile app.
|
||||||
"""
|
"""
|
||||||
self.template_vars = {
|
self.template_vars = {
|
||||||
'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.1 Remote'),
|
'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Remote'),
|
||||||
'stage_title': translate('RemotePlugin.Mobile', 'OpenLP 2.1 Stage View'),
|
'stage_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Stage View'),
|
||||||
'live_title': translate('RemotePlugin.Mobile', 'OpenLP 2.1 Live View'),
|
'live_title': translate('RemotePlugin.Mobile', 'OpenLP 2.2 Live View'),
|
||||||
'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
|
'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
|
||||||
'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
|
'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
|
||||||
'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
|
'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
|
||||||
|
@ -265,7 +265,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _validate_tags(self, tags):
|
def _validate_tags(self, tags, first_time=True):
|
||||||
"""
|
"""
|
||||||
Validates a list of tags
|
Validates a list of tags
|
||||||
Deletes the first affiliated tag pair which is located side by side in the list
|
Deletes the first affiliated tag pair which is located side by side in the list
|
||||||
@ -277,6 +277,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||||||
:param tags: A list of tags
|
:param tags: A list of tags
|
||||||
:return: True if the function can't find any mismatched tags. Else False.
|
:return: True if the function can't find any mismatched tags. Else False.
|
||||||
"""
|
"""
|
||||||
|
if first_time:
|
||||||
|
fixed_tags = []
|
||||||
|
for i in range(len(tags)):
|
||||||
|
if tags[i] != '{br}':
|
||||||
|
fixed_tags.append(tags[i])
|
||||||
|
tags = fixed_tags
|
||||||
if len(tags) == 0:
|
if len(tags) == 0:
|
||||||
return True
|
return True
|
||||||
if len(tags) % 2 != 0:
|
if len(tags) % 2 != 0:
|
||||||
@ -284,7 +290,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||||||
for i in range(len(tags)-1):
|
for i in range(len(tags)-1):
|
||||||
if tags[i+1] == "{/" + tags[i][1:]:
|
if tags[i+1] == "{/" + tags[i][1:]:
|
||||||
del tags[i:i+2]
|
del tags[i:i+2]
|
||||||
return self._validate_tags(tags)
|
return self._validate_tags(tags, False)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _process_lyrics(self):
|
def _process_lyrics(self):
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
Package to test the openlp.core.ui.firsttimeform package.
|
Package to test the openlp.core.ui.firsttimeform package.
|
||||||
"""
|
"""
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
|
import os
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from openlp.core.common import Registry
|
from openlp.core.common import Registry
|
||||||
@ -71,55 +72,117 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.setup_application()
|
self.setup_application()
|
||||||
self.app.setApplicationVersion('0.0')
|
self.app.setApplicationVersion('0.0')
|
||||||
|
# Set up a fake "set_normal_cursor" method since we're not dealing with an actual OpenLP application object
|
||||||
|
self.app.set_normal_cursor = lambda: None
|
||||||
|
self.app.process_events = lambda: None
|
||||||
Registry.create()
|
Registry.create()
|
||||||
Registry().register('application', self.app)
|
Registry().register('application', self.app)
|
||||||
|
|
||||||
def basic_initialise_test(self):
|
def initialise_test(self):
|
||||||
"""
|
"""
|
||||||
Test if we can intialise the FirstTimeForm without a config file
|
Test if we can intialise the FirstTimeForm
|
||||||
"""
|
"""
|
||||||
# GIVEN: A mocked get_web_page, a First Time Wizard and an expected screen object
|
# GIVEN: A First Time Wizard and an expected screen object
|
||||||
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
|
frw = FirstTimeForm(None)
|
||||||
first_time_form = FirstTimeForm(None)
|
expected_screens = MagicMock()
|
||||||
expected_screens = MagicMock()
|
|
||||||
expected_web_url = 'http://openlp.org/files/frw/'
|
|
||||||
expected_user_agent = 'OpenLP/0.0'
|
|
||||||
mocked_get_web_page.return_value = None
|
|
||||||
|
|
||||||
# WHEN: The First Time Wizard is initialised
|
# WHEN: The First Time Wizard is initialised
|
||||||
first_time_form.initialize(expected_screens)
|
frw.initialize(expected_screens)
|
||||||
|
|
||||||
# THEN: The First Time Form web configuration file should be accessible and parseable
|
# THEN: The screens should be set up, and the default values initialised
|
||||||
self.assertEqual(expected_screens, first_time_form.screens, 'The screens should be correct')
|
self.assertEqual(expected_screens, frw.screens, 'The screens should be correct')
|
||||||
self.assertEqual(expected_web_url, first_time_form.web, 'The base path of the URL should be correct')
|
self.assertTrue(frw.web_access, 'The default value of self.web_access should be True')
|
||||||
self.assertIsInstance(first_time_form.config, ConfigParser, 'The config object should be a ConfigParser')
|
self.assertFalse(frw.was_cancelled, 'The default value of self.was_cancelled should be False')
|
||||||
mocked_get_web_page.assert_called_with(expected_web_url + 'download.cfg',
|
self.assertListEqual([], frw.theme_screenshot_threads, 'The list of threads should be empty')
|
||||||
header=('User-Agent', expected_user_agent))
|
self.assertListEqual([], frw.theme_screenshot_workers, 'The list of workers should be empty')
|
||||||
|
self.assertFalse(frw.has_run_wizard, 'has_run_wizard should be False')
|
||||||
|
|
||||||
def config_initialise_test(self):
|
def set_defaults_test(self):
|
||||||
"""
|
"""
|
||||||
Test if we can intialise the FirstTimeForm with a config file
|
Test that the default values are set when set_defaults() is run
|
||||||
"""
|
"""
|
||||||
# GIVEN: A mocked get_web_page, a First Time Wizard and an expected screen object
|
# GIVEN: An initialised FRW and a whole lot of stuff mocked out
|
||||||
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
|
frw = FirstTimeForm(None)
|
||||||
first_time_form = FirstTimeForm(None)
|
frw.initialize(MagicMock())
|
||||||
expected_web_url = 'http://openlp.org/files/frw/'
|
with patch.object(frw, 'restart') as mocked_restart, \
|
||||||
expected_songs_url = 'http://example.com/frw/songs/'
|
patch.object(frw, 'cancel_button') as mocked_cancel_button, \
|
||||||
expected_bibles_url = 'http://example.com/frw/bibles/'
|
patch.object(frw, 'no_internet_finish_button') as mocked_no_internet_finish_btn, \
|
||||||
expected_themes_url = 'http://example.com/frw/themes/'
|
patch.object(frw, 'currentIdChanged') as mocked_currentIdChanged, \
|
||||||
expected_user_agent = 'OpenLP/0.0'
|
patch.object(Registry, 'register_function') as mocked_register_function, \
|
||||||
mocked_get_web_page.return_value.read.return_value = FAKE_CONFIG
|
patch('openlp.core.ui.firsttimeform.Settings') as MockedSettings, \
|
||||||
|
patch('openlp.core.ui.firsttimeform.gettempdir') as mocked_gettempdir, \
|
||||||
|
patch('openlp.core.ui.firsttimeform.check_directory_exists') as mocked_check_directory_exists, \
|
||||||
|
patch.object(frw.application, 'set_normal_cursor') as mocked_set_normal_cursor:
|
||||||
|
mocked_settings = MagicMock()
|
||||||
|
mocked_settings.value.return_value = True
|
||||||
|
MockedSettings.return_value = mocked_settings
|
||||||
|
mocked_gettempdir.return_value = 'temp'
|
||||||
|
expected_temp_path = os.path.join('temp', 'openlp')
|
||||||
|
|
||||||
# WHEN: The First Time Wizard is initialised
|
# WHEN: The set_defaults() method is run
|
||||||
first_time_form.initialize(MagicMock())
|
frw.set_defaults()
|
||||||
|
|
||||||
# THEN: The First Time Form web configuration file should be accessible and parseable
|
# THEN: The default values should have been set
|
||||||
self.assertIsInstance(first_time_form.config, ConfigParser, 'The config object should be a ConfigParser')
|
mocked_restart.assert_called_with()
|
||||||
mocked_get_web_page.assert_called_with(expected_web_url + 'download.cfg',
|
self.assertEqual('http://openlp.org/files/frw/', frw.web, 'The default URL should be set')
|
||||||
header=('User-Agent', expected_user_agent))
|
mocked_cancel_button.clicked.connect.assert_called_with(frw.on_cancel_button_clicked)
|
||||||
self.assertEqual(expected_songs_url, first_time_form.songs_url, 'The songs URL should be correct')
|
mocked_no_internet_finish_btn.clicked.connect.assert_called_with(frw.on_no_internet_finish_button_clicked)
|
||||||
self.assertEqual(expected_bibles_url, first_time_form.bibles_url, 'The bibles URL should be correct')
|
mocked_currentIdChanged.connect.assert_called_with(frw.on_current_id_changed)
|
||||||
self.assertEqual(expected_themes_url, first_time_form.themes_url, 'The themes URL should be correct')
|
mocked_register_function.assert_called_with('config_screen_changed', frw.update_screen_list_combo)
|
||||||
|
mocked_no_internet_finish_btn.setVisible.assert_called_with(False)
|
||||||
|
mocked_settings.value.assert_called_with('core/has run wizard')
|
||||||
|
mocked_gettempdir.assert_called_with()
|
||||||
|
mocked_check_directory_exists.assert_called_with(expected_temp_path)
|
||||||
|
|
||||||
|
def update_screen_list_combo_test(self):
|
||||||
|
"""
|
||||||
|
Test that the update_screen_list_combo() method works correctly
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked Screen() object and an initialised First Run Wizard and a mocked display_combo_box
|
||||||
|
expected_screen_list = ['Screen 1', 'Screen 2']
|
||||||
|
mocked_screens = MagicMock()
|
||||||
|
mocked_screens.get_screen_list.return_value = expected_screen_list
|
||||||
|
frw = FirstTimeForm(None)
|
||||||
|
frw.initialize(mocked_screens)
|
||||||
|
with patch.object(frw, 'display_combo_box') as mocked_display_combo_box:
|
||||||
|
mocked_display_combo_box.count.return_value = 2
|
||||||
|
|
||||||
|
# WHEN: update_screen_list_combo() is called
|
||||||
|
frw.update_screen_list_combo()
|
||||||
|
|
||||||
|
# THEN: The combobox should have been updated
|
||||||
|
mocked_display_combo_box.clear.assert_called_with()
|
||||||
|
mocked_screens.get_screen_list.assert_called_with()
|
||||||
|
mocked_display_combo_box.addItems.assert_called_with(expected_screen_list)
|
||||||
|
mocked_display_combo_box.count.assert_called_with()
|
||||||
|
mocked_display_combo_box.setCurrentIndex.assert_called_with(1)
|
||||||
|
|
||||||
|
def on_cancel_button_clicked_test(self):
|
||||||
|
"""
|
||||||
|
Test that the cancel button click slot shuts down the threads correctly
|
||||||
|
"""
|
||||||
|
# GIVEN: A FRW, some mocked threads and workers (that isn't quite done) and other mocked stuff
|
||||||
|
frw = FirstTimeForm(None)
|
||||||
|
frw.initialize(MagicMock())
|
||||||
|
mocked_worker = MagicMock()
|
||||||
|
mocked_thread = MagicMock()
|
||||||
|
mocked_thread.isRunning.side_effect = [True, False]
|
||||||
|
frw.theme_screenshot_workers.append(mocked_worker)
|
||||||
|
frw.theme_screenshot_threads.append(mocked_thread)
|
||||||
|
with patch('openlp.core.ui.firsttimeform.time') as mocked_time, \
|
||||||
|
patch.object(frw.application, 'set_normal_cursor') as mocked_set_normal_cursor:
|
||||||
|
|
||||||
|
# WHEN: on_cancel_button_clicked() is called
|
||||||
|
frw.on_cancel_button_clicked()
|
||||||
|
|
||||||
|
# THEN: The right things should be called in the right order
|
||||||
|
self.assertTrue(frw.was_cancelled, 'The was_cancelled property should have been set to True')
|
||||||
|
mocked_worker.set_download_canceled.assert_called_with(True)
|
||||||
|
mocked_thread.isRunning.assert_called_with()
|
||||||
|
self.assertEqual(2, mocked_thread.isRunning.call_count, 'isRunning() should have been called twice')
|
||||||
|
mocked_time.sleep.assert_called_with(0.1)
|
||||||
|
self.assertEqual(1, mocked_time.sleep.call_count, 'sleep() should have only been called once')
|
||||||
|
mocked_set_normal_cursor.assert_called_with()
|
||||||
|
|
||||||
def broken_config_test(self):
|
def broken_config_test(self):
|
||||||
"""
|
"""
|
||||||
@ -128,10 +191,11 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
|||||||
# GIVEN: A mocked get_web_page, a First Time Wizard, an expected screen object, and a mocked broken config file
|
# GIVEN: A mocked get_web_page, a First Time Wizard, an expected screen object, and a mocked broken config file
|
||||||
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
|
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
|
||||||
first_time_form = FirstTimeForm(None)
|
first_time_form = FirstTimeForm(None)
|
||||||
|
first_time_form.initialize(MagicMock())
|
||||||
mocked_get_web_page.return_value.read.return_value = FAKE_BROKEN_CONFIG
|
mocked_get_web_page.return_value.read.return_value = FAKE_BROKEN_CONFIG
|
||||||
|
|
||||||
# WHEN: The First Time Wizard is initialised
|
# WHEN: The First Time Wizard is downloads the config file
|
||||||
first_time_form.initialize(MagicMock())
|
first_time_form._download_index()
|
||||||
|
|
||||||
# THEN: The First Time Form should not have web access
|
# THEN: The First Time Form should not have web access
|
||||||
self.assertFalse(first_time_form.web_access, 'There should not be web access with a broken config file')
|
self.assertFalse(first_time_form.web_access, 'There should not be web access with a broken config file')
|
||||||
@ -143,10 +207,11 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
|||||||
# GIVEN: A mocked get_web_page, a First Time Wizard, an expected screen object, and a mocked invalid config file
|
# GIVEN: A mocked get_web_page, a First Time Wizard, an expected screen object, and a mocked invalid config file
|
||||||
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
|
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
|
||||||
first_time_form = FirstTimeForm(None)
|
first_time_form = FirstTimeForm(None)
|
||||||
|
first_time_form.initialize(MagicMock())
|
||||||
mocked_get_web_page.return_value.read.return_value = FAKE_INVALID_CONFIG
|
mocked_get_web_page.return_value.read.return_value = FAKE_INVALID_CONFIG
|
||||||
|
|
||||||
# WHEN: The First Time Wizard is initialised
|
# WHEN: The First Time Wizard is downloads the config file
|
||||||
first_time_form.initialize(MagicMock())
|
first_time_form._download_index()
|
||||||
|
|
||||||
# THEN: The First Time Form should not have web access
|
# THEN: The First Time Form should not have web access
|
||||||
self.assertFalse(first_time_form.web_access, 'There should not be web access with an invalid config file')
|
self.assertFalse(first_time_form.web_access, 'There should not be web access with an invalid config file')
|
||||||
|
@ -382,7 +382,7 @@ class TestUtils(TestCase):
|
|||||||
mocked_page_object = MagicMock()
|
mocked_page_object = MagicMock()
|
||||||
mock_urlopen.return_value = mocked_page_object
|
mock_urlopen.return_value = mocked_page_object
|
||||||
fake_url = 'this://is.a.fake/url'
|
fake_url = 'this://is.a.fake/url'
|
||||||
user_agent_header = ('User-Agent', 'OpenLP/2.1.0')
|
user_agent_header = ('User-Agent', 'OpenLP/2.2.0')
|
||||||
|
|
||||||
# WHEN: The get_web_page() method is called
|
# WHEN: The get_web_page() method is called
|
||||||
returned_page = get_web_page(fake_url, header=user_agent_header)
|
returned_page = get_web_page(fake_url, header=user_agent_header)
|
||||||
|
28
tests/functional/openlp_plugins/custom/__init__.py
Normal file
28
tests/functional/openlp_plugins/custom/__init__.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2014 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||||
|
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
||||||
|
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
||||||
|
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||||
|
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
|
||||||
|
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# 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 #
|
||||||
|
###############################################################################
|
101
tests/functional/openlp_plugins/custom/test_mediaitem.py
Normal file
101
tests/functional/openlp_plugins/custom/test_mediaitem.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
"""
|
||||||
|
This module contains tests for the lib submodule of the Songs plugin.
|
||||||
|
"""
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
from openlp.core.common import Registry, Settings
|
||||||
|
from openlp.core.lib import ServiceItem, PluginStatus
|
||||||
|
from openlp.plugins.custom.lib import CustomMediaItem
|
||||||
|
from openlp.plugins.custom.lib.db import CustomSlide
|
||||||
|
from tests.functional import patch, MagicMock
|
||||||
|
from tests.helpers.testmixin import TestMixin
|
||||||
|
|
||||||
|
FOOTER = ['Arky Arky (Unknown)', 'Public Domain', 'CCLI 123456']
|
||||||
|
|
||||||
|
|
||||||
|
class TestMediaItem(TestCase, TestMixin):
|
||||||
|
"""
|
||||||
|
Test the functions in the :mod:`lib` module.
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
"""
|
||||||
|
Set up the components need for all tests.
|
||||||
|
"""
|
||||||
|
Registry.create()
|
||||||
|
Registry().register('service_list', MagicMock())
|
||||||
|
Registry().register('main_window', MagicMock())
|
||||||
|
with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \
|
||||||
|
patch('openlp.core.lib.mediamanageritem.MediaManagerItem.setup_item'), \
|
||||||
|
patch('openlp.plugins.custom.forms.editcustomform.EditCustomForm.__init__'), \
|
||||||
|
patch('openlp.plugins.custom.lib.mediaitem.CustomMediaItem.setup_item'):
|
||||||
|
self.media_item = CustomMediaItem(None, MagicMock())
|
||||||
|
self.setup_application()
|
||||||
|
self.build_settings()
|
||||||
|
QtCore.QLocale.setDefault(QtCore.QLocale('en_GB'))
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""
|
||||||
|
Delete all the C++ objects at the end so that we don't have a segfault
|
||||||
|
"""
|
||||||
|
self.destroy_settings()
|
||||||
|
|
||||||
|
def service_load_inactive_test(self):
|
||||||
|
"""
|
||||||
|
Test the service load in custom with a default service item
|
||||||
|
"""
|
||||||
|
# GIVEN: An empty Service Item
|
||||||
|
service_item = ServiceItem(None)
|
||||||
|
|
||||||
|
# WHEN: I search for the custom in the database
|
||||||
|
item = self.media_item.service_load(service_item)
|
||||||
|
|
||||||
|
# THEN: the processing should be ignored
|
||||||
|
self.assertEqual(item, None, 'The Service item is inactive so processing should be bypassed')
|
||||||
|
|
||||||
|
def service_load_basic_custom_false_test(self):
|
||||||
|
"""
|
||||||
|
Test the service load in custom with a default service item and no requirement to add to the database
|
||||||
|
"""
|
||||||
|
# GIVEN: An empty Service Item and an active plugin
|
||||||
|
service_item = ServiceItem(None)
|
||||||
|
service_item.raw_footer = FOOTER
|
||||||
|
self.media_item.plugin = MagicMock()
|
||||||
|
self.media_item.plugin.status = PluginStatus.Active
|
||||||
|
self.media_item.plugin.db_manager = MagicMock()
|
||||||
|
self.media_item.plugin.db_manager.get_object_filtered = MagicMock()
|
||||||
|
self.media_item.plugin.db_manager.get_object_filtered.return_value = None
|
||||||
|
|
||||||
|
with patch('openlp.plugins.custom.lib.mediaitem.CustomSlide'):
|
||||||
|
# WHEN: I search for the custom in the database
|
||||||
|
self.media_item.add_custom_from_service = False
|
||||||
|
self.media_item.create_from_service_item = MagicMock()
|
||||||
|
self.media_item.service_load(service_item)
|
||||||
|
|
||||||
|
# THEN: the item should not be added to the database.
|
||||||
|
self.assertEqual(self.media_item.create_from_service_item.call_count, 0,
|
||||||
|
'The item should not have been added to the database')
|
||||||
|
|
||||||
|
def service_load_basic_custom_true_test(self):
|
||||||
|
"""
|
||||||
|
Test the service load in custom with a default service item and a requirement to add to the database
|
||||||
|
"""
|
||||||
|
# GIVEN: An empty Service Item and an active plugin
|
||||||
|
service_item = ServiceItem(None)
|
||||||
|
service_item.raw_footer = FOOTER
|
||||||
|
self.media_item.plugin = MagicMock()
|
||||||
|
self.media_item.plugin.status = PluginStatus.Active
|
||||||
|
self.media_item.plugin.db_manager = MagicMock()
|
||||||
|
self.media_item.plugin.db_manager.get_object_filtered = MagicMock()
|
||||||
|
self.media_item.plugin.db_manager.get_object_filtered.return_value = None
|
||||||
|
|
||||||
|
with patch('openlp.plugins.custom.lib.mediaitem.CustomSlide'):
|
||||||
|
# WHEN: I search for the custom in the database
|
||||||
|
self.media_item.add_custom_from_service = True
|
||||||
|
self.media_item.create_from_service_item = MagicMock()
|
||||||
|
self.media_item.service_load(service_item)
|
||||||
|
|
||||||
|
# THEN: the item should not be added to the database.
|
||||||
|
self.assertEqual(self.media_item.create_from_service_item.call_count, 1,
|
||||||
|
'The item should have been added to the database')
|
57
tests/functional/openlp_plugins/songs/test_editsongform.py
Normal file
57
tests/functional/openlp_plugins/songs/test_editsongform.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"""
|
||||||
|
This module contains tests for the lib submodule of the Songs plugin.
|
||||||
|
"""
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
from openlp.core.common import Registry, Settings
|
||||||
|
from openlp.core.lib import ServiceItem
|
||||||
|
from openlp.plugins.songs.forms.editsongform import EditSongForm
|
||||||
|
from openlp.plugins.songs.lib.db import AuthorType
|
||||||
|
from tests.functional import patch, MagicMock
|
||||||
|
from tests.helpers.testmixin import TestMixin
|
||||||
|
|
||||||
|
|
||||||
|
class TestEditSongForm(TestCase, TestMixin):
|
||||||
|
"""
|
||||||
|
Test the functions in the :mod:`lib` module.
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
"""
|
||||||
|
Set up the components need for all tests.
|
||||||
|
"""
|
||||||
|
Registry.create()
|
||||||
|
Registry().register('service_list', MagicMock())
|
||||||
|
Registry().register('main_window', MagicMock())
|
||||||
|
with patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__', return_value=None):
|
||||||
|
self.edit_song_form = EditSongForm(None, MagicMock(), MagicMock())
|
||||||
|
self.setup_application()
|
||||||
|
self.build_settings()
|
||||||
|
QtCore.QLocale.setDefault(QtCore.QLocale('en_GB'))
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""
|
||||||
|
Delete all the C++ objects at the end so that we don't have a segfault
|
||||||
|
"""
|
||||||
|
self.destroy_settings()
|
||||||
|
|
||||||
|
def validate_matching_tags_test(self):
|
||||||
|
# Given a set of tags
|
||||||
|
tags = ['{r}', '{/r}', '{bl}', '{/bl}', '{su}', '{/su}']
|
||||||
|
|
||||||
|
# WHEN we validate them
|
||||||
|
valid = self.edit_song_form._validate_tags(tags)
|
||||||
|
|
||||||
|
# THEN they should be valid
|
||||||
|
self.assertTrue(valid, "The tags list should be valid")
|
||||||
|
|
||||||
|
def validate_nonmatching_tags_test(self):
|
||||||
|
# Given a set of tags
|
||||||
|
tags = ['{r}', '{/r}', '{bl}', '{/bl}', '{br}', '{su}', '{/su}']
|
||||||
|
|
||||||
|
# WHEN we validate them
|
||||||
|
valid = self.edit_song_form._validate_tags(tags)
|
||||||
|
|
||||||
|
# THEN they should be valid
|
||||||
|
self.assertTrue(valid, "The tags list should be valid")
|
@ -94,11 +94,9 @@ class TestProjectorManager(TestCase, TestMixin):
|
|||||||
self.projector_manager.bootstrap_initialise()
|
self.projector_manager.bootstrap_initialise()
|
||||||
self.projector_manager.bootstrap_post_set_up()
|
self.projector_manager.bootstrap_post_set_up()
|
||||||
|
|
||||||
# THEN: verify calls to retrieve saved projectors
|
# THEN: verify calls to retrieve saved projectors and edit page initialized
|
||||||
self.assertEqual(1, self.projector_manager._load_projectors.call_count,
|
self.assertEqual(1, self.projector_manager._load_projectors.call_count,
|
||||||
'Initialization should have called load_projectors()')
|
'Initialization should have called load_projectors()')
|
||||||
|
|
||||||
# THEN: Verify edit page is initialized
|
|
||||||
self.assertEqual(type(self.projector_manager.projector_form), ProjectorEditForm,
|
self.assertEqual(type(self.projector_manager.projector_form), ProjectorEditForm,
|
||||||
'Initialization should have created a Projector Edit Form')
|
'Initialization should have created a Projector Edit Form')
|
||||||
self.assertIs(self.projector_manager.projectordb,
|
self.assertIs(self.projector_manager.projectordb,
|
||||||
|
79
tests/interfaces/openlp_core_ui/test_projectorsourceform.py
Normal file
79
tests/interfaces/openlp_core_ui/test_projectorsourceform.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2014 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||||
|
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
||||||
|
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
||||||
|
# Christian Richter, Philip Ridout, Ken Roberts, Simon Scudder, #
|
||||||
|
# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||||
|
# Dave Warnock, Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# 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 #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
:mod: `tests.interfaces.openlp_core_ui.test_projectorsourceform` module
|
||||||
|
|
||||||
|
Tests for the Projector Source Select form.
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
log.debug('test_projectorsourceform loaded')
|
||||||
|
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from tests.helpers.testmixin import TestMixin
|
||||||
|
from openlp.core.lib.projector.constants import PJLINK_DEFAULT_CODES, PJLINK_DEFAULT_SOURCES
|
||||||
|
|
||||||
|
from openlp.core.ui.projector.sourceselectform import source_group
|
||||||
|
|
||||||
|
|
||||||
|
def build_source_dict():
|
||||||
|
"""
|
||||||
|
Builds a source dictionary to verify source_group returns a valid dictionary of dictionary items
|
||||||
|
|
||||||
|
:returns: dictionary of valid PJLink source codes grouped by PJLink source group
|
||||||
|
"""
|
||||||
|
test_group = {}
|
||||||
|
for group in PJLINK_DEFAULT_SOURCES.keys():
|
||||||
|
test_group[group] = {}
|
||||||
|
for key in PJLINK_DEFAULT_CODES:
|
||||||
|
test_group[key[0]][key] = PJLINK_DEFAULT_CODES[key]
|
||||||
|
return test_group
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectorSourceFormTest(TestCase, TestMixin):
|
||||||
|
"""
|
||||||
|
Test class for the Projector Source Select form module
|
||||||
|
"""
|
||||||
|
def source_dict_test(self):
|
||||||
|
"""
|
||||||
|
Test that source list dict returned from sourceselectform module is a valid dict with proper entries
|
||||||
|
"""
|
||||||
|
# GIVEN: A list of inputs
|
||||||
|
codes = []
|
||||||
|
for item in PJLINK_DEFAULT_CODES.keys():
|
||||||
|
codes.append(item)
|
||||||
|
codes.sort()
|
||||||
|
|
||||||
|
# WHEN: projector.sourceselectform.source_select() is called
|
||||||
|
check = source_group(codes, PJLINK_DEFAULT_CODES)
|
||||||
|
|
||||||
|
# THEN: return dictionary should match test dictionary
|
||||||
|
self.assertEquals(check, build_source_dict(),
|
||||||
|
"Source group dictionary should match test dictionary")
|
Loading…
Reference in New Issue
Block a user