diff --git a/openlp/.version b/openlp/.version index d41002840..3245d0c77 100644 --- a/openlp/.version +++ b/openlp/.version @@ -1 +1 @@ -2.1.0-bzr2141 +2.1.0-bzr2234 diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index c6bce2a00..dfc12608f 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -38,6 +38,8 @@ from sqlalchemy import Table, MetaData, Column, types, create_engine from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, DBAPIError, OperationalError from sqlalchemy.orm import scoped_session, sessionmaker, mapper from sqlalchemy.pool import NullPool +from alembic.migration import MigrationContext +from alembic.operations import Operations from openlp.core.lib import translate, Settings from openlp.core.lib.ui import critical_error_message_box @@ -65,6 +67,17 @@ def init_db(url, auto_flush=True, auto_commit=False): return session, metadata +def get_upgrade_op(session): + """ + Create a migration context and an operations object for performing upgrades. + + ``session`` + The SQLAlchemy session object. + """ + context = MigrationContext.configure(session.bind.connect()) + return Operations(context) + + def upgrade_db(url, upgrade): """ Upgrade a database. @@ -82,13 +95,7 @@ def upgrade_db(url, upgrade): Provides a class for the metadata table. """ pass - load_changes = False - tables = [] - try: - tables = upgrade.upgrade_setup(metadata) - load_changes = True - except (SQLAlchemyError, DBAPIError): - pass + metadata_table = Table(u'metadata', metadata, Column(u'key', types.Unicode(64), primary_key=True), Column(u'value', types.UnicodeText(), default=None) @@ -105,22 +112,22 @@ def upgrade_db(url, upgrade): if version > upgrade.__version__: return version, upgrade.__version__ version += 1 - if load_changes: + try: while hasattr(upgrade, u'upgrade_%d' % version): log.debug(u'Running upgrade_%d', version) try: upgrade_func = getattr(upgrade, u'upgrade_%d' % version) - upgrade_func(session, metadata, tables) + upgrade_func(session, metadata) session.commit() # Update the version number AFTER a commit so that we are sure the previous transaction happened version_meta.value = unicode(version) session.commit() version += 1 except (SQLAlchemyError, DBAPIError): - log.exception(u'Could not run database upgrade script ' - '"upgrade_%s", upgrade process has been halted.', version) + log.exception(u'Could not run database upgrade script "upgrade_%s", upgrade process has been halted.', + version) break - else: + except (SQLAlchemyError, DBAPIError): version_meta = Metadata.populate(key=u'version', value=int(upgrade.__version__)) session.commit() return int(version_meta.value), upgrade.__version__ diff --git a/openlp/core/lib/formattingtags.py b/openlp/core/lib/formattingtags.py index b2d8f6ea7..1984b08ba 100644 --- a/openlp/core/lib/formattingtags.py +++ b/openlp/core/lib/formattingtags.py @@ -29,7 +29,7 @@ """ Provide HTML Tag management and Formatting Tag access class """ -import cPickle +import json from openlp.core.lib import Settings, translate @@ -66,7 +66,7 @@ class FormattingTags(object): if isinstance(tag[element], unicode): tag[element] = tag[element].encode('utf8') # Formatting Tags were also known as display tags. - Settings().setValue(u'displayTags/html_tags', cPickle.dumps(tags) if tags else u'') + Settings().setValue(u'formattingTags/html_tags', json.dumps(tags) if tags else u'') @staticmethod def load_tags(): @@ -156,13 +156,10 @@ class FormattingTags(object): u'end html': u'', u'protected': True, u'temporary': False}) FormattingTags.add_html_tags(base_tags) FormattingTags.add_html_tags(temporary_tags) - # Formatting Tags were also known as display tags. - user_expands = Settings().value(u'displayTags/html_tags') - # cPickle only accepts str not unicode strings - user_expands_string = str(user_expands) + user_expands_string = str(Settings().value(u'formattingTags/html_tags')) if user_expands_string: - user_tags = cPickle.loads(user_expands_string) + user_tags = json.loads(user_expands_string) for tag in user_tags: for element in tag: if isinstance(tag[element], str): diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index 412eddd1e..dc535a665 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -1,3 +1,4 @@ + # -*- coding: utf-8 -*- # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index c3e1fa366..973d457bb 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -728,10 +728,14 @@ class MediaManagerItem(QtGui.QWidget): def _get_application(self): """ - Adds the openlp to the class dynamically + Adds the openlp to the class dynamically. + Windows needs to access the application in a dynamic manner. """ - if not hasattr(self, u'_application'): - self._application = Registry().get(u'application') - return self._application + if os.name == u'nt': + return Registry().get(u'application') + else: + if not hasattr(self, u'_application'): + self._application = Registry().get(u'application') + return self._application application = property(_get_application) diff --git a/openlp/core/lib/plugin.py b/openlp/core/lib/plugin.py index b4f851b24..a79ba850a 100644 --- a/openlp/core/lib/plugin.py +++ b/openlp/core/lib/plugin.py @@ -30,6 +30,7 @@ Provide the generic plugin functionality for OpenLP plugins. """ import logging +import os from PyQt4 import QtCore @@ -424,8 +425,11 @@ class Plugin(QtCore.QObject): """ Adds the openlp to the class dynamically """ - if not hasattr(self, u'_application'): - self._application = Registry().get(u'application') - return self._application + if os.name == u'nt': + return Registry().get(u'application') + else: + if not hasattr(self, u'_application'): + self._application = Registry().get(u'application') + return self._application application = property(_get_application) diff --git a/openlp/core/lib/registry.py b/openlp/core/lib/registry.py index 7e880f1f9..cee9e0329 100644 --- a/openlp/core/lib/registry.py +++ b/openlp/core/lib/registry.py @@ -103,9 +103,6 @@ class Registry(object): ``key`` The service to be deleted. """ - if self.running_under_test is False: - log.error(u'Invalid Method call for key %s' % key) - raise KeyError(u'Invalid Method call for key %s' % key) if key in self.service_list: del self.service_list[key] diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index b32e1aaf0..ee1a5c588 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -485,6 +485,12 @@ class ServiceItem(object): """ return self.unique_identifier != other.unique_identifier + def __hash__(self): + """ + Return the hash for the service item. + """ + return self.unique_identifier + def is_media(self): """ Confirms if the ServiceItem is media diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index 49cd8f6d5..a887d2ce6 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -115,7 +115,7 @@ class Settings(QtCore.QSettings): u'advanced/single click preview': False, u'advanced/x11 bypass wm': X11_BYPASS_DEFAULT, u'crashreport/last directory': u'', - u'displayTags/html_tags': u'', + u'formattingTags/html_tags': u'', u'core/audio repeat list': False, u'core/auto open': False, u'core/auto preview': False, @@ -244,6 +244,7 @@ class Settings(QtCore.QSettings): u'shortcuts/printServiceItem': [QtGui.QKeySequence(u'Ctrl+P')], u'shortcuts/songExportItem': [], u'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key_F4)], + u'shortcuts/searchShortcut': [QtGui.QKeySequence(u'Ctrl+F')], u'shortcuts/settingsShortcutsItem': [], u'shortcuts/settingsImportItem': [], u'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(u'Alt+F7')], @@ -271,6 +272,7 @@ class Settings(QtCore.QSettings): u'shortcuts/songImportItem': [], u'shortcuts/themeScreen': [QtGui.QKeySequence(u'T')], u'shortcuts/toolsReindexItem': [], + u'shortcuts/toolsFindDuplicates': [], u'shortcuts/toolsAlertItem': [QtGui.QKeySequence(u'F7')], u'shortcuts/toolsFirstTimeWizard': [], u'shortcuts/toolsOpenDataFolder': [], diff --git a/openlp/core/ui/aboutdialog.py b/openlp/core/ui/aboutdialog.py index 82f0a6683..f17d70bac 100644 --- a/openlp/core/ui/aboutdialog.py +++ b/openlp/core/ui/aboutdialog.py @@ -291,7 +291,7 @@ class Ui_AboutDialog(object): 'but WITHOUT ANY WARRANTY; without even the implied warranty of ' 'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See below ' 'for more details.') - gpltext = ('GNU GENERAL PUBLIC LICENSE\n' + gpl_text = ('GNU GENERAL PUBLIC LICENSE\n' 'Version 2, June 1991\n' '\n' 'Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 ' @@ -662,7 +662,7 @@ class Ui_AboutDialog(object): 'linking proprietary applications with the library. If this is ' 'what you want to do, use the GNU Lesser General Public License ' 'instead of this License.') - self.license_text_edit.setPlainText(u'%s\n\n%s\n\n%s\n\n\n%s' % (copyright_note, licence, disclaimer, gpltext)) + self.license_text_edit.setPlainText(u'%s\n\n%s\n\n%s\n\n\n%s' % (copyright_note, licence, disclaimer, gpl_text)) self.about_notebook.setTabText(self.about_notebook.indexOf(self.license_tab), translate('OpenLP.AboutForm', 'License')) self.volunteer_button.setText(translate('OpenLP.AboutForm', 'Volunteer')) diff --git a/openlp/core/ui/exceptionform.py b/openlp/core/ui/exceptionform.py index af1744424..49d6b0bef 100644 --- a/openlp/core/ui/exceptionform.py +++ b/openlp/core/ui/exceptionform.py @@ -34,8 +34,8 @@ import re import os import platform +import bs4 import sqlalchemy -from bs4 import BeautifulSoup from lxml import etree from PyQt4 import Qt, QtCore, QtGui, QtWebKit @@ -145,7 +145,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog): u'QtWebkit: %s\n' % WEBKIT_VERSION + \ u'SQLAlchemy: %s\n' % sqlalchemy.__version__ + \ u'SQLAlchemy Migrate: %s\n' % MIGRATE_VERSION + \ - u'BeautifulSoup: %s\n' % BeautifulSoup.__version__ + \ + u'BeautifulSoup: %s\n' % bs4.__version__ + \ u'lxml: %s\n' % etree.__version__ + \ u'Chardet: %s\n' % CHARDET_VERSION + \ u'PyEnchant: %s\n' % ENCHANT_VERSION + \ diff --git a/openlp/core/ui/firsttimeform.py b/openlp/core/ui/firsttimeform.py index 0f3f3cc18..f163b3573 100644 --- a/openlp/core/ui/firsttimeform.py +++ b/openlp/core/ui/firsttimeform.py @@ -68,7 +68,7 @@ class ThemeScreenshotThread(QtCore.QThread): screenshot = config.get(u'theme_%s' % theme, u'screenshot') urllib.urlretrieve(u'%s%s' % (self.parent().web, screenshot), os.path.join(unicode(gettempdir(), get_filesystem_encoding()), u'openlp', screenshot)) - item = QtGui.QListWidgetItem(title, self.parent().themesListWidget) + item = QtGui.QListWidgetItem(title, self.parent().themes_list_widget) item.setData(QtCore.Qt.UserRole, filename) item.setCheckState(QtCore.Qt.Unchecked) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) @@ -76,8 +76,7 @@ class ThemeScreenshotThread(QtCore.QThread): class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): """ - This is the Theme Import Wizard, which allows easy creation and editing of - OpenLP themes. + This is the Theme Import Wizard, which allows easy creation and editing of OpenLP themes. """ log.info(u'ThemeWizardForm loaded') @@ -97,10 +96,11 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): self.config.readfp(io.BytesIO(files)) self.update_screen_list_combo() self.was_download_cancelled = False + self.theme_screenshot_thread = None self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading %s...') - self.cancelButton.clicked.connect(self.onCancelButtonClicked) - self.noInternetFinishButton.clicked.connect(self.onNoInternetFinishButtonClicked) - self.currentIdChanged.connect(self.onCurrentIdChanged) + 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(u'config_screen_changed', self.update_screen_list_combo) def exec_(self): @@ -116,9 +116,9 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): """ self.restart() check_directory_exists(os.path.join(unicode(gettempdir(), get_filesystem_encoding()), u'openlp')) - self.noInternetFinishButton.setVisible(False) + self.no_internet_finish_button.setVisible(False) # Check if this is a re-run of the wizard. - self.hasRunWizard = Settings().value(u'core/has run wizard') + self.has_run_wizard = Settings().value(u'core/has run wizard') # Sort out internet access for downloads if self.web_access: songs = self.config.get(u'songs', u'languages') @@ -126,7 +126,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): for song in songs: title = unicode(self.config.get(u'songs_%s' % song, u'title'), u'utf8') filename = unicode(self.config.get(u'songs_%s' % song, u'filename'), u'utf8') - item = QtGui.QListWidgetItem(title, self.songsListWidget) + item = QtGui.QListWidgetItem(title, self.songs_list_widget) item.setData(QtCore.Qt.UserRole, filename) item.setCheckState(QtCore.Qt.Unchecked) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) @@ -134,7 +134,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): bible_languages = bible_languages.split(u',') for lang in bible_languages: language = unicode(self.config.get(u'bibles_%s' % lang, u'title'), u'utf8') - langItem = QtGui.QTreeWidgetItem(self.biblesTreeWidget, [language]) + langItem = QtGui.QTreeWidgetItem(self.bibles_tree_widget, [language]) bibles = self.config.get(u'bibles_%s' % lang, u'translations') bibles = bibles.split(u',') for bible in bibles: @@ -144,10 +144,10 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): item.setData(0, QtCore.Qt.UserRole, filename) item.setCheckState(0, QtCore.Qt.Unchecked) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) - self.biblesTreeWidget.expandAll() + self.bibles_tree_widget.expandAll() # Download the theme screenshots. - self.themeScreenshotThread = ThemeScreenshotThread(self) - self.themeScreenshotThread.start() + self.theme_screenshot_thread = ThemeScreenshotThread(self) + self.theme_screenshot_thread.start() self.application.set_normal_cursor() def nextId(self): @@ -166,61 +166,60 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): return FirstTimePage.Progress elif self.currentId() == FirstTimePage.Themes: self.application.set_busy_cursor() - while not self.themeScreenshotThread.isFinished(): + while not self.theme_screenshot_thread.isFinished(): time.sleep(0.1) self.application.process_events() # Build the screenshot icons, as this can not be done in the thread. - self._buildThemeScreenshots() + self._build_theme_screenshots() self.application.set_normal_cursor() return FirstTimePage.Defaults else: return self.currentId() + 1 - def onCurrentIdChanged(self, pageId): + def on_current_id_changed(self, page_id): """ Detects Page changes and updates as appropriate. """ - # Keep track of the page we are at. Triggering "Cancel" causes pageId - # to be a -1. + # Keep track of the page we are at. Triggering "Cancel" causes page_id to be a -1. self.application.process_events() - if pageId != -1: - self.lastId = pageId - if pageId == FirstTimePage.Plugins: + if page_id != -1: + self.last_id = page_id + if page_id == FirstTimePage.Plugins: # Set the no internet page text. - if self.hasRunWizard: - self.noInternetLabel.setText(self.noInternetText) + if self.has_run_wizard: + self.no_internet_label.setText(self.no_internet_text) else: - self.noInternetLabel.setText(self.noInternetText + self.cancelWizardText) - elif pageId == FirstTimePage.Defaults: - self.themeComboBox.clear() - for iter in xrange(self.themesListWidget.count()): - item = self.themesListWidget.item(iter) + self.no_internet_label.setText(self.no_internet_text + self.cancelWizardText) + elif page_id == FirstTimePage.Defaults: + self.theme_combo_box.clear() + for iter in xrange(self.themes_list_widget.count()): + item = self.themes_list_widget.item(iter) if item.checkState() == QtCore.Qt.Checked: - self.themeComboBox.addItem(item.text()) - if self.hasRunWizard: + self.theme_combo_box.addItem(item.text()) + if self.has_run_wizard: # Add any existing themes to list. for theme in self.theme_manager.get_themes(): - index = self.themeComboBox.findText(theme) + index = self.theme_combo_box.findText(theme) if index == -1: - self.themeComboBox.addItem(theme) + self.theme_combo_box.addItem(theme) default_theme = Settings().value(u'themes/global theme') # Pre-select the current default theme. - index = self.themeComboBox.findText(default_theme) - self.themeComboBox.setCurrentIndex(index) - elif pageId == FirstTimePage.NoInternet: - self.backButton.setVisible(False) - self.nextButton.setVisible(False) - self.noInternetFinishButton.setVisible(True) - if self.hasRunWizard: - self.cancelButton.setVisible(False) - elif pageId == FirstTimePage.Progress: + 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) + self.no_internet_finish_button.setVisible(True) + if self.has_run_wizard: + self.cancel_button.setVisible(False) + elif page_id == FirstTimePage.Progress: 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._preWizard() - self._performWizard() + self._pre_wizard() + self._perform_wizard() self._post_wizard() self.application.set_normal_cursor() @@ -229,70 +228,72 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): The user changed screen resolution or enabled/disabled more screens, so we need to update the combo box. """ - self.displayComboBox.clear() - self.displayComboBox.addItems(self.screens.get_screen_list()) - self.displayComboBox.setCurrentIndex(self.displayComboBox.count() - 1) + 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) - def onCancelButtonClicked(self): + def on_cancel_button_clicked(self): """ Process the triggering of the cancel button. """ - if self.lastId == FirstTimePage.NoInternet or (self.lastId <= FirstTimePage.Plugins and not self.hasRunWizard): + if self.last_id == FirstTimePage.NoInternet or (self.last_id <= FirstTimePage.Plugins and not self.has_run_wizard): QtCore.QCoreApplication.exit() sys.exit() self.was_download_cancelled = True - while self.themeScreenshotThread.isRunning(): - time.sleep(0.1) + # Was the thread created. + if self.theme_screenshot_thread: + while self.theme_screenshot_thread.isRunning(): + time.sleep(0.1) self.application.set_normal_cursor() - def onNoInternetFinishButtonClicked(self): + def on_no_internet_finish_button_clicked(self): """ Process the triggering of the "Finish" button on the No Internet page. """ self.application.set_busy_cursor() - self._performWizard() + self._perform_wizard() self.application.set_normal_cursor() Settings().setValue(u'core/has run wizard', True) self.close() - def urlGetFile(self, url, fpath): + def url_get_file(self, url, f_path): """" - Download a file given a URL. The file is retrieved in chunks, giving - the ability to cancel the download at any point. + Download a file given a URL. The file is retrieved in chunks, giving the ability to cancel the download at any + point. """ block_count = 0 block_size = 4096 - urlfile = urllib2.urlopen(url) - filename = open(fpath, "wb") + url_file = urllib2.urlopen(url) + filename = open(f_path, "wb") # Download until finished or canceled. while not self.was_download_cancelled: - data = urlfile.read(block_size) + data = url_file.read(block_size) if not data: break filename.write(data) block_count += 1 - self._downloadProgress(block_count, block_size) + self._download_progress(block_count, block_size) filename.close() # Delete file if cancelled, it may be a partial file. if self.was_download_cancelled: - os.remove(fpath) + os.remove(f_path) - def _buildThemeScreenshots(self): + def _build_theme_screenshots(self): """ This method builds the theme screenshots' icons for all items in the - ``self.themesListWidget``. + ``self.themes_list_widget``. """ themes = self.config.get(u'themes', u'files') themes = themes.split(u',') for theme in themes: filename = self.config.get(u'theme_%s' % theme, u'filename') screenshot = self.config.get(u'theme_%s' % theme, u'screenshot') - for index in xrange(self.themesListWidget.count()): - item = self.themesListWidget.item(index) + for index in xrange(self.themes_list_widget.count()): + item = self.themes_list_widget.item(index) if item.data(QtCore.Qt.UserRole) == filename: break item.setIcon(build_icon(os.path.join(unicode(gettempdir(), - get_filesystem_encoding()), u'openlp', screenshot))) + get_filesystem_encoding()), u'openlp', screenshot))) def _getFileSize(self, url): """ @@ -305,15 +306,15 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): meta = site.info() return int(meta.getheaders("Content-Length")[0]) - def _downloadProgress(self, count, block_size): + def _download_progress(self, count, block_size): """ Calculate and display the download progress. """ increment = (count * block_size) - self.previous_size - self._incrementProgressBar(None, increment) + self._increment_progress_bar(None, increment) self.previous_size = count * block_size - def _incrementProgressBar(self, status_text, increment=1): + def _increment_progress_bar(self, status_text, increment=1): """ Update the wizard progress page. @@ -324,28 +325,28 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): The value to increment the progress bar by. """ if status_text: - self.progressLabel.setText(status_text) + self.progress_label.setText(status_text) if increment > 0: - self.progressBar.setValue(self.progressBar.value() + increment) + self.progress_bar.setValue(self.progress_bar.value() + increment) self.application.process_events() - def _preWizard(self): + def _pre_wizard(self): """ Prepare the UI for the process. """ self.max_progress = 0 - self.finishButton.setVisible(False) + self.finish_button.setVisible(False) self.application.process_events() # Loop through the songs list and increase for each selected item - for i in xrange(self.songsListWidget.count()): + for i in xrange(self.songs_list_widget.count()): self.application.process_events() - item = self.songsListWidget.item(i) + item = self.songs_list_widget.item(i) if item.checkState() == QtCore.Qt.Checked: filename = item.data(QtCore.Qt.UserRole) size = self._getFileSize(u'%s%s' % (self.web, filename)) self.max_progress += size # Loop through the Bibles list and increase for each selected item - iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget) + iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget) while iterator.value(): self.application.process_events() item = iterator.value() @@ -355,9 +356,9 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): self.max_progress += size iterator += 1 # Loop through the themes list and increase for each selected item - for i in xrange(self.themesListWidget.count()): + for i in xrange(self.themes_list_widget.count()): self.application.process_events() - item = self.themesListWidget.item(i) + item = self.themes_list_widget.item(i) if item.checkState() == QtCore.Qt.Checked: filename = item.data(QtCore.Qt.UserRole) size = self._getFileSize(u'%s%s' % (self.web, filename)) @@ -365,16 +366,16 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): if self.max_progress: # Add on 2 for plugins status setting plus a "finished" point. self.max_progress += 2 - self.progressBar.setValue(0) - self.progressBar.setMinimum(0) - self.progressBar.setMaximum(self.max_progress) - self.progressPage.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up And Downloading')) - self.progressPage.setSubTitle( + 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( translate('OpenLP.FirstTimeWizard', 'Please wait while OpenLP is set up and your data is downloaded.')) else: - self.progressBar.setVisible(False) - self.progressPage.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up')) - self.progressPage.setSubTitle(u'Setup complete.') + self.progress_bar.setVisible(False) + self.progress_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up')) + self.progress_page.setSubTitle(u'Setup complete.') self.repaint() self.application.process_events() # Try to give the wizard a chance to repaint itself @@ -385,44 +386,44 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): Clean up the UI after the process has finished. """ if self.max_progress: - self.progressBar.setValue(self.progressBar.maximum()) - if self.hasRunWizard: - self.progressLabel.setText(translate('OpenLP.FirstTimeWizard', + self.progress_bar.setValue(self.progress_bar.maximum()) + if self.has_run_wizard: + self.progress_label.setText(translate('OpenLP.FirstTimeWizard', 'Download complete. Click the finish button to return to OpenLP.')) else: - self.progressLabel.setText(translate('OpenLP.FirstTimeWizard', + self.progress_label.setText(translate('OpenLP.FirstTimeWizard', 'Download complete. Click the finish button to start OpenLP.')) else: - if self.hasRunWizard: - self.progressLabel.setText(translate('OpenLP.FirstTimeWizard', + if self.has_run_wizard: + self.progress_label.setText(translate('OpenLP.FirstTimeWizard', 'Click the finish button to return to OpenLP.')) else: - self.progressLabel.setText(translate('OpenLP.FirstTimeWizard', + self.progress_label.setText(translate('OpenLP.FirstTimeWizard', 'Click the finish button to start OpenLP.')) - self.finishButton.setVisible(True) - self.finishButton.setEnabled(True) - self.cancelButton.setVisible(False) - self.nextButton.setVisible(False) + self.finish_button.setVisible(True) + self.finish_button.setEnabled(True) + self.cancel_button.setVisible(False) + self.next_button.setVisible(False) self.application.process_events() - def _performWizard(self): + def _perform_wizard(self): """ Run the tasks in the wizard. """ # Set plugin states - self._incrementProgressBar(translate('OpenLP.FirstTimeWizard', 'Enabling selected plugins...')) - self._setPluginStatus(self.songsCheckBox, u'songs/status') - self._setPluginStatus(self.bibleCheckBox, u'bibles/status') + self._increment_progress_bar(translate('OpenLP.FirstTimeWizard', 'Enabling selected plugins...')) + self._set_plugin_status(self.songs_check_box, u'songs/status') + self._set_plugin_status(self.bible_check_box, u'bibles/status') # TODO Presentation plugin is not yet working on Mac OS X. # For now just ignore it. if sys.platform != 'darwin': - self._setPluginStatus(self.presentationCheckBox, u'presentations/status') - self._setPluginStatus(self.imageCheckBox, u'images/status') - self._setPluginStatus(self.mediaCheckBox, u'media/status') - self._setPluginStatus(self.remoteCheckBox, u'remotes/status') - self._setPluginStatus(self.customCheckBox, u'custom/status') - self._setPluginStatus(self.songUsageCheckBox, u'songusage/status') - self._setPluginStatus(self.alertCheckBox, u'alerts/status') + self._set_plugin_status(self.presentation_check_box, u'presentations/status') + self._set_plugin_status(self.image_check_box, u'images/status') + self._set_plugin_status(self.media_check_box, u'media/status') + self._set_plugin_status(self.remote_check_box, u'remotes/status') + self._set_plugin_status(self.custom_check_box, u'custom/status') + self._set_plugin_status(self.song_usage_check_box, u'songusage/status') + self._set_plugin_status(self.alert_check_box, u'alerts/status') if self.web_access: # Build directories for downloads songs_destination = os.path.join( @@ -430,42 +431,42 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): bibles_destination = AppLocation.get_section_data_path(u'bibles') themes_destination = AppLocation.get_section_data_path(u'themes') # Download songs - for i in xrange(self.songsListWidget.count()): - item = self.songsListWidget.item(i) + for i in xrange(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._incrementProgressBar(self.downloading % filename, 0) + self._increment_progress_bar(self.downloading % filename, 0) self.previous_size = 0 destination = os.path.join(songs_destination, unicode(filename)) - self.urlGetFile(u'%s%s' % (self.web, filename), destination) + self.url_get_file(u'%s%s' % (self.web, filename), destination) # Download Bibles bibles_iterator = QtGui.QTreeWidgetItemIterator( - self.biblesTreeWidget) + 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._incrementProgressBar(self.downloading % bible, 0) + self._increment_progress_bar(self.downloading % bible, 0) self.previous_size = 0 - self.urlGetFile(u'%s%s' % (self.web, bible), os.path.join(bibles_destination, bible)) + self.url_get_file(u'%s%s' % (self.web, bible), os.path.join(bibles_destination, bible)) bibles_iterator += 1 # Download themes - for i in xrange(self.themesListWidget.count()): - item = self.themesListWidget.item(i) + for i in xrange(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._incrementProgressBar(self.downloading % theme, 0) + self._increment_progress_bar(self.downloading % theme, 0) self.previous_size = 0 - self.urlGetFile(u'%s%s' % (self.web, theme), os.path.join(themes_destination, theme)) + self.url_get_file(u'%s%s' % (self.web, theme), os.path.join(themes_destination, theme)) # Set Default Display - if self.displayComboBox.currentIndex() != -1: - Settings().setValue(u'core/monitor', self.displayComboBox.currentIndex()) - self.screens.set_current_display(self.displayComboBox.currentIndex()) + if self.display_combo_box.currentIndex() != -1: + Settings().setValue(u'core/monitor', self.display_combo_box.currentIndex()) + self.screens.set_current_display(self.display_combo_box.currentIndex()) # Set Global Theme - if self.themeComboBox.currentIndex() != -1: - Settings().setValue(u'themes/global theme', self.themeComboBox.currentText()) + if self.theme_combo_box.currentIndex() != -1: + Settings().setValue(u'themes/global theme', self.theme_combo_box.currentText()) - def _setPluginStatus(self, field, tag): + def _set_plugin_status(self, field, tag): """ Set the status of a plugin. """ @@ -484,10 +485,14 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): def _get_application(self): """ - Adds the openlp to the class dynamically + Adds the openlp to the class dynamically. + Windows needs to access the application in a dynamic manner. """ - if not hasattr(self, u'_application'): - self._application = Registry().get(u'application') - return self._application + if os.name == u'nt': + return Registry().get(u'application') + else: + if not hasattr(self, u'_application'): + self._application = Registry().get(u'application') + return self._application application = property(_get_application) diff --git a/openlp/core/ui/firsttimewizard.py b/openlp/core/ui/firsttimewizard.py index 3a96873f5..b56507f65 100644 --- a/openlp/core/ui/firsttimewizard.py +++ b/openlp/core/ui/firsttimewizard.py @@ -55,200 +55,199 @@ class Ui_FirstTimeWizard(object): """ The UI widgets for the first time wizard. """ - def setupUi(self, FirstTimeWizard): + def setupUi(self, first_time_wizard): """ Set up the UI. """ - FirstTimeWizard.setObjectName(u'FirstTimeWizard') - FirstTimeWizard.resize(550, 386) - FirstTimeWizard.setModal(True) - FirstTimeWizard.setWizardStyle(QtGui.QWizard.ModernStyle) - FirstTimeWizard.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage | + first_time_wizard.setObjectName(u'first_time_wizard') + first_time_wizard.resize(550, 386) + first_time_wizard.setModal(True) + first_time_wizard.setWizardStyle(QtGui.QWizard.ModernStyle) + first_time_wizard.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.NoBackButtonOnLastPage | QtGui.QWizard.HaveCustomButton1) - self.finishButton = self.button(QtGui.QWizard.FinishButton) - self.noInternetFinishButton = self.button(QtGui.QWizard.CustomButton1) - self.cancelButton = self.button(QtGui.QWizard.CancelButton) - self.nextButton = self.button(QtGui.QWizard.NextButton) - self.backButton = self.button(QtGui.QWizard.BackButton) - add_welcome_page(FirstTimeWizard, u':/wizards/wizard_firsttime.bmp') + self.finish_button = self.button(QtGui.QWizard.FinishButton) + self.no_internet_finish_button = self.button(QtGui.QWizard.CustomButton1) + self.cancel_button = self.button(QtGui.QWizard.CancelButton) + self.next_button = self.button(QtGui.QWizard.NextButton) + self.back_button = self.button(QtGui.QWizard.BackButton) + add_welcome_page(first_time_wizard, u':/wizards/wizard_firsttime.bmp') # The plugins page - self.pluginPage = QtGui.QWizardPage() - self.pluginPage.setObjectName(u'pluginPage') - self.pluginLayout = QtGui.QVBoxLayout(self.pluginPage) - self.pluginLayout.setContentsMargins(40, 15, 40, 0) - self.pluginLayout.setObjectName(u'pluginLayout') - self.songsCheckBox = QtGui.QCheckBox(self.pluginPage) - self.songsCheckBox.setChecked(True) - self.songsCheckBox.setObjectName(u'songsCheckBox') - self.pluginLayout.addWidget(self.songsCheckBox) - self.customCheckBox = QtGui.QCheckBox(self.pluginPage) - self.customCheckBox.setChecked(True) - self.customCheckBox.setObjectName(u'customCheckBox') - self.pluginLayout.addWidget(self.customCheckBox) - self.bibleCheckBox = QtGui.QCheckBox(self.pluginPage) - self.bibleCheckBox.setChecked(True) - self.bibleCheckBox.setObjectName(u'bibleCheckBox') - self.pluginLayout.addWidget(self.bibleCheckBox) - self.imageCheckBox = QtGui.QCheckBox(self.pluginPage) - self.imageCheckBox.setChecked(True) - self.imageCheckBox.setObjectName(u'imageCheckBox') - self.pluginLayout.addWidget(self.imageCheckBox) + self.plugin_page = QtGui.QWizardPage() + self.plugin_page.setObjectName(u'plugin_page') + self.plugin_layout = QtGui.QVBoxLayout(self.plugin_page) + self.plugin_layout.setContentsMargins(40, 15, 40, 0) + self.plugin_layout.setObjectName(u'plugin_layout') + self.songs_check_box = QtGui.QCheckBox(self.plugin_page) + self.songs_check_box.setChecked(True) + self.songs_check_box.setObjectName(u'songs_check_box') + self.plugin_layout.addWidget(self.songs_check_box) + self.custom_check_box = QtGui.QCheckBox(self.plugin_page) + self.custom_check_box.setChecked(True) + self.custom_check_box.setObjectName(u'custom_check_box') + self.plugin_layout.addWidget(self.custom_check_box) + self.bible_check_box = QtGui.QCheckBox(self.plugin_page) + self.bible_check_box.setChecked(True) + self.bible_check_box.setObjectName(u'bible_check_box') + self.plugin_layout.addWidget(self.bible_check_box) + self.image_check_box = QtGui.QCheckBox(self.plugin_page) + self.image_check_box.setChecked(True) + self.image_check_box.setObjectName(u'image_check_box') + self.plugin_layout.addWidget(self.image_check_box) # TODO Presentation plugin is not yet working on Mac OS X. # For now just ignore it. if sys.platform != 'darwin': - self.presentationCheckBox = QtGui.QCheckBox(self.pluginPage) - self.presentationCheckBox.setChecked(True) - self.presentationCheckBox.setObjectName(u'presentationCheckBox') - self.pluginLayout.addWidget(self.presentationCheckBox) - self.mediaCheckBox = QtGui.QCheckBox(self.pluginPage) - self.mediaCheckBox.setChecked(True) - self.mediaCheckBox.setObjectName(u'mediaCheckBox') - self.pluginLayout.addWidget(self.mediaCheckBox) - self.remoteCheckBox = QtGui.QCheckBox(self.pluginPage) - self.remoteCheckBox.setObjectName(u'remoteCheckBox') - self.pluginLayout.addWidget(self.remoteCheckBox) - self.songUsageCheckBox = QtGui.QCheckBox(self.pluginPage) - self.songUsageCheckBox.setChecked(True) - self.songUsageCheckBox.setObjectName(u'songUsageCheckBox') - self.pluginLayout.addWidget(self.songUsageCheckBox) - self.alertCheckBox = QtGui.QCheckBox(self.pluginPage) - self.alertCheckBox.setChecked(True) - self.alertCheckBox.setObjectName(u'alertCheckBox') - self.pluginLayout.addWidget(self.alertCheckBox) - FirstTimeWizard.setPage(FirstTimePage.Plugins, self.pluginPage) + self.presentation_check_box = QtGui.QCheckBox(self.plugin_page) + self.presentation_check_box.setChecked(True) + self.presentation_check_box.setObjectName(u'presentation_check_box') + self.plugin_layout.addWidget(self.presentation_check_box) + self.media_check_box = QtGui.QCheckBox(self.plugin_page) + self.media_check_box.setChecked(True) + self.media_check_box.setObjectName(u'media_check_box') + self.plugin_layout.addWidget(self.media_check_box) + self.remote_check_box = QtGui.QCheckBox(self.plugin_page) + self.remote_check_box.setObjectName(u'remote_check_box') + self.plugin_layout.addWidget(self.remote_check_box) + self.song_usage_check_box = QtGui.QCheckBox(self.plugin_page) + self.song_usage_check_box.setChecked(True) + self.song_usage_check_box.setObjectName(u'song_usage_check_box') + self.plugin_layout.addWidget(self.song_usage_check_box) + self.alert_check_box = QtGui.QCheckBox(self.plugin_page) + self.alert_check_box.setChecked(True) + self.alert_check_box.setObjectName(u'alert_check_box') + self.plugin_layout.addWidget(self.alert_check_box) + first_time_wizard.setPage(FirstTimePage.Plugins, self.plugin_page) # The "you don't have an internet connection" page. - self.noInternetPage = QtGui.QWizardPage() - self.noInternetPage.setObjectName(u'noInternetPage') - self.noInternetLayout = QtGui.QVBoxLayout(self.noInternetPage) - self.noInternetLayout.setContentsMargins(50, 30, 50, 40) - self.noInternetLayout.setObjectName(u'noInternetLayout') - self.noInternetLabel = QtGui.QLabel(self.noInternetPage) - self.noInternetLabel.setWordWrap(True) - self.noInternetLabel.setObjectName(u'noInternetLabel') - self.noInternetLayout.addWidget(self.noInternetLabel) - FirstTimeWizard.setPage(FirstTimePage.NoInternet, self.noInternetPage) + self.no_internet_page = QtGui.QWizardPage() + self.no_internet_page.setObjectName(u'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(u'no_internet_layout') + self.no_internet_label = QtGui.QLabel(self.no_internet_page) + self.no_internet_label.setWordWrap(True) + self.no_internet_label.setObjectName(u'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 - self.songsPage = QtGui.QWizardPage() - self.songsPage.setObjectName(u'songsPage') - self.songsLayout = QtGui.QVBoxLayout(self.songsPage) - self.songsLayout.setContentsMargins(50, 20, 50, 20) - self.songsLayout.setObjectName(u'songsLayout') - self.songsListWidget = QtGui.QListWidget(self.songsPage) - self.songsListWidget.setAlternatingRowColors(True) - self.songsListWidget.setObjectName(u'songsListWidget') - self.songsLayout.addWidget(self.songsListWidget) - FirstTimeWizard.setPage(FirstTimePage.Songs, self.songsPage) + self.songs_page = QtGui.QWizardPage() + self.songs_page.setObjectName(u'songs_page') + self.songs_layout = QtGui.QVBoxLayout(self.songs_page) + self.songs_layout.setContentsMargins(50, 20, 50, 20) + self.songs_layout.setObjectName(u'songs_layout') + self.songs_list_widget = QtGui.QListWidget(self.songs_page) + self.songs_list_widget.setAlternatingRowColors(True) + self.songs_list_widget.setObjectName(u'songs_list_widget') + self.songs_layout.addWidget(self.songs_list_widget) + first_time_wizard.setPage(FirstTimePage.Songs, self.songs_page) # The Bible samples page - self.biblesPage = QtGui.QWizardPage() - self.biblesPage.setObjectName(u'biblesPage') - self.biblesLayout = QtGui.QVBoxLayout(self.biblesPage) - self.biblesLayout.setContentsMargins(50, 20, 50, 20) - self.biblesLayout.setObjectName(u'biblesLayout') - self.biblesTreeWidget = QtGui.QTreeWidget(self.biblesPage) - self.biblesTreeWidget.setAlternatingRowColors(True) - self.biblesTreeWidget.header().setVisible(False) - self.biblesTreeWidget.setObjectName(u'biblesTreeWidget') - self.biblesLayout.addWidget(self.biblesTreeWidget) - FirstTimeWizard.setPage(FirstTimePage.Bibles, self.biblesPage) + self.bibles_page = QtGui.QWizardPage() + self.bibles_page.setObjectName(u'bibles_page') + self.bibles_layout = QtGui.QVBoxLayout(self.bibles_page) + self.bibles_layout.setContentsMargins(50, 20, 50, 20) + self.bibles_layout.setObjectName(u'bibles_layout') + self.bibles_tree_widget = QtGui.QTreeWidget(self.bibles_page) + self.bibles_tree_widget.setAlternatingRowColors(True) + self.bibles_tree_widget.header().setVisible(False) + self.bibles_tree_widget.setObjectName(u'bibles_tree_widget') + self.bibles_layout.addWidget(self.bibles_tree_widget) + first_time_wizard.setPage(FirstTimePage.Bibles, self.bibles_page) # The theme samples page - self.themesPage = QtGui.QWizardPage() - self.themesPage.setObjectName(u'themesPage') - self.themesLayout = QtGui.QVBoxLayout(self.themesPage) - self.themesLayout.setContentsMargins(20, 50, 20, 60) - self.themesLayout.setObjectName(u'themesLayout') - self.themesListWidget = QtGui.QListWidget(self.themesPage) - self.themesListWidget.setViewMode(QtGui.QListView.IconMode) - self.themesListWidget.setMovement(QtGui.QListView.Static) - self.themesListWidget.setFlow(QtGui.QListView.LeftToRight) - self.themesListWidget.setSpacing(4) - self.themesListWidget.setUniformItemSizes(True) - self.themesListWidget.setIconSize(QtCore.QSize(133, 100)) - self.themesListWidget.setWrapping(False) - self.themesListWidget.setObjectName(u'themesListWidget') - self.themesLayout.addWidget(self.themesListWidget) - FirstTimeWizard.setPage(FirstTimePage.Themes, self.themesPage) + self.themes_page = QtGui.QWizardPage() + self.themes_page.setObjectName(u'themes_page') + self.themes_layout = QtGui.QVBoxLayout(self.themes_page) + self.themes_layout.setContentsMargins(20, 50, 20, 60) + self.themes_layout.setObjectName(u'themes_layout') + self.themes_list_widget = QtGui.QListWidget(self.themes_page) + self.themes_list_widget.setViewMode(QtGui.QListView.IconMode) + self.themes_list_widget.setMovement(QtGui.QListView.Static) + self.themes_list_widget.setFlow(QtGui.QListView.LeftToRight) + self.themes_list_widget.setSpacing(4) + self.themes_list_widget.setUniformItemSizes(True) + self.themes_list_widget.setIconSize(QtCore.QSize(133, 100)) + self.themes_list_widget.setWrapping(False) + self.themes_list_widget.setObjectName(u'themes_list_widget') + self.themes_layout.addWidget(self.themes_list_widget) + first_time_wizard.setPage(FirstTimePage.Themes, self.themes_page) # the default settings page - self.defaultsPage = QtGui.QWizardPage() - self.defaultsPage.setObjectName(u'defaultsPage') - self.defaultsLayout = QtGui.QFormLayout(self.defaultsPage) - self.defaultsLayout.setContentsMargins(50, 20, 50, 20) - self.defaultsLayout.setObjectName(u'defaultsLayout') - self.displayLabel = QtGui.QLabel(self.defaultsPage) - self.displayLabel.setObjectName(u'displayLabel') - self.displayComboBox = QtGui.QComboBox(self.defaultsPage) - self.displayComboBox.setEditable(False) - self.displayComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert) - self.displayComboBox.setObjectName(u'displayComboBox') - self.defaultsLayout.addRow(self.displayLabel, self.displayComboBox) - self.themeLabel = QtGui.QLabel(self.defaultsPage) - self.themeLabel.setObjectName(u'themeLabel') - self.themeComboBox = QtGui.QComboBox(self.defaultsPage) - self.themeComboBox.setEditable(False) - self.themeComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert) - self.themeComboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) - self.themeComboBox.setObjectName(u'themeComboBox') - self.defaultsLayout.addRow(self.themeLabel, self.themeComboBox) - FirstTimeWizard.setPage(FirstTimePage.Defaults, self.defaultsPage) + self.defaults_page = QtGui.QWizardPage() + self.defaults_page.setObjectName(u'defaults_page') + self.defaults_layout = QtGui.QFormLayout(self.defaults_page) + self.defaults_layout.setContentsMargins(50, 20, 50, 20) + self.defaults_layout.setObjectName(u'defaults_layout') + self.display_label = QtGui.QLabel(self.defaults_page) + self.display_label.setObjectName(u'display_label') + self.display_combo_box = QtGui.QComboBox(self.defaults_page) + self.display_combo_box.setEditable(False) + self.display_combo_box.setInsertPolicy(QtGui.QComboBox.NoInsert) + self.display_combo_box.setObjectName(u'display_combo_box') + self.defaults_layout.addRow(self.display_label, self.display_combo_box) + self.theme_label = QtGui.QLabel(self.defaults_page) + self.theme_label.setObjectName(u'theme_label') + self.theme_combo_box = QtGui.QComboBox(self.defaults_page) + self.theme_combo_box.setEditable(False) + self.theme_combo_box.setInsertPolicy(QtGui.QComboBox.NoInsert) + self.theme_combo_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) + self.theme_combo_box.setObjectName(u'theme_combo_box') + self.defaults_layout.addRow(self.theme_label, self.theme_combo_box) + first_time_wizard.setPage(FirstTimePage.Defaults, self.defaults_page) # Progress page - 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.progressLayout.addWidget(self.progressLabel) - self.progressBar = QtGui.QProgressBar(self.progressPage) - self.progressBar.setObjectName(u'progressBar') - self.progressLayout.addWidget(self.progressBar) - FirstTimeWizard.setPage(FirstTimePage.Progress, self.progressPage) - self.retranslateUi(FirstTimeWizard) + 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_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) + first_time_wizard.setPage(FirstTimePage.Progress, self.progress_page) + self.retranslateUi(first_time_wizard) - def retranslateUi(self, FirstTimeWizard): + def retranslateUi(self, first_time_wizard): """ Translate the UI on the fly """ - FirstTimeWizard.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'First Time Wizard')) + first_time_wizard.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'First Time Wizard')) self.title_label.setText(u'%s' % translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard')) self.information_label.setText(translate('OpenLP.FirstTimeWizard', 'This wizard will help you to configure OpenLP for initial use. Click the next button below to start.')) - self.pluginPage.setTitle(translate('OpenLP.FirstTimeWizard', 'Activate required Plugins')) - self.pluginPage.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select the Plugins you wish to use. ')) - self.songsCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Songs')) - self.customCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Custom Slides')) - self.bibleCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Bible')) - self.imageCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Images')) + 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.songs_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Songs')) + self.custom_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Custom Slides')) + self.bible_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Bible')) + self.image_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Images')) # TODO Presentation plugin is not yet working on Mac OS X. # For now just ignore it. if sys.platform != 'darwin': - self.presentationCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Presentations')) - self.mediaCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Media (Audio and Video)')) - self.remoteCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Allow remote access')) - self.songUsageCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Monitor Song Usage')) - self.alertCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Allow Alerts')) - self.noInternetPage.setTitle(translate('OpenLP.FirstTimeWizard', 'No Internet Connection')) - self.noInternetPage.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Unable to detect an Internet connection.')) - self.noInternetText = translate('OpenLP.FirstTimeWizard', - 'No Internet connection was found. The First Time Wizard needs an ' - 'Internet connection in order to be able to download sample ' - 'songs, Bibles and themes. Click the Finish button now to start ' - 'OpenLP with initial settings and no sample data.\n\nTo re-run the ' - 'First Time Wizard and import this sample data at a later time, ' - 'check your Internet connection and re-run this wizard by ' - 'selecting "Tools/Re-run First Time Wizard" from OpenLP.') + self.presentation_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Presentations')) + self.media_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Media (Audio and Video)')) + self.remote_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Allow remote access')) + self.song_usage_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Monitor Song Usage')) + self.alert_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Allow Alerts')) + self.no_internet_page.setTitle(translate('OpenLP.FirstTimeWizard', 'No Internet Connection')) + self.no_internet_page.setSubTitle( + translate('OpenLP.FirstTimeWizard', 'Unable to detect an Internet connection.')) + self.no_internet_text = translate('OpenLP.FirstTimeWizard', + 'No Internet connection was found. The First Time Wizard needs an Internet connection in order to be able ' + 'to download sample songs, Bibles and themes. Click the Finish button now to start OpenLP with initial ' + 'settings and no sample data.\n\nTo re-run the First Time Wizard and import this sample data at a later ' + 'time, check your Internet connection and re-run this wizard by selecting "Tools/Re-run First Time Wizard" ' + 'from OpenLP.') self.cancelWizardText = translate('OpenLP.FirstTimeWizard', '\n\nTo cancel the First Time Wizard completely (and not start OpenLP), click the Cancel button now.') - self.songsPage.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Songs')) - self.songsPage.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download public domain songs.')) - self.biblesPage.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Bibles')) - self.biblesPage.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download free Bibles.')) - self.themesPage.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Themes')) - self.themesPage.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download sample themes.')) - self.defaultsPage.setTitle(translate('OpenLP.FirstTimeWizard', 'Default Settings')) - self.defaultsPage.setSubTitle(translate('OpenLP.FirstTimeWizard', + self.songs_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Songs')) + self.songs_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download public domain songs.')) + self.bibles_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Bibles')) + self.bibles_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download free Bibles.')) + self.themes_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Sample Themes')) + self.themes_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select and download sample themes.')) + self.defaults_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Default Settings')) + self.defaults_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Set up default settings to be used by OpenLP.')) - self.displayLabel.setText(translate('OpenLP.FirstTimeWizard', 'Default output display:')) - self.themeLabel.setText(translate('OpenLP.FirstTimeWizard', 'Select default theme:')) - self.progressLabel.setText(translate('OpenLP.FirstTimeWizard', 'Starting configuration process...')) - FirstTimeWizard.setButtonText(QtGui.QWizard.CustomButton1, translate('OpenLP.FirstTimeWizard', 'Finish')) + self.display_label.setText(translate('OpenLP.FirstTimeWizard', 'Default output display:')) + self.theme_label.setText(translate('OpenLP.FirstTimeWizard', 'Select default theme:')) + self.progress_label.setText(translate('OpenLP.FirstTimeWizard', 'Starting configuration process...')) + first_time_wizard.setButtonText(QtGui.QWizard.CustomButton1, translate('OpenLP.FirstTimeWizard', 'Finish')) diff --git a/openlp/core/ui/listpreviewwidget.py b/openlp/core/ui/listpreviewwidget.py new file mode 100644 index 000000000..ae6d0bed8 --- /dev/null +++ b/openlp/core/ui/listpreviewwidget.py @@ -0,0 +1,173 @@ +# -*- 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:`listpreviewwidget` is a widget that lists the slides in the slide controller. +It is based on a QTableWidget but represents its contents in list form. +""" +from __future__ import division +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import ImageSource, Registry, ServiceItem + + +class ListPreviewWidget(QtGui.QTableWidget): + def __init__(self, parent, screen_ratio): + """ + Initializes the widget to default state. + An empty ServiceItem is used per default. + One needs to call replace_service_manager_item() to make this widget display something. + """ + super(QtGui.QTableWidget, self).__init__(parent) + # Set up the widget. + self.setColumnCount(1) + self.horizontalHeader().setVisible(False) + self.setColumnWidth(0, parent.width()) + self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) + self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.setAlternatingRowColors(True) + # Initialize variables. + self.service_item = ServiceItem() + self.screen_ratio = screen_ratio + + def resizeEvent(self, QResizeEvent): + """ + Overloaded method from QTableWidget. Will recalculate the layout. + """ + self.__recalculate_layout() + + def __recalculate_layout(self): + """ + Recalculates the layout of the table widget. It will set height and width + of the table cells. QTableWidget does not adapt the cells to the widget size on its own. + """ + self.setColumnWidth(0, self.viewport().width()) + if self.service_item: + # Sort out songs, bibles, etc. + if self.service_item.is_text(): + self.resizeRowsToContents() + else: + # Sort out image heights. + for framenumber in range(len(self.service_item.get_frames())): + height = self.viewport().width() // self.screen_ratio + self.setRowHeight(framenumber, height) + + def screen_size_changed(self, screen_ratio): + """ + To be called whenever the live screen size changes. + Because this makes a layout recalculation necessary. + """ + self.screen_ratio = screen_ratio + self.__recalculate_layout() + + def replace_service_item(self, service_item, width, slideNumber): + """ + Replaces the current preview items with the ones in service_item. + Displays the given slide. + """ + self.service_item = service_item + self.clear() + self.setRowCount(0) + self.setColumnWidth(0, width) + row = 0 + text = [] + for framenumber, frame in enumerate(self.service_item.get_frames()): + self.setRowCount(self.slide_count() + 1) + item = QtGui.QTableWidgetItem() + slide_height = 0 + if self.service_item.is_text(): + if frame[u'verseTag']: + # These tags are already translated. + verse_def = frame[u'verseTag'] + verse_def = u'%s%s' % (verse_def[0], verse_def[1:]) + two_line_def = u'%s\n%s' % (verse_def[0], verse_def[1:]) + row = two_line_def + else: + row += 1 + item.setText(frame[u'text']) + else: + label = QtGui.QLabel() + label.setMargin(4) + if self.service_item.is_media(): + label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) + else: + label.setScaledContents(True) + if self.service_item.is_command(): + label.setPixmap(QtGui.QPixmap(frame[u'image'])) + else: + image = self.image_manager.get_image(frame[u'path'], ImageSource.ImagePlugin) + label.setPixmap(QtGui.QPixmap.fromImage(image)) + self.setCellWidget(framenumber, 0, label) + slide_height = width // self.screen_ratio + row += 1 + text.append(unicode(row)) + self.setItem(framenumber, 0, item) + if slide_height: + self.setRowHeight(framenumber, slide_height) + self.setVerticalHeaderLabels(text) + if self.service_item.is_text(): + self.resizeRowsToContents() + self.setColumnWidth(0, self.viewport().width()) + self.setFocus() + self.change_slide(slideNumber) + + def change_slide(self, slide): + """ + Switches to the given row. + """ + if slide >= self.slide_count(): + slide = self.slide_count() - 1 + # Scroll to next item if possible. + if slide + 1 < self.slide_count(): + self.scrollToItem(self.item(slide + 1, 0)) + self.selectRow(slide) + + def current_slide_number(self): + """ + Returns the position of the currently active item. Will return -1 if the widget is empty. + """ + return super(ListPreviewWidget, self).currentRow() + + def slide_count(self): + """ + Returns the number of slides this widget holds. + """ + return super(ListPreviewWidget, self).rowCount() + + def _get_image_manager(self): + """ + Adds the image manager to the class dynamically. + """ + if not hasattr(self, u'_image_manager'): + self._image_manager = Registry().get(u'image_manager') + return self._image_manager + + image_manager = property(_get_image_manager) + diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 02ae469d6..4b99d38cd 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -38,6 +38,7 @@ Some of the code for this form is based on the examples at: from __future__ import division import cgi import logging +import os import sys from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL @@ -288,7 +289,7 @@ class MainDisplay(Display): self.image(path) # Update the preview frame. if self.is_live: - self.live_controller.updatePreview() + self.live_controller.update_preview() return True def image(self, path): @@ -327,6 +328,9 @@ class MainDisplay(Display): self.display_image(self.service_item.bg_image_bytes) else: self.display_image(None) + # Update the preview frame. + if self.is_live: + self.live_controller.update_preview() # clear the cache self.override = {} @@ -494,11 +498,15 @@ class MainDisplay(Display): def _get_application(self): """ - Adds the openlp to the class dynamically + Adds the openlp to the class dynamically. + Windows needs to access the application in a dynamic manner. """ - if not hasattr(self, u'_application'): - self._application = Registry().get(u'application') - return self._application + if os.name == u'nt': + return Registry().get(u'application') + else: + if not hasattr(self, u'_application'): + self._application = Registry().get(u'application') + return self._application application = property(_get_application) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 6b86bfe7a..307239032 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -100,10 +100,10 @@ class Ui_MainWindow(object): self.main_contentLayout.setMargin(0) self.main_contentLayout.setObjectName(u'main_contentLayout') main_window.setCentralWidget(self.main_content) - self.controlSplitter = QtGui.QSplitter(self.main_content) - self.controlSplitter.setOrientation(QtCore.Qt.Horizontal) - self.controlSplitter.setObjectName(u'controlSplitter') - self.main_contentLayout.addWidget(self.controlSplitter) + self.control_splitter = QtGui.QSplitter(self.main_content) + self.control_splitter.setOrientation(QtCore.Qt.Horizontal) + self.control_splitter.setObjectName(u'control_splitter') + self.main_contentLayout.addWidget(self.control_splitter) # Create slide controllers self.preview_controller = SlideController(self) self.live_controller = SlideController(self, True) @@ -113,9 +113,9 @@ class Ui_MainWindow(object): panel_locked = Settings().value(u'user interface/lock panel') self.live_controller.panel.setVisible(live_visible) # Create menu - self.menuBar = QtGui.QMenuBar(main_window) - self.menuBar.setObjectName(u'menuBar') - self.file_menu = QtGui.QMenu(self.menuBar) + self.menu_bar = QtGui.QMenuBar(main_window) + self.menu_bar.setObjectName(u'menu_bar') + self.file_menu = QtGui.QMenu(self.menu_bar) self.file_menu.setObjectName(u'fileMenu') self.recent_files_menu = QtGui.QMenu(self.file_menu) self.recent_files_menu.setObjectName(u'recentFilesMenu') @@ -124,22 +124,22 @@ class Ui_MainWindow(object): self.file_export_menu = QtGui.QMenu(self.file_menu) self.file_export_menu.setObjectName(u'file_export_menu') # View Menu - self.view_menu = QtGui.QMenu(self.menuBar) + self.view_menu = QtGui.QMenu(self.menu_bar) self.view_menu.setObjectName(u'viewMenu') self.view_modeMenu = QtGui.QMenu(self.view_menu) self.view_modeMenu.setObjectName(u'viewModeMenu') # Tools Menu - self.tools_menu = QtGui.QMenu(self.menuBar) + self.tools_menu = QtGui.QMenu(self.menu_bar) self.tools_menu.setObjectName(u'tools_menu') # Settings Menu - self.settings_menu = QtGui.QMenu(self.menuBar) + self.settings_menu = QtGui.QMenu(self.menu_bar) self.settings_menu.setObjectName(u'settingsMenu') self.settings_language_menu = QtGui.QMenu(self.settings_menu) self.settings_language_menu.setObjectName(u'settingsLanguageMenu') # Help Menu - self.help_menu = QtGui.QMenu(self.menuBar) + self.help_menu = QtGui.QMenu(self.menu_bar) self.help_menu.setObjectName(u'helpMenu') - main_window.setMenuBar(self.menuBar) + main_window.setMenuBar(self.menu_bar) self.status_bar = QtGui.QStatusBar(main_window) self.status_bar.setObjectName(u'status_bar') main_window.setStatusBar(self.status_bar) @@ -237,7 +237,7 @@ class Ui_MainWindow(object): self.view_live_panel = create_action(main_window, u'viewLivePanel', can_shortcuts=True, checked=live_visible, category=UiStrings().View, triggers=self.set_live_panel_visibility) - self.lockPanel = create_action(main_window, u'lockPanel', + self.lock_panel = create_action(main_window, u'lockPanel', can_shortcuts=True, checked=panel_locked, category=UiStrings().View, triggers=self.set_lock_panel) @@ -310,6 +310,10 @@ class Ui_MainWindow(object): can_shortcuts=True, category=UiStrings().Help, triggers=self.on_online_help_clicked) self.web_site_item = create_action(main_window, u'webSiteItem', can_shortcuts=True, category=UiStrings().Help) + # Shortcuts not connected to buttons or menu entires. + self.search_shortcut_action = create_action(main_window, + u'searchShortcut', can_shortcuts=True, category=translate('OpenLP.MainWindow', 'General'), + triggers=self.on_search_shortcut_triggered) add_actions(self.file_import_menu, (self.settings_import_item, None, self.import_theme_item, self.import_language_item)) add_actions(self.file_export_menu, (self.settings_export_item, None, self.export_theme_item, @@ -321,7 +325,7 @@ class Ui_MainWindow(object): add_actions(self.view_modeMenu, (self.mode_default_Item, self.mode_setup_item, self.mode_live_item)) add_actions(self.view_menu, (self.view_modeMenu.menuAction(), None, self.view_media_manager_item, self.view_service_manager_item, self.view_theme_manager_item, None, self.view_preview_panel, - self.view_live_panel, None, self.lockPanel)) + self.view_live_panel, None, self.lock_panel)) # i18n add Language Actions add_actions(self.settings_language_menu, (self.auto_language_item, None)) add_actions(self.settings_language_menu, self.language_group.actions()) @@ -342,8 +346,9 @@ class Ui_MainWindow(object): self.about_item)) else: add_actions(self.help_menu, (self.on_line_help_item, None, self.web_site_item, self.about_item)) - add_actions(self.menuBar, (self.file_menu.menuAction(), self.view_menu.menuAction(), + add_actions(self.menu_bar, (self.file_menu.menuAction(), self.view_menu.menuAction(), self.tools_menu.menuAction(), self.settings_menu.menuAction(), self.help_menu.menuAction())) + add_actions(self, [self.search_shortcut_action]) # Initialise the translation self.retranslateUi(main_window) self.media_tool_box.setCurrentIndex(0) @@ -356,12 +361,11 @@ class Ui_MainWindow(object): self.set_lock_panel(panel_locked) self.settingsImported = False - def retranslateUi(self, mainWindow): + def retranslateUi(self, main_window): """ Set up the translation system """ - mainWindow.mainTitle = UiStrings().OLPV2x - mainWindow.setWindowTitle(mainWindow.mainTitle) + main_window.setWindowTitle(UiStrings().OLPV2x) self.file_menu.setTitle(translate('OpenLP.MainWindow', '&File')) self.file_import_menu.setTitle(translate('OpenLP.MainWindow', '&Import')) self.file_export_menu.setTitle(translate('OpenLP.MainWindow', '&Export')) @@ -423,8 +427,8 @@ class Ui_MainWindow(object): translate('OpenLP.MainWindow', 'Toggle the visibility of the preview panel.')) self.view_live_panel.setText(translate('OpenLP.MainWindow', '&Live Panel')) self.view_live_panel.setToolTip(translate('OpenLP.MainWindow', 'Toggle Live Panel')) - self.lockPanel.setText(translate('OpenLP.MainWindow', 'L&ock Panels')) - self.lockPanel.setStatusTip(translate('OpenLP.MainWindow', 'Prevent the panels being moved.')) + self.lock_panel.setText(translate('OpenLP.MainWindow', 'L&ock Panels')) + self.lock_panel.setStatusTip(translate('OpenLP.MainWindow', 'Prevent the panels being moved.')) self.view_live_panel.setStatusTip(translate('OpenLP.MainWindow', 'Toggle the visibility of the live panel.')) self.settingsPluginListItem.setText(translate('OpenLP.MainWindow', '&Plugin List')) self.settingsPluginListItem.setStatusTip(translate('OpenLP.MainWindow', 'List the Plugins')) @@ -433,6 +437,9 @@ class Ui_MainWindow(object): if os.name == u'nt': self.offlineHelpItem.setText(translate('OpenLP.MainWindow', '&User Guide')) self.on_line_help_item.setText(translate('OpenLP.MainWindow', '&Online Help')) + self.search_shortcut_action.setText(UiStrings().Search) + self.search_shortcut_action.setToolTip( + translate('OpenLP.MainWindow', 'Jump to the search box of the current active plugin.')) self.web_site_item.setText(translate('OpenLP.MainWindow', '&Web Site')) for item in self.language_group.actions(): item.setText(item.objectName()) @@ -467,8 +474,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def __init__(self): """ - This constructor sets up the interface, the various managers, and the - plugins. + This constructor sets up the interface, the various managers, and the plugins. """ QtGui.QMainWindow.__init__(self) Registry().register(u'main_window', self) @@ -491,7 +497,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.new_data_path = None self.copy_data = False Settings().set_up_default_values() - self.service_not_saved = False self.about_form = AboutForm(self) self.media_controller = MediaController() self.settings_form = SettingsForm(self) @@ -536,22 +541,31 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Registry().register_function(u'theme_update_global', self.default_theme_changed) Registry().register_function(u'openlp_version_check', self.version_notice) Registry().register_function(u'config_screen_changed', self.screen_changed) + Registry().register_function(u'bootstrap_post_set_up', self.restore_current_media_manager_item) self.renderer = Renderer() - log.info(u'Load data from Settings') - if Settings().value(u'advanced/save current plugin'): - savedPlugin = Settings().value(u'advanced/current media plugin') - if savedPlugin != -1: - self.media_tool_box.setCurrentIndex(savedPlugin) # Reset the cursor self.application.set_normal_cursor() - def setAutoLanguage(self, value): + def restore_current_media_manager_item(self): """ - Set the language to automatic. + Called on start up to restore the last active media plugin. """ - self.language_group.setDisabled(value) - LanguageManager.auto_language = value - LanguageManager.set_language(self.language_group.checkedAction()) + log.info(u'Load data from Settings') + if Settings().value(u'advanced/save current plugin'): + saved_plugin_id = Settings().value(u'advanced/current media plugin') + if saved_plugin_id != -1: + self.media_tool_box.setCurrentIndex(saved_plugin_id) + + def on_search_shortcut_triggered(self): + """ + Called when the search shotcut has been pressed. + """ + # Make sure the media_dock is visible. + if not self.media_manager_dock.isVisible(): + self.media_manager_dock.setVisible(True) + widget = self.media_tool_box.currentWidget() + if widget: + widget.on_focus() def on_media_tool_box_changed(self, index): """ @@ -669,7 +683,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Check and display message if screen blank on setup. """ settings = Settings() - self.live_controller.mainDisplaySetBackground() + self.live_controller.main_display_set_background() if settings.value(u'%s/screen blank' % self.general_settings_section): if settings.value(u'%s/blank warning' % self.general_settings_section): QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Main Display Blanked'), @@ -966,8 +980,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ self.setViewMode(False, True, False, False, True, u'live') - def setViewMode(self, media=True, service=True, theme=True, preview=True, - live=True, mode=u''): + def setViewMode(self, media=True, service=True, theme=True, preview=True, live=True, mode=u''): """ Set OpenLP to a different view mode. """ @@ -982,8 +995,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def screen_changed(self): """ - The screen has changed so we have to update components such as the - renderer. + The screen has changed so we have to update components such as the renderer. """ log.debug(u'screen_changed') self.application.set_busy_cursor() @@ -1064,44 +1076,24 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): if self.live_controller.display: self.live_controller.display.close() self.live_controller.display = None + if os.name == u'nt': + # Needed for Windows to stop crashes on exit + Registry().remove(u'application') - def service_changed(self, reset=False, serviceName=None): + def set_service_modified(self, modified, file_name): """ - Hook to change the main window title when the service changes - - ``reset`` - Shows if the service has been cleared or saved - - ``serviceName`` - The name of the service (if it has one) - """ - if not serviceName: - service_name = u'(unsaved service)' - else: - service_name = serviceName - if reset: - self.service_not_saved = False - title = u'%s - %s' % (self.mainTitle, service_name) - else: - self.service_not_saved = True - title = u'%s - %s*' % (self.mainTitle, service_name) - self.setWindowTitle(title) - - def set_service_modified(self, modified, fileName): - """ - This method is called from the ServiceManager to set the title of the - main window. + This method is called from the ServiceManager to set the title of the main window. ``modified`` Whether or not this service has been modified. - ``fileName`` + ``file_name`` The file name of the service file. """ if modified: - title = u'%s - %s*' % (self.mainTitle, fileName) + title = u'%s - %s*' % (UiStrings().OLPV2x, file_name) else: - title = u'%s - %s' % (self.mainTitle, fileName) + title = u'%s - %s' % (UiStrings().OLPV2x, file_name) self.setWindowTitle(title) def show_status_message(self, message): @@ -1137,8 +1129,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def set_preview_panel_visibility(self, visible): """ - Sets the visibility of the preview panel including saving the setting - and updating the menu. + Sets the visibility of the preview panel including saving the setting and updating the menu. ``visible`` A bool giving the state to set the panel to @@ -1175,8 +1166,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def set_live_panel_visibility(self, visible): """ - Sets the visibility of the live panel including saving the setting and - updating the menu. + Sets the visibility of the live panel including saving the setting and updating the menu. ``visible`` A bool giving the state to set the panel to @@ -1205,7 +1195,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.restoreState(settings.value(u'main window state')) self.live_controller.splitter.restoreState(settings.value(u'live splitter geometry')) self.preview_controller.splitter.restoreState(settings.value(u'preview splitter geometry')) - self.controlSplitter.restoreState(settings.value(u'main window splitter geometry')) + self.control_splitter.restoreState(settings.value(u'main window splitter geometry')) settings.endGroup() def save_settings(self): @@ -1226,13 +1216,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): settings.setValue(u'main window geometry', self.saveGeometry()) settings.setValue(u'live splitter geometry', self.live_controller.splitter.saveState()) settings.setValue(u'preview splitter geometry', self.preview_controller.splitter.saveState()) - settings.setValue(u'main window splitter geometry', self.controlSplitter.saveState()) + settings.setValue(u'main window splitter geometry', self.control_splitter.saveState()) settings.endGroup() def update_recent_files_menu(self): """ - Updates the recent file menu with the latest list of service files - accessed. + Updates the recent file menu with the latest list of service files accessed. """ recent_file_count = Settings().value(u'advanced/recent file count') existing_recent_files = [recentFile for recentFile in self.recent_files @@ -1374,10 +1363,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def _get_application(self): """ - Adds the openlp to the class dynamically + Adds the openlp to the class dynamically. + Windows needs to access the application in a dynamic manner. """ - if not hasattr(self, u'_application'): - self._application = Registry().get(u'application') - return self._application + if os.name == u'nt': + return Registry().get(u'application') + else: + if not hasattr(self, u'_application'): + self._application = Registry().get(u'application') + return self._application application = property(_get_application) diff --git a/openlp/core/ui/media/mediaplayer.py b/openlp/core/ui/media/mediaplayer.py index c1f060f60..5d9e3663f 100644 --- a/openlp/core/ui/media/mediaplayer.py +++ b/openlp/core/ui/media/mediaplayer.py @@ -29,6 +29,8 @@ """ The :mod:`~openlp.core.ui.media.mediaplayer` module contains the MediaPlayer class. """ +import os + from openlp.core.lib import Registry from openlp.core.ui.media import MediaState @@ -153,10 +155,14 @@ class MediaPlayer(object): def _get_application(self): """ - Adds the openlp to the class dynamically + Adds the openlp to the class dynamically. + Windows needs to access the application in a dynamic manner. """ - if not hasattr(self, u'_application'): - self._application = Registry().get(u'application') - return self._application + if os.name == u'nt': + return Registry().get(u'application') + else: + if not hasattr(self, u'_application'): + self._application = Registry().get(u'application') + return self._application application = property(_get_application) \ No newline at end of file diff --git a/openlp/core/ui/media/webkitplayer.py b/openlp/core/ui/media/webkitplayer.py index f2dbfe5dc..e534a974b 100644 --- a/openlp/core/ui/media/webkitplayer.py +++ b/openlp/core/ui/media/webkitplayer.py @@ -44,113 +44,57 @@ VIDEO_CSS = u""" z-index:3; background-color: %(bgcolor)s; } -#video1 { - background-color: %(bgcolor)s; - z-index:4; -} -#video2 { +#video { background-color: %(bgcolor)s; z-index:4; } """ VIDEO_JS = u""" - var video_timer = null; - var current_video = '1'; + function show_video(state, path, volume, loop, variable_value){ + // Sometimes video.currentTime stops slightly short of video.duration and video.ended is intermittent! - function show_video(state, path, volume, loop, varVal){ - // Note, the preferred method for looping would be to use the - // video tag loop attribute. - // But QtWebKit doesn't support this. Neither does it support the - // onended event, hence the setInterval() - // In addition, setting the currentTime attribute to zero to restart - // the video raises an INDEX_SIZE_ERROR: DOM Exception 1 - // To complicate it further, sometimes vid.currentTime stops - // slightly short of vid.duration and vid.ended is intermittent! - // - // Note, currently the background may go black between loops. Not - // desirable. Need to investigate using two