openlp/openlp/core/ui/wizard.py

318 lines
13 KiB
Python
Raw Normal View History

2011-01-13 17:55:29 +00:00
# -*- coding: utf-8 -*-
2012-12-29 15:25:29 +00:00
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
2011-01-13 17:55:29 +00:00
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2012-12-29 20:56:56 +00:00
# Copyright (c) 2008-2013 Raoul Snyman #
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
# 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, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
2011-01-13 17:55:29 +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 #
###############################################################################
"""
The :mod:``wizard`` module provides generic wizard tools for OpenLP.
"""
import logging
2011-02-10 21:07:28 +00:00
import os
2011-01-13 17:55:29 +00:00
from PyQt4 import QtCore, QtGui
2013-02-05 08:05:28 +00:00
from openlp.core.lib import Receiver, Registry, Settings, UiStrings, build_icon, translate
from openlp.core.lib.ui import add_welcome_page
2011-01-13 17:55:29 +00:00
log = logging.getLogger(__name__)
2013-02-01 21:34:23 +00:00
2011-02-12 02:43:13 +00:00
class WizardStrings(object):
"""
Provide standard strings for wizards to use.
"""
2011-02-12 20:25:40 +00:00
# Applications/Formats we import from or export to. These get used in
# multiple places but do not need translating unless you find evidence of
# the writers translating their own product name.
CSV = u'CSV'
OS = u'OpenSong'
OSIS = u'OSIS'
2011-02-12 02:43:13 +00:00
# These strings should need a good reason to be retranslated elsewhere.
FinishedImport = translate('OpenLP.Ui', 'Finished import.')
2011-02-12 02:43:13 +00:00
FormatLabel = translate('OpenLP.Ui', 'Format:')
HeaderStyle = u'<span style="font-size:14pt; font-weight:600;">%s</span>'
2011-02-12 15:37:02 +00:00
Importing = translate('OpenLP.Ui', 'Importing')
2012-05-17 18:57:01 +00:00
ImportingType = translate('OpenLP.Ui', 'Importing "%s"...')
2011-02-12 02:43:13 +00:00
ImportSelect = translate('OpenLP.Ui', 'Select Import Source')
2012-05-17 18:57:01 +00:00
ImportSelectLong = translate('OpenLP.Ui',
'Select the import format and the location to import from.')
2011-02-13 01:09:04 +00:00
NoSqlite = translate('OpenLP.Ui', 'The openlp.org 1.x importer has been '
'disabled due to a missing Python module. If you want to use this '
2012-12-29 15:25:29 +00:00
'importer, you will need to install the "python-sqlite" module.')
2012-05-17 18:57:01 +00:00
OpenTypeFile = translate('OpenLP.Ui', 'Open %s File')
2012-10-03 16:38:06 +00:00
OpenTypeFolder = translate('OpenLP.Ui', 'Open %s Folder')
2012-05-17 18:57:01 +00:00
PercentSymbolFormat = translate('OpenLP.Ui', '%p%')
2011-02-13 01:09:04 +00:00
Ready = translate('OpenLP.Ui', 'Ready.')
StartingImport = translate('OpenLP.Ui', 'Starting import...')
2012-10-03 16:38:06 +00:00
YouSpecifyFile = translate('OpenLP.Ui', 'You need to specify one '
'%s file to import from.', 'A file type e.g. OpenSong')
YouSpecifyFiles = translate('OpenLP.Ui', 'You need to specify at '
2012-05-17 18:57:01 +00:00
'least one %s file to import from.', 'A file type e.g. OpenSong')
2012-10-03 16:38:06 +00:00
YouSpecifyFolder = translate('OpenLP.Ui', 'You need to specify one '
'%s folder to import from.', 'A song format e.g. PowerSong')
2011-02-12 02:43:13 +00:00
2011-01-13 17:55:29 +00:00
class OpenLPWizard(QtGui.QWizard):
"""
Generic OpenLP wizard to provide generic functionality and a unified look
and feel.
2013-01-22 21:35:53 +00:00
``parent``
The QWidget-derived parent of the wizard.
``plugin``
Plugin this wizard is part of. The plugin will be saved in the "plugin" variable.
The plugin will also be used as basis for the file dialog methods this class provides.
``name``
The object name this wizard should have.
``image``
The image to display on the "welcome" page of the wizard. Should be 163x350.
``addProgressPage``
Whether to add a progress page with a progressbar at the end of the wizard.
2011-01-13 17:55:29 +00:00
"""
def __init__(self, parent, plugin, name, image, addProgressPage=True):
2013-02-01 21:34:23 +00:00
"""
Constructor
"""
2011-01-13 17:55:29 +00:00
QtGui.QWizard.__init__(self, parent)
2011-02-12 02:43:13 +00:00
self.plugin = plugin
self.withProgressPage = addProgressPage
2011-01-13 17:55:29 +00:00
self.setObjectName(name)
self.openIcon = build_icon(u':/general/general_open.png')
self.deleteIcon = build_icon(u':/general/general_delete.png')
self.finishButton = self.button(QtGui.QWizard.FinishButton)
self.cancelButton = self.button(QtGui.QWizard.CancelButton)
self.setupUi(image)
self.registerFields()
self.customInit()
self.customSignals()
2012-12-29 15:25:29 +00:00
QtCore.QObject.connect(self, QtCore.SIGNAL(u'currentIdChanged(int)'), self.onCurrentIdChanged)
if self.withProgressPage:
QtCore.QObject.connect(self.errorCopyToButton, QtCore.SIGNAL(u'clicked()'), self.onErrorCopyToButtonClicked)
QtCore.QObject.connect(self.errorSaveToButton, QtCore.SIGNAL(u'clicked()'), self.onErrorSaveToButtonClicked)
2011-01-13 17:55:29 +00:00
def setupUi(self, image):
"""
2012-06-01 07:32:58 +00:00
Set up the wizard UI.
2011-01-13 17:55:29 +00:00
"""
self.setModal(True)
self.setWizardStyle(QtGui.QWizard.ModernStyle)
self.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.NoBackButtonOnLastPage)
add_welcome_page(self, image)
2011-01-13 17:55:29 +00:00
self.addCustomPages()
if self.withProgressPage:
self.addProgressPage()
2011-01-13 17:55:29 +00:00
self.retranslateUi()
2011-02-10 19:28:17 +00:00
def registerFields(self):
"""
Hook method for wizards to register any fields they need.
"""
pass
2011-01-13 17:55:29 +00:00
def addProgressPage(self):
"""
2011-01-18 18:53:09 +00:00
Add the progress page for the wizard. This page informs the user how
2011-01-13 17:55:29 +00:00
the wizard is progressing with its task.
"""
self.progressPage = QtGui.QWizardPage()
self.progressPage.setObjectName(u'progressPage')
self.progressLayout = QtGui.QVBoxLayout(self.progressPage)
self.progressLayout.setMargin(48)
self.progressLayout.setObjectName(u'progressLayout')
self.progressLabel = QtGui.QLabel(self.progressPage)
self.progressLabel.setObjectName(u'progressLabel')
self.progressLabel.setWordWrap(True)
2011-01-13 17:55:29 +00:00
self.progressLayout.addWidget(self.progressLabel)
self.progressBar = QtGui.QProgressBar(self.progressPage)
self.progressBar.setObjectName(u'progressBar')
self.progressLayout.addWidget(self.progressBar)
# Add a QTextEdit and a copy to file and copy to clipboard button to be
# able to provide feedback to the user. Hidden by default.
self.errorReportTextEdit = QtGui.QTextEdit(self.progressPage)
self.errorReportTextEdit.setObjectName(u'progresserrorReportTextEdit')
self.errorReportTextEdit.setHidden(True)
self.errorReportTextEdit.setReadOnly(True)
self.progressLayout.addWidget(self.errorReportTextEdit)
self.errorButtonLayout = QtGui.QHBoxLayout()
self.errorButtonLayout.setObjectName(u'errorButtonLayout')
2012-12-29 15:25:29 +00:00
spacer = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.errorButtonLayout.addItem(spacer)
self.errorCopyToButton = QtGui.QPushButton(self.progressPage)
self.errorCopyToButton.setObjectName(u'errorCopyToButton')
self.errorCopyToButton.setHidden(True)
2012-12-29 15:25:29 +00:00
self.errorCopyToButton.setIcon(build_icon(u':/system/system_edit_copy.png'))
self.errorButtonLayout.addWidget(self.errorCopyToButton)
self.errorSaveToButton = QtGui.QPushButton(self.progressPage)
self.errorSaveToButton.setObjectName(u'errorSaveToButton')
self.errorSaveToButton.setHidden(True)
2012-12-29 15:25:29 +00:00
self.errorSaveToButton.setIcon(build_icon(u':/general/general_save.png'))
self.errorButtonLayout.addWidget(self.errorSaveToButton)
self.progressLayout.addLayout(self.errorButtonLayout)
2011-01-13 17:55:29 +00:00
self.addPage(self.progressPage)
def exec_(self):
"""
Run the wizard.
"""
self.setDefaults()
return QtGui.QWizard.exec_(self)
def reject(self):
"""
Stop the wizard on cancel button, close button or ESC key.
"""
log.debug(u'Wizard cancelled by user.')
if self.withProgressPage and self.currentPage() == self.progressPage:
2011-01-13 17:55:29 +00:00
Receiver.send_message(u'openlp_stop_wizard')
2011-01-18 18:53:09 +00:00
self.done(QtGui.QDialog.Rejected)
2011-01-13 17:55:29 +00:00
def onCurrentIdChanged(self, pageId):
"""
Perform necessary functions depending on which wizard page is active.
"""
if self.withProgressPage and self.page(pageId) == self.progressPage:
2011-01-13 17:55:29 +00:00
self.preWizard()
self.performWizard()
self.postWizard()
else:
self.customPageChanged(pageId)
def customPageChanged(self, pageId):
"""
Called when changing to a page other than the progress page
"""
pass
2011-01-13 17:55:29 +00:00
def onErrorCopyToButtonClicked(self):
"""
Called when the ``onErrorCopyToButtonClicked`` has been clicked.
"""
pass
def onErrorSaveToButtonClicked(self):
"""
Called when the ``onErrorSaveToButtonClicked`` has been clicked.
"""
pass
2011-01-13 17:55:29 +00:00
def incrementProgressBar(self, status_text, increment=1):
"""
Update the wizard progress page.
``status_text``
Current status information to display.
``increment``
The value to increment the progress bar by.
"""
log.debug(u'IncrementBar %s', status_text)
self.progressLabel.setText(status_text)
if increment > 0:
self.progressBar.setValue(self.progressBar.value() + increment)
2013-02-03 19:23:12 +00:00
self.application.process_events()
2011-01-13 17:55:29 +00:00
def preWizard(self):
"""
Prepare the UI for the import.
"""
self.finishButton.setVisible(False)
self.progressBar.setMinimum(0)
self.progressBar.setMaximum(1188)
self.progressBar.setValue(0)
def postWizard(self):
"""
Clean up the UI after the import has finished.
"""
self.progressBar.setValue(self.progressBar.maximum())
self.finishButton.setVisible(True)
self.cancelButton.setVisible(False)
2013-02-03 19:23:12 +00:00
self.application.process_events()
2011-02-10 19:37:02 +00:00
2013-01-18 20:35:30 +00:00
def getFileName(self, title, editbox, setting_name, filters=u''):
2011-02-10 19:37:02 +00:00
"""
Opens a QFileDialog and saves the filename to the given editbox.
``title``
The title of the dialog (unicode).
``editbox``
2012-05-07 10:36:39 +00:00
An editbox (QLineEdit).
2011-02-10 19:37:02 +00:00
2013-01-18 20:35:30 +00:00
``setting_name``
The place where to save the last opened directory.
2011-02-10 19:37:02 +00:00
``filters``
The file extension filters. It should contain the file description
as well as the file extension. For example::
u'OpenLP 2.0 Databases (*.sqlite)'
"""
if filters:
filters += u';;'
filters += u'%s (*)' % UiStrings().AllFiles
filename = QtGui.QFileDialog.getOpenFileName(self, title,
2013-01-18 20:35:30 +00:00
os.path.dirname(Settings().value(self.plugin.settingsSection + u'/' + setting_name)), filters)
2011-02-10 19:37:02 +00:00
if filename:
editbox.setText(filename)
2013-01-18 20:35:30 +00:00
Settings().setValue(self.plugin.settingsSection + u'/' + setting_name, filename)
2013-01-18 20:35:30 +00:00
def getFolder(self, title, editbox, setting_name):
2012-05-07 10:36:39 +00:00
"""
Opens a QFileDialog and saves the selected folder to the given editbox.
``title``
The title of the dialog (unicode).
``editbox``
An editbox (QLineEdit).
2013-01-18 20:35:30 +00:00
``setting_name``
The place where to save the last opened directory.
2012-05-07 10:36:39 +00:00
"""
folder = QtGui.QFileDialog.getExistingDirectory(self, title,
2013-01-18 20:35:30 +00:00
Settings().value(self.plugin.settingsSection + u'/' + setting_name),
QtGui.QFileDialog.ShowDirsOnly)
2012-05-07 10:36:39 +00:00
if folder:
editbox.setText(folder)
2013-01-18 20:35:30 +00:00
Settings().setValue(self.plugin.settingsSection + u'/' + setting_name, folder)
2013-02-03 09:07:31 +00:00
2013-02-03 19:23:12 +00:00
def _get_application(self):
2013-02-03 09:07:31 +00:00
"""
Adds the openlp to the class dynamically
"""
2013-02-03 19:23:12 +00:00
if not hasattr(self, u'_application'):
self._application = Registry().get(u'application')
return self._application
2013-02-03 09:07:31 +00:00
2013-02-05 08:05:28 +00:00
application = property(_get_application)