2011-02-26 11:16:21 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2012-12-29 13:15:42 +00:00
|
|
|
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
2011-02-26 11:16:21 +00:00
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
# OpenLP - Open Source Lyrics Projection #
|
|
|
|
# --------------------------------------------------------------------------- #
|
2013-12-24 08:56:50 +00:00
|
|
|
# Copyright (c) 2008-2014 Raoul Snyman #
|
|
|
|
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
|
2012-06-22 14:14:53 +00:00
|
|
|
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
2012-11-11 21:16:14 +00:00
|
|
|
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
2012-10-21 13:16:22 +00:00
|
|
|
# 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, #
|
2012-12-01 07:57:54 +00:00
|
|
|
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
2011-02-26 11:16:21 +00:00
|
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
# 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 #
|
|
|
|
###############################################################################
|
2013-02-01 20:36:27 +00:00
|
|
|
"""
|
|
|
|
This module contains the first time wizard.
|
|
|
|
"""
|
2011-02-26 15:19:43 +00:00
|
|
|
import logging
|
2011-09-17 22:33:03 +00:00
|
|
|
import os
|
2011-12-29 12:26:37 +00:00
|
|
|
import time
|
2013-07-07 14:41:43 +00:00
|
|
|
import urllib.request
|
|
|
|
import urllib.parse
|
|
|
|
import urllib.error
|
2011-03-10 19:48:15 +00:00
|
|
|
from tempfile import gettempdir
|
2014-11-07 09:32:45 +00:00
|
|
|
from configparser import ConfigParser, MissingSectionHeaderError, NoSectionError, NoOptionError
|
2011-02-26 15:19:43 +00:00
|
|
|
|
2011-02-26 16:51:00 +00:00
|
|
|
from PyQt4 import QtCore, QtGui
|
2011-02-26 11:16:21 +00:00
|
|
|
|
2014-11-01 10:38:33 +00:00
|
|
|
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, \
|
2014-11-06 13:19:00 +00:00
|
|
|
translate, clean_button_text, trace_error_handler
|
2013-12-13 17:44:05 +00:00
|
|
|
from openlp.core.lib import PluginStatus, build_icon
|
2014-11-06 13:19:00 +00:00
|
|
|
from openlp.core.lib.ui import critical_error_message_box
|
2014-11-23 20:52:16 +00:00
|
|
|
from openlp.core.utils import get_web_page, CONNECTION_RETRIES, CONNECTION_TIMEOUT
|
2014-10-22 20:43:05 +00:00
|
|
|
from .firsttimewizard import UiFirstTimeWizard, FirstTimePage
|
2011-02-26 11:16:21 +00:00
|
|
|
|
2011-03-06 19:44:33 +00:00
|
|
|
log = logging.getLogger(__name__)
|
2011-02-26 15:19:43 +00:00
|
|
|
|
2013-02-01 20:36:27 +00:00
|
|
|
|
2014-11-06 21:08:56 +00:00
|
|
|
class ThemeScreenshotWorker(QtCore.QObject):
|
2011-12-29 12:26:37 +00:00
|
|
|
"""
|
2014-11-07 23:46:18 +00:00
|
|
|
This thread downloads a theme's screenshot
|
2011-12-29 12:26:37 +00:00
|
|
|
"""
|
2014-11-06 21:08:56 +00:00
|
|
|
screenshot_downloaded = QtCore.pyqtSignal(str, str)
|
2014-11-07 23:46:18 +00:00
|
|
|
finished = QtCore.pyqtSignal()
|
2014-11-06 21:08:56 +00:00
|
|
|
|
2014-11-07 23:46:18 +00:00
|
|
|
def __init__(self, themes_url, title, filename, screenshot):
|
2014-11-06 21:08:56 +00:00
|
|
|
"""
|
|
|
|
Set up the worker object
|
|
|
|
"""
|
|
|
|
self.was_download_cancelled = False
|
2014-11-07 23:46:18 +00:00
|
|
|
self.themes_url = themes_url
|
|
|
|
self.title = title
|
|
|
|
self.filename = filename
|
|
|
|
self.screenshot = screenshot
|
2014-11-06 21:08:56 +00:00
|
|
|
super(ThemeScreenshotWorker, self).__init__()
|
|
|
|
|
2011-12-29 12:26:37 +00:00
|
|
|
def run(self):
|
2013-02-01 20:36:27 +00:00
|
|
|
"""
|
|
|
|
Overridden method to run the thread.
|
|
|
|
"""
|
2014-11-07 23:46:18 +00:00
|
|
|
if self.was_download_cancelled:
|
|
|
|
return
|
|
|
|
try:
|
|
|
|
urllib.request.urlretrieve('%s%s' % (self.themes_url, self.screenshot),
|
|
|
|
os.path.join(gettempdir(), 'openlp', self.screenshot))
|
2014-11-06 21:08:56 +00:00
|
|
|
# Signal that the screenshot has been downloaded
|
2014-11-07 23:46:18 +00:00
|
|
|
self.screenshot_downloaded.emit(self.title, self.filename)
|
|
|
|
except:
|
|
|
|
log.exception('Unable to download screenshot')
|
|
|
|
finally:
|
|
|
|
self.finished.emit()
|
2014-11-06 21:08:56 +00:00
|
|
|
|
|
|
|
@QtCore.pyqtSlot(bool)
|
|
|
|
def set_download_canceled(self, toggle):
|
|
|
|
"""
|
|
|
|
Externally set if the download was canceled
|
|
|
|
|
|
|
|
:param toggle: Set if the download was canceled or not
|
|
|
|
"""
|
|
|
|
self.was_download_cancelled = toggle
|
2011-12-29 12:26:37 +00:00
|
|
|
|
|
|
|
|
2014-10-22 20:43:05 +00:00
|
|
|
class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
2011-02-26 15:19:43 +00:00
|
|
|
"""
|
2013-05-11 17:28:42 +00:00
|
|
|
This is the Theme Import Wizard, which allows easy creation and editing of OpenLP themes.
|
2011-02-26 15:19:43 +00:00
|
|
|
"""
|
2013-08-31 18:17:38 +00:00
|
|
|
log.info('ThemeWizardForm loaded')
|
2011-02-26 11:16:21 +00:00
|
|
|
|
2014-10-22 20:43:05 +00:00
|
|
|
def __init__(self, parent=None):
|
2013-02-01 20:36:27 +00:00
|
|
|
"""
|
|
|
|
Create and set up the first time wizard.
|
|
|
|
"""
|
|
|
|
super(FirstTimeForm, self).__init__(parent)
|
2014-12-12 20:57:42 +00:00
|
|
|
self.web_access = True
|
|
|
|
self.web = ''
|
2014-10-22 20:43:05 +00:00
|
|
|
self.setup_ui(self)
|
|
|
|
|
2014-11-11 13:58:03 +00:00
|
|
|
def get_next_page_id(self):
|
|
|
|
"""
|
|
|
|
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():
|
2014-11-26 09:04:09 +00:00
|
|
|
print('Go for songs! %r' % self.songs_check_box.isChecked())
|
2014-11-11 13:58:03 +00:00
|
|
|
return FirstTimePage.Songs
|
|
|
|
# The Bibles plugin is enabled
|
|
|
|
elif FirstTimePage.Welcome < self.currentId() < FirstTimePage.Bibles and self.bible_check_box.isChecked():
|
|
|
|
return FirstTimePage.Bibles
|
|
|
|
elif FirstTimePage.Welcome < self.currentId() < FirstTimePage.Themes:
|
|
|
|
return FirstTimePage.Themes
|
|
|
|
else:
|
|
|
|
return self.currentId() + 1
|
|
|
|
|
2014-10-22 20:43:05 +00:00
|
|
|
def nextId(self):
|
|
|
|
"""
|
|
|
|
Determine the next page in the Wizard to go to.
|
|
|
|
"""
|
|
|
|
self.application.process_events()
|
2014-11-07 23:46:18 +00:00
|
|
|
if self.currentId() == FirstTimePage.Download:
|
2014-10-22 20:43:05 +00:00
|
|
|
if not self.web_access:
|
|
|
|
return FirstTimePage.NoInternet
|
|
|
|
else:
|
2014-11-11 13:58:03 +00:00
|
|
|
return self.get_next_page_id()
|
2014-10-22 20:43:05 +00:00
|
|
|
elif self.currentId() == FirstTimePage.Progress:
|
|
|
|
return -1
|
|
|
|
elif self.currentId() == FirstTimePage.NoInternet:
|
|
|
|
return FirstTimePage.Progress
|
|
|
|
elif self.currentId() == FirstTimePage.Themes:
|
|
|
|
self.application.set_busy_cursor()
|
2014-11-07 23:46:18 +00:00
|
|
|
while not all([thread.isFinished() for thread in self.theme_screenshot_threads]):
|
2014-10-22 20:43:05 +00:00
|
|
|
time.sleep(0.1)
|
|
|
|
self.application.process_events()
|
|
|
|
# Build the screenshot icons, as this can not be done in the thread.
|
|
|
|
self._build_theme_screenshots()
|
|
|
|
self.application.set_normal_cursor()
|
|
|
|
return FirstTimePage.Defaults
|
|
|
|
else:
|
2014-11-11 13:58:03 +00:00
|
|
|
return self.get_next_page_id()
|
2014-10-22 20:43:05 +00:00
|
|
|
|
|
|
|
def exec_(self):
|
|
|
|
"""
|
|
|
|
Run the wizard.
|
|
|
|
"""
|
|
|
|
self.set_defaults()
|
|
|
|
return QtGui.QWizard.exec_(self)
|
|
|
|
|
|
|
|
def initialize(self, screens):
|
|
|
|
"""
|
|
|
|
Set up the First Time Wizard
|
|
|
|
|
|
|
|
:param screens: The screens detected by OpenLP
|
|
|
|
"""
|
2011-03-21 08:03:05 +00:00
|
|
|
self.screens = screens
|
2014-11-08 21:15:25 +00:00
|
|
|
self.was_cancelled = False
|
|
|
|
self.theme_screenshot_threads = []
|
|
|
|
self.theme_screenshot_workers = []
|
|
|
|
self.has_run_wizard = False
|
2014-11-07 23:46:18 +00:00
|
|
|
|
|
|
|
def _download_index(self):
|
|
|
|
"""
|
|
|
|
Download the configuration file and kick off the theme screenshot download threads
|
|
|
|
"""
|
2011-02-26 11:16:21 +00:00
|
|
|
# check to see if we have web access
|
2014-11-07 09:32:45 +00:00
|
|
|
self.web_access = False
|
2013-12-20 19:25:42 +00:00
|
|
|
self.config = ConfigParser()
|
|
|
|
user_agent = 'OpenLP/' + Registry().get('application').applicationVersion()
|
2014-11-26 20:02:48 +00:00
|
|
|
self.application.process_events()
|
2014-11-07 09:32:45 +00:00
|
|
|
web_config = get_web_page('%s%s' % (self.web, 'download.cfg'), header=('User-Agent', user_agent))
|
|
|
|
if web_config:
|
|
|
|
files = web_config.read()
|
|
|
|
try:
|
|
|
|
self.config.read_string(files.decode())
|
|
|
|
self.web = self.config.get('general', 'base url')
|
|
|
|
self.songs_url = self.web + self.config.get('songs', 'directory') + '/'
|
|
|
|
self.bibles_url = self.web + self.config.get('bibles', 'directory') + '/'
|
|
|
|
self.themes_url = self.web + self.config.get('themes', 'directory') + '/'
|
|
|
|
self.web_access = True
|
|
|
|
except (NoSectionError, NoOptionError, MissingSectionHeaderError):
|
|
|
|
log.debug('A problem occured while parsing the downloaded config file')
|
|
|
|
trace_error_handler(log)
|
2013-02-07 11:33:47 +00:00
|
|
|
self.update_screen_list_combo()
|
2014-11-26 20:02:48 +00:00
|
|
|
self.application.process_events()
|
2012-12-29 18:13:08 +00:00
|
|
|
self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading %s...')
|
2014-11-26 09:04:09 +00:00
|
|
|
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())
|
|
|
|
self.presentation_check_box.setChecked(self.plugin_manager.get_plugin_by_name('presentations').is_active())
|
|
|
|
self.image_check_box.setChecked(self.plugin_manager.get_plugin_by_name('images').is_active())
|
|
|
|
self.media_check_box.setChecked(self.plugin_manager.get_plugin_by_name('media').is_active())
|
|
|
|
self.remote_check_box.setChecked(self.plugin_manager.get_plugin_by_name('remotes').is_active())
|
|
|
|
self.custom_check_box.setChecked(self.plugin_manager.get_plugin_by_name('custom').is_active())
|
|
|
|
self.song_usage_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songusage').is_active())
|
|
|
|
self.alert_check_box.setChecked(self.plugin_manager.get_plugin_by_name('alerts').is_active())
|
|
|
|
self.application.set_normal_cursor()
|
2011-02-27 14:29:19 +00:00
|
|
|
# Sort out internet access for downloads
|
2013-02-09 14:13:38 +00:00
|
|
|
if self.web_access:
|
2013-08-31 18:17:38 +00:00
|
|
|
songs = self.config.get('songs', 'languages')
|
|
|
|
songs = songs.split(',')
|
2011-03-10 13:15:49 +00:00
|
|
|
for song in songs:
|
2014-11-26 20:02:48 +00:00
|
|
|
self.application.process_events()
|
2013-08-31 18:17:38 +00:00
|
|
|
title = self.config.get('songs_%s' % song, 'title')
|
|
|
|
filename = self.config.get('songs_%s' % song, 'filename')
|
2013-05-11 17:41:26 +00:00
|
|
|
item = QtGui.QListWidgetItem(title, self.songs_list_widget)
|
2012-05-17 15:13:09 +00:00
|
|
|
item.setData(QtCore.Qt.UserRole, filename)
|
2011-03-10 13:15:49 +00:00
|
|
|
item.setCheckState(QtCore.Qt.Unchecked)
|
|
|
|
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
2013-08-31 18:17:38 +00:00
|
|
|
bible_languages = self.config.get('bibles', 'languages')
|
|
|
|
bible_languages = bible_languages.split(',')
|
2011-03-10 19:48:15 +00:00
|
|
|
for lang in bible_languages:
|
2014-11-26 20:02:48 +00:00
|
|
|
self.application.process_events()
|
2013-08-31 18:17:38 +00:00
|
|
|
language = self.config.get('bibles_%s' % lang, 'title')
|
2013-12-24 15:55:01 +00:00
|
|
|
lang_item = QtGui.QTreeWidgetItem(self.bibles_tree_widget, [language])
|
2013-08-31 18:17:38 +00:00
|
|
|
bibles = self.config.get('bibles_%s' % lang, 'translations')
|
|
|
|
bibles = bibles.split(',')
|
2011-03-10 13:15:49 +00:00
|
|
|
for bible in bibles:
|
2014-11-26 20:02:48 +00:00
|
|
|
self.application.process_events()
|
2013-08-31 18:17:38 +00:00
|
|
|
title = self.config.get('bible_%s' % bible, 'title')
|
|
|
|
filename = self.config.get('bible_%s' % bible, 'filename')
|
2013-12-24 15:55:01 +00:00
|
|
|
item = QtGui.QTreeWidgetItem(lang_item, [title])
|
2012-05-17 15:13:09 +00:00
|
|
|
item.setData(0, QtCore.Qt.UserRole, filename)
|
2011-03-10 13:15:49 +00:00
|
|
|
item.setCheckState(0, QtCore.Qt.Unchecked)
|
|
|
|
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
2013-05-11 17:41:26 +00:00
|
|
|
self.bibles_tree_widget.expandAll()
|
2014-11-26 20:02:48 +00:00
|
|
|
self.application.process_events()
|
2014-11-07 23:46:18 +00:00
|
|
|
# Download the theme screenshots
|
|
|
|
themes = self.config.get('themes', 'files').split(',')
|
|
|
|
for theme in themes:
|
2014-11-26 20:02:48 +00:00
|
|
|
self.application.process_events()
|
2014-11-07 23:46:18 +00:00
|
|
|
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'))
|
2011-02-26 20:52:26 +00:00
|
|
|
|
2014-10-22 20:43:05 +00:00
|
|
|
def update_screen_list_combo(self):
|
2011-03-09 17:37:25 +00:00
|
|
|
"""
|
2014-10-22 20:43:05 +00:00
|
|
|
The user changed screen resolution or enabled/disabled more screens, so
|
|
|
|
we need to update the combo box.
|
2011-03-09 17:37:25 +00:00
|
|
|
"""
|
2014-10-22 20:43:05 +00:00
|
|
|
self.display_combo_box.clear()
|
|
|
|
self.display_combo_box.addItems(self.screens.get_screen_list())
|
|
|
|
self.display_combo_box.setCurrentIndex(self.display_combo_box.count() - 1)
|
2011-03-09 17:37:25 +00:00
|
|
|
|
2013-05-11 17:41:26 +00:00
|
|
|
def on_current_id_changed(self, page_id):
|
2011-03-02 21:47:55 +00:00
|
|
|
"""
|
2012-10-12 18:51:47 +00:00
|
|
|
Detects Page changes and updates as appropriate.
|
2011-03-02 21:47:55 +00:00
|
|
|
"""
|
2013-05-11 17:41:26 +00:00
|
|
|
# Keep track of the page we are at. Triggering "Cancel" causes page_id to be a -1.
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.process_events()
|
2013-05-11 17:41:26 +00:00
|
|
|
if page_id != -1:
|
|
|
|
self.last_id = page_id
|
2014-11-07 23:46:18 +00:00
|
|
|
if page_id == FirstTimePage.Download:
|
|
|
|
self.back_button.setVisible(False)
|
|
|
|
self.next_button.setVisible(False)
|
2011-09-13 00:13:12 +00:00
|
|
|
# Set the no internet page text.
|
2013-05-11 17:41:26 +00:00
|
|
|
if self.has_run_wizard:
|
|
|
|
self.no_internet_label.setText(self.no_internet_text)
|
2011-09-13 00:13:12 +00:00
|
|
|
else:
|
2014-10-22 21:01:40 +00:00
|
|
|
self.no_internet_label.setText(self.no_internet_text + self.cancel_wizard_text)
|
2014-11-07 23:46:18 +00:00
|
|
|
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()
|
2013-05-11 17:41:26 +00:00
|
|
|
elif page_id == FirstTimePage.Defaults:
|
|
|
|
self.theme_combo_box.clear()
|
2014-05-01 17:49:43 +00:00
|
|
|
for index in range(self.themes_list_widget.count()):
|
|
|
|
item = self.themes_list_widget.item(index)
|
2011-03-10 19:48:15 +00:00
|
|
|
if item.checkState() == QtCore.Qt.Checked:
|
2013-05-11 17:41:26 +00:00
|
|
|
self.theme_combo_box.addItem(item.text())
|
|
|
|
if self.has_run_wizard:
|
2011-08-03 13:19:43 +00:00
|
|
|
# Add any existing themes to list.
|
2013-02-02 07:34:42 +00:00
|
|
|
for theme in self.theme_manager.get_themes():
|
2013-05-11 17:41:26 +00:00
|
|
|
index = self.theme_combo_box.findText(theme)
|
2011-08-02 01:58:10 +00:00
|
|
|
if index == -1:
|
2013-05-11 17:41:26 +00:00
|
|
|
self.theme_combo_box.addItem(theme)
|
2013-08-31 18:17:38 +00:00
|
|
|
default_theme = Settings().value('themes/global theme')
|
2011-08-03 13:19:43 +00:00
|
|
|
# Pre-select the current default theme.
|
2013-05-11 17:41:26 +00:00
|
|
|
index = self.theme_combo_box.findText(default_theme)
|
|
|
|
self.theme_combo_box.setCurrentIndex(index)
|
|
|
|
elif page_id == FirstTimePage.NoInternet:
|
|
|
|
self.back_button.setVisible(False)
|
|
|
|
self.next_button.setVisible(False)
|
2014-11-07 23:46:18 +00:00
|
|
|
self.cancel_button.setVisible(False)
|
2013-05-11 17:28:42 +00:00
|
|
|
self.no_internet_finish_button.setVisible(True)
|
2014-11-26 20:02:48 +00:00
|
|
|
elif page_id == FirstTimePage.Plugins:
|
|
|
|
self.back_button.setVisible(False)
|
2013-05-11 17:41:26 +00:00
|
|
|
elif page_id == FirstTimePage.Progress:
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_busy_cursor()
|
2013-04-29 18:42:29 +00:00
|
|
|
self._pre_wizard()
|
2013-05-11 18:11:52 +00:00
|
|
|
self._perform_wizard()
|
2013-03-14 22:22:18 +00:00
|
|
|
self._post_wizard()
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_normal_cursor()
|
2011-03-02 21:47:55 +00:00
|
|
|
|
2013-05-11 18:11:52 +00:00
|
|
|
def on_cancel_button_clicked(self):
|
2011-09-13 00:13:12 +00:00
|
|
|
"""
|
2012-04-02 00:19:16 +00:00
|
|
|
Process the triggering of the cancel button.
|
2011-09-13 00:13:12 +00:00
|
|
|
"""
|
2014-11-08 21:15:25 +00:00
|
|
|
self.was_cancelled = True
|
2014-11-07 23:46:18 +00:00
|
|
|
if self.theme_screenshot_workers:
|
|
|
|
for worker in self.theme_screenshot_workers:
|
|
|
|
worker.set_download_canceled(True)
|
2013-04-28 18:31:48 +00:00
|
|
|
# Was the thread created.
|
2014-11-07 23:46:18 +00:00
|
|
|
if self.theme_screenshot_threads:
|
|
|
|
while any([thread.isRunning() for thread in self.theme_screenshot_threads]):
|
2013-04-28 18:31:48 +00:00
|
|
|
time.sleep(0.1)
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_normal_cursor()
|
2011-09-08 13:14:51 +00:00
|
|
|
|
2014-11-06 21:08:56 +00:00
|
|
|
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)
|
|
|
|
|
2013-05-11 18:11:52 +00:00
|
|
|
def on_no_internet_finish_button_clicked(self):
|
2011-09-13 00:13:12 +00:00
|
|
|
"""
|
2012-04-02 00:19:16 +00:00
|
|
|
Process the triggering of the "Finish" button on the No Internet page.
|
2011-09-13 00:13:12 +00:00
|
|
|
"""
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_busy_cursor()
|
2013-05-11 18:11:52 +00:00
|
|
|
self._perform_wizard()
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.set_normal_cursor()
|
2013-08-31 18:17:38 +00:00
|
|
|
Settings().setValue('core/has run wizard', True)
|
2011-09-13 00:13:12 +00:00
|
|
|
self.close()
|
|
|
|
|
2013-05-11 18:11:52 +00:00
|
|
|
def url_get_file(self, url, f_path):
|
2011-09-08 13:14:51 +00:00
|
|
|
""""
|
2013-05-11 18:11:52 +00:00
|
|
|
Download a file given a URL. The file is retrieved in chunks, giving the ability to cancel the download at any
|
2014-11-06 13:19:00 +00:00
|
|
|
point. Returns False on download error.
|
|
|
|
|
|
|
|
:param url: URL to download
|
|
|
|
:param f_path: Destination file
|
2011-09-08 13:14:51 +00:00
|
|
|
"""
|
|
|
|
block_count = 0
|
|
|
|
block_size = 4096
|
2014-11-23 20:52:16 +00:00
|
|
|
retries = 0
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
url_file = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
|
|
|
|
filename = open(f_path, "wb")
|
|
|
|
# Download until finished or canceled.
|
2014-12-12 20:57:42 +00:00
|
|
|
while not self.was_cancelled:
|
2014-11-23 20:52:16 +00:00
|
|
|
data = url_file.read(block_size)
|
|
|
|
if not data:
|
|
|
|
break
|
|
|
|
filename.write(data)
|
|
|
|
block_count += 1
|
|
|
|
self._download_progress(block_count, block_size)
|
|
|
|
filename.close()
|
|
|
|
except ConnectionError:
|
|
|
|
trace_error_handler(log)
|
|
|
|
filename.close()
|
|
|
|
os.remove(f_path)
|
|
|
|
if retries > CONNECTION_RETRIES:
|
|
|
|
return False
|
|
|
|
else:
|
|
|
|
retries += 1
|
2014-11-24 19:38:15 +00:00
|
|
|
time.sleep(0.1)
|
2014-11-23 20:52:16 +00:00
|
|
|
continue
|
|
|
|
break
|
2012-05-26 16:52:34 +00:00
|
|
|
# Delete file if cancelled, it may be a partial file.
|
2014-11-08 21:15:25 +00:00
|
|
|
if self.was_cancelled:
|
2013-05-11 18:11:52 +00:00
|
|
|
os.remove(f_path)
|
2014-11-06 13:19:00 +00:00
|
|
|
return True
|
2011-09-08 13:14:51 +00:00
|
|
|
|
2013-05-11 18:11:52 +00:00
|
|
|
def _build_theme_screenshots(self):
|
2011-12-29 12:26:37 +00:00
|
|
|
"""
|
2014-03-17 19:05:55 +00:00
|
|
|
This method builds the theme screenshots' icons for all items in the ``self.themes_list_widget``.
|
2011-12-29 12:26:37 +00:00
|
|
|
"""
|
2013-08-31 18:17:38 +00:00
|
|
|
themes = self.config.get('themes', 'files')
|
|
|
|
themes = themes.split(',')
|
2014-05-01 17:49:43 +00:00
|
|
|
for index, theme in enumerate(themes):
|
2013-08-31 18:17:38 +00:00
|
|
|
screenshot = self.config.get('theme_%s' % theme, 'screenshot')
|
2014-05-01 17:49:43 +00:00
|
|
|
item = self.themes_list_widget.item(index)
|
2013-08-31 18:17:38 +00:00
|
|
|
item.setIcon(build_icon(os.path.join(gettempdir(), 'openlp', screenshot)))
|
2011-12-29 12:26:37 +00:00
|
|
|
|
2014-03-17 19:05:55 +00:00
|
|
|
def _get_file_size(self, url):
|
2013-02-01 20:36:27 +00:00
|
|
|
"""
|
|
|
|
Get the size of a file.
|
|
|
|
|
2014-03-17 19:05:55 +00:00
|
|
|
:param url: The URL of the file we want to download.
|
2013-02-01 20:36:27 +00:00
|
|
|
"""
|
2014-11-23 20:52:16 +00:00
|
|
|
retries = 0
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
site = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
|
|
|
|
meta = site.info()
|
|
|
|
return int(meta.get("Content-Length"))
|
|
|
|
except ConnectionException:
|
|
|
|
if retries > CONNECTION_RETRIES:
|
|
|
|
raise
|
|
|
|
else:
|
|
|
|
retries += 1
|
2014-11-24 19:38:15 +00:00
|
|
|
time.sleep(0.1)
|
2014-11-23 20:52:16 +00:00
|
|
|
continue
|
2011-03-17 13:03:57 +00:00
|
|
|
|
2013-05-11 18:11:52 +00:00
|
|
|
def _download_progress(self, count, block_size):
|
2013-02-01 20:36:27 +00:00
|
|
|
"""
|
|
|
|
Calculate and display the download progress.
|
|
|
|
"""
|
2011-03-17 13:03:57 +00:00
|
|
|
increment = (count * block_size) - self.previous_size
|
2013-04-29 18:42:29 +00:00
|
|
|
self._increment_progress_bar(None, increment)
|
2011-03-17 13:03:57 +00:00
|
|
|
self.previous_size = count * block_size
|
2011-12-29 12:26:37 +00:00
|
|
|
|
2013-04-29 18:42:29 +00:00
|
|
|
def _increment_progress_bar(self, status_text, increment=1):
|
2011-03-11 10:20:09 +00:00
|
|
|
"""
|
|
|
|
Update the wizard progress page.
|
|
|
|
|
2014-03-17 19:05:55 +00:00
|
|
|
:param status_text: Current status information to display.
|
|
|
|
:param increment: The value to increment the progress bar by.
|
2011-03-11 10:20:09 +00:00
|
|
|
"""
|
|
|
|
if status_text:
|
2013-05-11 17:41:26 +00:00
|
|
|
self.progress_label.setText(status_text)
|
2011-03-11 10:20:09 +00:00
|
|
|
if increment > 0:
|
2013-05-11 17:41:26 +00:00
|
|
|
self.progress_bar.setValue(self.progress_bar.value() + increment)
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.process_events()
|
2011-03-11 10:20:09 +00:00
|
|
|
|
2013-04-29 18:42:29 +00:00
|
|
|
def _pre_wizard(self):
|
2011-03-11 10:20:09 +00:00
|
|
|
"""
|
|
|
|
Prepare the UI for the process.
|
|
|
|
"""
|
2011-06-09 22:03:30 +00:00
|
|
|
self.max_progress = 0
|
2013-05-11 17:41:26 +00:00
|
|
|
self.finish_button.setVisible(False)
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.process_events()
|
2014-11-06 13:19:00 +00:00
|
|
|
try:
|
|
|
|
# Loop through the songs list and increase for each selected item
|
|
|
|
for i in range(self.songs_list_widget.count()):
|
|
|
|
self.application.process_events()
|
|
|
|
item = self.songs_list_widget.item(i)
|
|
|
|
if item.checkState() == QtCore.Qt.Checked:
|
|
|
|
filename = item.data(QtCore.Qt.UserRole)
|
|
|
|
size = self._get_file_size('%s%s' % (self.songs_url, filename))
|
|
|
|
self.max_progress += size
|
|
|
|
# Loop through the Bibles list and increase for each selected item
|
|
|
|
iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
|
|
|
while iterator.value():
|
|
|
|
self.application.process_events()
|
|
|
|
item = iterator.value()
|
|
|
|
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
|
|
|
filename = item.data(0, QtCore.Qt.UserRole)
|
|
|
|
size = self._get_file_size('%s%s' % (self.bibles_url, filename))
|
|
|
|
self.max_progress += size
|
|
|
|
iterator += 1
|
|
|
|
# Loop through the themes list and increase for each selected item
|
|
|
|
for i in range(self.themes_list_widget.count()):
|
|
|
|
self.application.process_events()
|
|
|
|
item = self.themes_list_widget.item(i)
|
|
|
|
if item.checkState() == QtCore.Qt.Checked:
|
|
|
|
filename = item.data(QtCore.Qt.UserRole)
|
|
|
|
size = self._get_file_size('%s%s' % (self.themes_url, filename))
|
|
|
|
self.max_progress += size
|
2014-11-07 09:32:45 +00:00
|
|
|
except ConnectionError:
|
2014-11-06 13:19:00 +00:00
|
|
|
trace_error_handler(log)
|
|
|
|
critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'),
|
|
|
|
translate('OpenLP.FirstTimeWizard', 'There was a connection problem during '
|
|
|
|
'download, so further downloads will be skipped. Try to re-run the '
|
|
|
|
'First Time Wizard later.'))
|
|
|
|
self.max_progress = 0
|
|
|
|
self.web_access = None
|
2011-06-09 22:03:30 +00:00
|
|
|
if self.max_progress:
|
|
|
|
# Add on 2 for plugins status setting plus a "finished" point.
|
2013-02-04 21:26:27 +00:00
|
|
|
self.max_progress += 2
|
2013-05-11 17:41:26 +00:00
|
|
|
self.progress_bar.setValue(0)
|
|
|
|
self.progress_bar.setMinimum(0)
|
|
|
|
self.progress_bar.setMaximum(self.max_progress)
|
|
|
|
self.progress_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up And Downloading'))
|
|
|
|
self.progress_page.setSubTitle(
|
2012-12-29 13:15:42 +00:00
|
|
|
translate('OpenLP.FirstTimeWizard', 'Please wait while OpenLP is set up and your data is downloaded.'))
|
2011-06-09 22:03:30 +00:00
|
|
|
else:
|
2013-05-11 17:41:26 +00:00
|
|
|
self.progress_bar.setVisible(False)
|
|
|
|
self.progress_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up'))
|
2013-08-31 18:17:38 +00:00
|
|
|
self.progress_page.setSubTitle('Setup complete.')
|
2012-10-13 17:05:55 +00:00
|
|
|
self.repaint()
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.process_events()
|
2012-10-13 17:05:55 +00:00
|
|
|
# Try to give the wizard a chance to repaint itself
|
|
|
|
time.sleep(0.1)
|
2011-03-11 10:20:09 +00:00
|
|
|
|
2013-03-14 22:22:18 +00:00
|
|
|
def _post_wizard(self):
|
2011-03-11 10:20:09 +00:00
|
|
|
"""
|
|
|
|
Clean up the UI after the process has finished.
|
|
|
|
"""
|
2011-06-09 22:03:30 +00:00
|
|
|
if self.max_progress:
|
2013-05-11 17:41:26 +00:00
|
|
|
self.progress_bar.setValue(self.progress_bar.maximum())
|
|
|
|
if self.has_run_wizard:
|
|
|
|
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
2014-08-22 22:12:35 +00:00
|
|
|
'Download complete. Click the %s button to return to OpenLP.') %
|
2014-11-01 10:35:54 +00:00
|
|
|
clean_button_text(self.buttonText(QtGui.QWizard.FinishButton)))
|
2011-08-02 01:58:10 +00:00
|
|
|
else:
|
2013-05-11 17:41:26 +00:00
|
|
|
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
2014-08-22 22:12:35 +00:00
|
|
|
'Download complete. Click the %s button to start OpenLP.') %
|
2014-11-01 10:35:54 +00:00
|
|
|
clean_button_text(self.buttonText(QtGui.QWizard.FinishButton)))
|
2011-06-09 22:03:30 +00:00
|
|
|
else:
|
2013-05-11 17:41:26 +00:00
|
|
|
if self.has_run_wizard:
|
|
|
|
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
2014-08-22 22:12:35 +00:00
|
|
|
'Click the %s button to return to OpenLP.') %
|
2014-11-01 10:35:54 +00:00
|
|
|
clean_button_text(self.buttonText(QtGui.QWizard.FinishButton)))
|
2011-08-02 01:58:10 +00:00
|
|
|
else:
|
2013-05-11 17:41:26 +00:00
|
|
|
self.progress_label.setText(translate('OpenLP.FirstTimeWizard',
|
2014-08-22 22:12:35 +00:00
|
|
|
'Click the %s button to start OpenLP.') %
|
2014-11-01 10:35:54 +00:00
|
|
|
clean_button_text(self.buttonText(QtGui.QWizard.FinishButton)))
|
2013-05-11 17:41:26 +00:00
|
|
|
self.finish_button.setVisible(True)
|
|
|
|
self.finish_button.setEnabled(True)
|
2013-05-11 17:28:42 +00:00
|
|
|
self.cancel_button.setVisible(False)
|
2013-05-11 17:41:26 +00:00
|
|
|
self.next_button.setVisible(False)
|
2013-02-03 19:23:12 +00:00
|
|
|
self.application.process_events()
|
2011-03-11 10:20:09 +00:00
|
|
|
|
2013-05-11 18:11:52 +00:00
|
|
|
def _perform_wizard(self):
|
2011-03-11 10:20:09 +00:00
|
|
|
"""
|
|
|
|
Run the tasks in the wizard.
|
|
|
|
"""
|
|
|
|
# Set plugin states
|
2013-04-29 18:42:29 +00:00
|
|
|
self._increment_progress_bar(translate('OpenLP.FirstTimeWizard', 'Enabling selected plugins...'))
|
2013-08-31 18:17:38 +00:00
|
|
|
self._set_plugin_status(self.songs_check_box, 'songs/status')
|
|
|
|
self._set_plugin_status(self.bible_check_box, 'bibles/status')
|
2014-05-30 09:21:26 +00:00
|
|
|
self._set_plugin_status(self.presentation_check_box, 'presentations/status')
|
2013-08-31 18:17:38 +00:00
|
|
|
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.remote_check_box, 'remotes/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')
|
2013-02-09 14:13:38 +00:00
|
|
|
if self.web_access:
|
2014-11-06 13:19:00 +00:00
|
|
|
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.'))
|
2011-03-06 13:44:35 +00:00
|
|
|
# Set Default Display
|
2013-05-11 17:41:26 +00:00
|
|
|
if self.display_combo_box.currentIndex() != -1:
|
2013-08-31 18:17:38 +00:00
|
|
|
Settings().setValue('core/monitor', self.display_combo_box.currentIndex())
|
2013-05-11 17:41:26 +00:00
|
|
|
self.screens.set_current_display(self.display_combo_box.currentIndex())
|
2011-03-06 13:44:35 +00:00
|
|
|
# Set Global Theme
|
2013-05-11 17:41:26 +00:00
|
|
|
if self.theme_combo_box.currentIndex() != -1:
|
2013-08-31 18:17:38 +00:00
|
|
|
Settings().setValue('themes/global theme', self.theme_combo_box.currentText())
|
2011-02-26 16:51:00 +00:00
|
|
|
|
2014-11-06 13:19:00 +00:00
|
|
|
def _download_selected(self):
|
|
|
|
"""
|
|
|
|
Download selected songs, bibles and themes. Returns False on download error
|
|
|
|
"""
|
|
|
|
# Build directories for downloads
|
|
|
|
songs_destination = os.path.join(gettempdir(), 'openlp')
|
|
|
|
bibles_destination = AppLocation.get_section_data_path('bibles')
|
|
|
|
themes_destination = AppLocation.get_section_data_path('themes')
|
|
|
|
# Download songs
|
|
|
|
for i in range(self.songs_list_widget.count()):
|
|
|
|
item = self.songs_list_widget.item(i)
|
|
|
|
if item.checkState() == QtCore.Qt.Checked:
|
|
|
|
filename = item.data(QtCore.Qt.UserRole)
|
|
|
|
self._increment_progress_bar(self.downloading % filename, 0)
|
|
|
|
self.previous_size = 0
|
|
|
|
destination = os.path.join(songs_destination, str(filename))
|
|
|
|
if not self.url_get_file('%s%s' % (self.songs_url, filename), destination):
|
|
|
|
return False
|
|
|
|
# Download Bibles
|
|
|
|
bibles_iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
|
|
|
while bibles_iterator.value():
|
|
|
|
item = bibles_iterator.value()
|
|
|
|
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
|
|
|
bible = item.data(0, QtCore.Qt.UserRole)
|
|
|
|
self._increment_progress_bar(self.downloading % bible, 0)
|
|
|
|
self.previous_size = 0
|
|
|
|
if not self.url_get_file('%s%s' % (self.bibles_url, bible), os.path.join(bibles_destination, bible)):
|
|
|
|
return False
|
|
|
|
bibles_iterator += 1
|
|
|
|
# Download themes
|
|
|
|
for i in range(self.themes_list_widget.count()):
|
|
|
|
item = self.themes_list_widget.item(i)
|
|
|
|
if item.checkState() == QtCore.Qt.Checked:
|
|
|
|
theme = item.data(QtCore.Qt.UserRole)
|
|
|
|
self._increment_progress_bar(self.downloading % theme, 0)
|
|
|
|
self.previous_size = 0
|
|
|
|
if not self.url_get_file('%s%s' % (self.themes_url, theme), os.path.join(themes_destination, theme)):
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2013-05-11 18:11:52 +00:00
|
|
|
def _set_plugin_status(self, field, tag):
|
2013-02-01 20:36:27 +00:00
|
|
|
"""
|
|
|
|
Set the status of a plugin.
|
|
|
|
"""
|
2012-12-29 13:15:42 +00:00
|
|
|
status = PluginStatus.Active if field.checkState() == QtCore.Qt.Checked else PluginStatus.Inactive
|
2014-03-20 19:10:31 +00:00
|
|
|
Settings().setValue(tag, status)
|