# -*- coding: utf-8 -*- # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 ############################################################################### # OpenLP - Open Source Lyrics Projection # # --------------------------------------------------------------------------- # # 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, # # 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 # ############################################################################### """ The :mod:``wizard`` module provides generic wizard tools for OpenLP. """ import logging import os from PyQt4 import QtCore, QtGui from openlp.core.lib import Registry, Settings, UiStrings, build_icon, translate from openlp.core.lib.ui import add_welcome_page log = logging.getLogger(__name__) class WizardStrings(object): """ Provide standard strings for wizards to use. """ # 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' # These strings should need a good reason to be retranslated elsewhere. FinishedImport = translate('OpenLP.Ui', 'Finished import.') FormatLabel = translate('OpenLP.Ui', 'Format:') HeaderStyle = u'%s' Importing = translate('OpenLP.Ui', 'Importing') ImportingType = translate('OpenLP.Ui', 'Importing "%s"...') ImportSelect = translate('OpenLP.Ui', 'Select Import Source') ImportSelectLong = translate('OpenLP.Ui', 'Select the import format and the location to import from.') OpenTypeFile = translate('OpenLP.Ui', 'Open %s File') OpenTypeFolder = translate('OpenLP.Ui', 'Open %s Folder') PercentSymbolFormat = translate('OpenLP.Ui', '%p%') Ready = translate('OpenLP.Ui', 'Ready.') StartingImport = translate('OpenLP.Ui', 'Starting import...') 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 ' 'least one %s file to import from.', 'A file type e.g. OpenSong') YouSpecifyFolder = translate('OpenLP.Ui', 'You need to specify one ' '%s folder to import from.', 'A song format e.g. PowerSong') class OpenLPWizard(QtGui.QWizard): """ Generic OpenLP wizard to provide generic functionality and a unified look and feel. """ def __init__(self, parent, plugin, name, image): """ Constructor """ QtGui.QWizard.__init__(self, parent) self.plugin = plugin self.setObjectName(name) self.open_icon = build_icon(u':/general/general_open.png') self.delete_icon = build_icon(u':/general/general_delete.png') self.finish_button = self.button(QtGui.QWizard.FinishButton) self.cancel_button = self.button(QtGui.QWizard.CancelButton) self.setupUi(image) self.register_fields() self.custom_init() self.custom_signals() self.currentIdChanged.connect(self.on_current_id_changed) self.error_copy_to_button.clicked.connect(self.on_error_copy_to_button_clicked) self.error_save_to_button.clicked.connect(self.on_error_save_to_button_clicked) def setupUi(self, image): """ Set up the wizard UI. """ self.setModal(True) self.setWizardStyle(QtGui.QWizard.ModernStyle) self.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.NoBackButtonOnLastPage) add_welcome_page(self, image) self.add_custom_pages() self.add_progress_page() self.retranslateUi() def register_fields(self): """ Hook method for wizards to register any fields they need. """ pass def custom_init(self): """ Hook method for custom initialisation """ pass def custom_signals(self): """ Hook method for adding custom signals """ pass def add_custom_pages(self): """ Hook method for wizards to add extra pages """ pass def add_progress_page(self): """ Add the progress page for the wizard. This page informs the user how the wizard is progressing with its task. """ self.progress_page = QtGui.QWizardPage() self.progress_page.setObjectName(u'progress_page') self.progress_layout = QtGui.QVBoxLayout(self.progress_page) self.progress_layout.setMargin(48) self.progress_layout.setObjectName(u'progress_layout') self.progress_label = QtGui.QLabel(self.progress_page) self.progress_label.setObjectName(u'progress_label') self.progress_label.setWordWrap(True) self.progress_layout.addWidget(self.progress_label) self.progress_bar = QtGui.QProgressBar(self.progress_page) self.progress_bar.setObjectName(u'progress_bar') self.progress_layout.addWidget(self.progress_bar) # 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.error_report_text_edit = QtGui.QTextEdit(self.progress_page) self.error_report_text_edit.setObjectName(u'error_report_text_edit') self.error_report_text_edit.setHidden(True) self.error_report_text_edit.setReadOnly(True) self.progress_layout.addWidget(self.error_report_text_edit) self.error_button_layout = QtGui.QHBoxLayout() self.error_button_layout.setObjectName(u'error_button_layout') spacer = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.error_button_layout.addItem(spacer) self.error_copy_to_button = QtGui.QPushButton(self.progress_page) self.error_copy_to_button.setObjectName(u'error_copy_to_button') self.error_copy_to_button.setHidden(True) self.error_copy_to_button.setIcon(build_icon(u':/system/system_edit_copy.png')) self.error_button_layout.addWidget(self.error_copy_to_button) self.error_save_to_button = QtGui.QPushButton(self.progress_page) self.error_save_to_button.setObjectName(u'error_save_to_button') self.error_save_to_button.setHidden(True) self.error_save_to_button.setIcon(build_icon(u':/general/general_save.png')) self.error_button_layout.addWidget(self.error_save_to_button) self.progress_layout.addLayout(self.error_button_layout) self.addPage(self.progress_page) 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.currentPage() == self.progress_page: Registry().execute(u'openlp_stop_wizard') self.done(QtGui.QDialog.Rejected) def on_current_id_changed(self, pageId): """ Perform necessary functions depending on which wizard page is active. """ if self.page(pageId) == self.progress_page: self.pre_wizard() self.performWizard() self.post_wizard() else: self.custom_cage_changed(pageId) def custom_cage_changed(self, pageId): """ Called when changing to a page other than the progress page """ pass def on_error_copy_to_button_clicked(self): """ Called when the ``error_copy_to_button`` has been clicked. """ pass def on_error_save_to_button_clicked(self): """ Called when the ``error_save_to_button`` has been clicked. """ pass def increment_progress_bar(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.progress_label.setText(status_text) if increment > 0: self.progress_bar.setValue(self.progress_bar.value() + increment) self.application.process_events() def pre_wizard(self): """ Prepare the UI for the import. """ self.finish_button.setVisible(False) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(1188) self.progress_bar.setValue(0) def post_wizard(self): """ Clean up the UI after the import has finished. """ self.progress_bar.setValue(self.progress_bar.maximum()) self.finish_button.setVisible(True) self.cancel_button.setVisible(False) self.application.process_events() def get_file_name(self, title, editbox, setting_name, filters=u''): """ Opens a QFileDialog and saves the filename to the given editbox. ``title`` The title of the dialog (unicode). ``editbox`` An editbox (QLineEdit). ``setting_name`` The place where to save the last opened directory. ``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, os.path.dirname(Settings().value(self.plugin.settings_section + u'/' + setting_name)), filters) if filename: editbox.setText(filename) Settings().setValue(self.plugin.settings_section + u'/' + setting_name, filename) def get_folder(self, title, editbox, setting_name): """ Opens a QFileDialog and saves the selected folder to the given editbox. ``title`` The title of the dialog (unicode). ``editbox`` An editbox (QLineEdit). ``setting_name`` The place where to save the last opened directory. """ folder = QtGui.QFileDialog.getExistingDirectory(self, title, Settings().value(self.plugin.settings_section + u'/' + setting_name), QtGui.QFileDialog.ShowDirsOnly) if folder: editbox.setText(folder) Settings().setValue(self.plugin.settings_section + u'/' + setting_name, folder) def _get_application(self): """ Adds the openlp to the class dynamically """ if not hasattr(self, u'_application'): self._application = Registry().get(u'application') return self._application application = property(_get_application)