diff --git a/documentation/SongFormat.txt b/documentation/SongFormat.txt deleted file mode 100644 index 31b202dd6..000000000 --- a/documentation/SongFormat.txt +++ /dev/null @@ -1,124 +0,0 @@ -openlp.org 2.x Song Database Structure -======================================================================== - -Introduction ------------- -The song database in openlp.org 2.x is similar to the 1.x format. The -biggest differences are the addition of extra tables, and the use of -SQLite version 3. - -The song database contains the following tables: -- authors -- authors_songs -- song_books -- songs -- songs_topics -- topics - - -"authors" Table ---------------- -This table holds the names of all the authors. It has the following -columns: - -* id -* first_name -* last_name -* display_name - - -"authors_songs" Table ---------------------- -This is a bridging table between the "authors" and "songs" tables, which -serves to create a many-to-many relationship between the two tables. It -has the following columns: - -* author_id -* song_id - - -"song_books" Table ------------------- -The "song_books" table holds a list of books that a congregation gets -their songs from, or old hymnals now no longer used. This table has the -following columns: - -* id -* name -* publisher - - -"songs" Table -------------- -This table contains the songs, and each song has a list of attributes. -The "songs" table has the following columns: - -* id -* song_book_id -* title -* lyrics -* verse_order -* copyright -* comments -* ccli_number -* song_number -* theme_name -* search_title -* search_lyrics - - -"songs_topics" Table --------------------- -This is a bridging table between the "songs" and "topics" tables, which -serves to create a many-to-many relationship between the two tables. It -has the following columns: - -* song_id -* topic_id - - -"topics" Table --------------- -The topics table holds a selection of topics that songs can cover. This -is useful when a worship leader wants to select songs with a certain -theme. This table has the following columns: - -* id -* name - - -The lyrics definition (more or less similar to interformat to/from ChangingSong -The tags can also be used within the lyrics test. - -! Please note that this format has been checked at http://validator.w3.org/#validate_by_upload - - - Amazing Grace - - name of verse specific theme (optional) - any text (optional) - - Amazing grace, how ... - - - A b c - D e f - - ... - - - name of verse specific theme (optional) - any text (optional) - ... - - - - Erstaunliche Anmut - - Erstaunliche Anmut, wie - ... - - - ... - - diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 7dd74efb0..39c37e2a9 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -245,7 +245,7 @@ class MediaManagerItem(QtGui.QWidget): preview_string[u'title'], preview_string[u'tooltip'], u':/general/general_preview.png', self.onPreviewClick) - ## Live Button ## + ## Live Button ## live_string = self.plugin.getString(StringContent.Live) self.addToolbarButton( live_string[u'title'], @@ -507,7 +507,7 @@ class MediaManagerItem(QtGui.QWidget): 'No Service Item Selected'), translate('OpenLP.MediaManagerItem', 'You must select an existing service item to add to.')) - elif self.title.lower() == serviceItem.name.lower(): + elif self.plugin.name.lower() == serviceItem.name.lower(): self.generateSlideData(serviceItem) self.parent.serviceManager.addServiceItem(serviceItem, replace=True) @@ -536,3 +536,25 @@ class MediaManagerItem(QtGui.QWidget): individual service items need to be processed by the plugins """ pass + + def _getIdOfItemToGenerate(self, item, remoteItem): + """ + Utility method to check items being submitted for slide generation. + + ``item`` + The item to check. + + ``remoteItem`` + The id to assign if the slide generation was remotely triggered. + """ + if item is None: + if self.remoteTriggered is None: + item = self.listView.currentItem() + if item is None: + return False + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + else: + item_id = remoteItem + else: + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + return item_id diff --git a/openlp/core/lib/plugin.py b/openlp/core/lib/plugin.py index 5a3fa41ce..fb31006b5 100644 --- a/openlp/core/lib/plugin.py +++ b/openlp/core/lib/plugin.py @@ -42,6 +42,7 @@ class PluginStatus(object): Inactive = 0 Disabled = -1 + class StringContent(object): Name = u'name' Import = u'import' @@ -54,6 +55,7 @@ class StringContent(object): Service = u'service' VisibleName = u'visible_name' + class Plugin(QtCore.QObject): """ Base class for openlp plugins to inherit from. @@ -116,7 +118,7 @@ class Plugin(QtCore.QObject): class MyPlugin(Plugin): def __init__(self): - Plugin.__init(self, u'MyPlugin', u'0.1') + Plugin.__init__(self, u'MyPlugin', u'0.1') ``name`` Defaults to *None*. The name of the plugin. diff --git a/openlp/core/lib/searchedit.py b/openlp/core/lib/searchedit.py index c69e1f15b..5e12dcefd 100644 --- a/openlp/core/lib/searchedit.py +++ b/openlp/core/lib/searchedit.py @@ -93,15 +93,15 @@ class SearchEdit(QtGui.QLineEdit): ``event`` The event that happened. """ - sz = self.clearButton.size() + size = self.clearButton.size() frameWidth = self.style().pixelMetric( QtGui.QStyle.PM_DefaultFrameWidth) - self.clearButton.move(self.rect().right() - frameWidth - sz.width(), - (self.rect().bottom() + 1 - sz.height()) / 2) + self.clearButton.move(self.rect().right() - frameWidth - size.width(), + (self.rect().bottom() + 1 - size.height()) / 2) if hasattr(self, u'menuButton'): - sz = self.menuButton.size() + size = self.menuButton.size() self.menuButton.move(self.rect().left() + frameWidth + 2, - (self.rect().bottom() + 1 - sz.height()) / 2) + (self.rect().bottom() + 1 - size.height()) / 2) def currentSearchType(self): """ diff --git a/openlp/core/lib/theme.py b/openlp/core/lib/theme.py index 70517b34d..d119f19ff 100644 --- a/openlp/core/lib/theme.py +++ b/openlp/core/lib/theme.py @@ -91,21 +91,30 @@ class ThemeLevel(object): Song = 3 class BackgroundType(object): + """ + Type enumeration for backgrounds. + """ Solid = 0 Gradient = 1 Image = 2 @staticmethod - def to_string(type): - if type == BackgroundType.Solid: + def to_string(background_type): + """ + Return a string representation of a background type. + """ + if background_type == BackgroundType.Solid: return u'solid' - elif type == BackgroundType.Gradient: + elif background_type == BackgroundType.Gradient: return u'gradient' - elif type == BackgroundType.Image: + elif background_type == BackgroundType.Image: return u'image' @staticmethod def from_string(type_string): + """ + Return a background type for the given string. + """ if type_string == u'solid': return BackgroundType.Solid elif type_string == u'gradient': @@ -114,6 +123,9 @@ class BackgroundType(object): return BackgroundType.Image class BackgroundGradientType(object): + """ + Type enumeration for background gradients. + """ Horizontal = 0 Vertical = 1 Circular = 2 @@ -121,20 +133,26 @@ class BackgroundGradientType(object): LeftBottom = 4 @staticmethod - def to_string(type): - if type == BackgroundGradientType.Horizontal: + def to_string(gradient_type): + """ + Return a string representation of a background gradient type. + """ + if gradient_type == BackgroundGradientType.Horizontal: return u'horizontal' - elif type == BackgroundGradientType.Vertical: + elif gradient_type == BackgroundGradientType.Vertical: return u'vertical' - elif type == BackgroundGradientType.Circular: + elif gradient_type == BackgroundGradientType.Circular: return u'circular' - elif type == BackgroundGradientType.LeftTop: + elif gradient_type == BackgroundGradientType.LeftTop: return u'leftTop' - elif type == BackgroundGradientType.LeftBottom: + elif gradient_type == BackgroundGradientType.LeftBottom: return u'leftBottom' @staticmethod def from_string(type_string): + """ + Return a background gradient type for the given string. + """ if type_string == u'horizontal': return BackgroundGradientType.Horizontal elif type_string == u'vertical': @@ -147,19 +165,25 @@ class BackgroundGradientType(object): return BackgroundGradientType.LeftBottom class HorizontalType(object): + """ + Type enumeration for horizontal alignment. + """ Left = 0 Center = 1 Right = 2 class VerticalType(object): + """ + Type enumeration for vertical alignment. + """ Top = 0 Middle = 1 Bottom = 2 -boolean_list = [u'italics', u'override', u'outline', u'shadow', +BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow', u'slide_transition'] -integer_list = [u'size', u'line_adjustment', u'x', u'height', u'y', +INTEGER_LIST = [u'size', u'line_adjustment', u'x', u'height', u'y', u'width', u'shadow_size', u'outline_size', u'horizontal_align', u'vertical_align', u'wrap_style'] @@ -514,9 +538,9 @@ class ThemeXML(object): return field = self._de_hump(element) tag = master + u'_' + field - if field in boolean_list: + if field in BOOLEAN_LIST: setattr(self, tag, str_to_bool(value)) - elif field in integer_list: + elif field in INTEGER_LIST: setattr(self, tag, int(value)) else: # make string value unicode diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py new file mode 100644 index 000000000..8cfffef45 --- /dev/null +++ b/openlp/core/lib/ui.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2011 Raoul Snyman # +# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # +# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard, Frode Woldsund # +# --------------------------------------------------------------------------- # +# 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:`ui` module provides standard UI components for OpenLP. +""" +import logging + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import translate + +log = logging.getLogger(__name__) + +def add_welcome_page(parent, image): + """ + Generate an opening welcome page for a wizard using a provided image. + + ``image`` + A splash image for the wizard. + """ + parent.welcomePage = QtGui.QWizardPage() + parent.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(image)) + parent.welcomePage.setObjectName(u'WelcomePage') + parent.welcomeLayout = QtGui.QVBoxLayout(parent.welcomePage) + parent.welcomeLayout.setObjectName(u'WelcomeLayout') + parent.titleLabel = QtGui.QLabel(parent.welcomePage) + parent.titleLabel.setObjectName(u'TitleLabel') + parent.welcomeLayout.addWidget(parent.titleLabel) + parent.welcomeLayout.addSpacing(40) + parent.informationLabel = QtGui.QLabel(parent.welcomePage) + parent.informationLabel.setWordWrap(True) + parent.informationLabel.setObjectName(u'InformationLabel') + parent.welcomeLayout.addWidget(parent.informationLabel) + parent.welcomeLayout.addStretch() + parent.addPage(parent.welcomePage) + +def save_cancel_button_box(parent): + """ + Return a standard dialog button box with save and cancel buttons. + """ + button_box = QtGui.QDialogButtonBox(parent) + button_box.setStandardButtons( + QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel) + button_box.setObjectName(u'%sButtonBox' % parent) + QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'accepted()'), + parent.accept) + QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'rejected()'), + parent.reject) + return button_box + +def critical_error_message_box(title=None, message=None, parent=None, + question=False): + """ + Provides a standard critical message box for errors that OpenLP displays + to users. + + ``title`` + The title for the message box. + + ``message`` + The message to display to the user. + + ``parent`` + The parent UI element to attach the dialog to. + + ``question`` + Should this message box question the user. + """ + error = translate('OpenLP.Ui', 'Error') + if question: + return QtGui.QMessageBox.critical(parent, error, message, + QtGui.QMessageBox.StandardButtons( + QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) + data = {u'message': message} + data[u'title'] = title if title else error + return Receiver.send_message(u'openlp_error_message', data) + +def media_item_combo_box(parent, name): + """ + Provide a standard combo box for media items. + """ + combo = QtGui.QComboBox(parent) + combo.setObjectName(name) + combo.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength) + combo.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) + return combo diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 80124c2be..eb0e89775 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -51,34 +51,6 @@ class HideMode(object): Theme = 2 Screen = 3 - -def criticalErrorMessageBox(title=None, message=None, parent=None, - question=False): - """ - Provides a standard critical message box for errors that OpenLP displays - to users. - - ``title`` - The title for the message box. - - ``message`` - The message to display to the user. - - ``parent`` - The parent UI element to attach the dialog to. - - ``question`` - Should this message box question the user. - """ - error = translate('OpenLP.Ui', 'Error') - if question: - return QtGui.QMessageBox.critical(parent, error, message, - QtGui.QMessageBox.StandardButtons( - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) - data = {u'message': message} - data[u'title'] = title if title else error - return Receiver.send_message(u'openlp_error_message', data) - from themeform import ThemeForm from filerenameform import FileRenameForm from maindisplay import MainDisplay @@ -99,6 +71,6 @@ from mediadockmanager import MediaDockManager from servicemanager import ServiceManager from thememanager import ThemeManager -__all__ = ['criticalErrorMessageBox', 'SplashScreen', 'AboutForm', - 'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager', - 'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm'] +__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay', + 'SlideController', 'ServiceManager', 'ThemeManager', 'MediaDockManager', + 'ServiceItemEditForm'] diff --git a/openlp/core/ui/advancedtab.py b/openlp/core/ui/advancedtab.py index db6efcf4c..f68131894 100644 --- a/openlp/core/ui/advancedtab.py +++ b/openlp/core/ui/advancedtab.py @@ -141,7 +141,8 @@ class AdvancedTab(SettingsTab): 'Hide the mouse cursor when moved over the display window')) self.serviceOrderGroupBox.setTitle(translate('OpenLP.AdvancedTab', 'Service Order Print')) - self.detailedServicePrintCheckBox.setText(translate('OpenLP.AdvancedTab', + self.detailedServicePrintCheckBox.setText( + translate('OpenLP.AdvancedTab', 'Print slide texts and service item notes as well')) # self.sharedDirGroupBox.setTitle( # translate('AdvancedTab', 'Central Data Store')) diff --git a/openlp/core/ui/displaytagtab.py b/openlp/core/ui/displaytagtab.py index 1c77084b9..983bc17a8 100644 --- a/openlp/core/ui/displaytagtab.py +++ b/openlp/core/ui/displaytagtab.py @@ -34,7 +34,7 @@ import cPickle from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab, translate, DisplayTags -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box class DisplayTagTab(SettingsTab): ''' @@ -276,7 +276,7 @@ class DisplayTagTab(SettingsTab): """ for html in DisplayTags.get_html_tags(): if self._strip(html[u'start tag']) == u'n': - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.DisplayTagTab', 'Update Error'), translate('OpenLP.DisplayTagTab', 'Tag "n" already defined.')) @@ -317,7 +317,7 @@ class DisplayTagTab(SettingsTab): for linenumber, html1 in enumerate(html_expands): if self._strip(html1[u'start tag']) == tag and \ linenumber != self.selected: - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.DisplayTagTab', 'Update Error'), unicode(translate('OpenLP.DisplayTagTab', 'Tag %s already defined.')) % tag) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 8477ccc24..6f57861c4 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -87,10 +87,10 @@ class Ui_MainWindow(object): self.screens, True) previewVisible = QtCore.QSettings().value( u'user interface/preview panel', QtCore.QVariant(True)).toBool() - self.previewController.Panel.setVisible(previewVisible) + self.previewController.panel.setVisible(previewVisible) liveVisible = QtCore.QSettings().value(u'user interface/live panel', QtCore.QVariant(True)).toBool() - self.liveController.Panel.setVisible(liveVisible) + self.liveController.panel.setVisible(liveVisible) # Create menu self.MenuBar = QtGui.QMenuBar(mainWindow) self.MenuBar.setObjectName(u'MenuBar') @@ -771,34 +771,29 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ Put OpenLP into "Default" view mode. """ - settings = QtCore.QSettings() - settings.setValue(u'%s/view mode' % self.generalSettingsSection, - u'default') - self.setViewMode(True, True, True, True, True) + self.setViewMode(True, True, True, True, True, u'default') def onModeSetupItemClicked(self): """ Put OpenLP into "Setup" view mode. """ - settings = QtCore.QSettings() - settings.setValue(u'%s/view mode' % self.generalSettingsSection, - u'setup') - self.setViewMode(True, True, False, True, False) + self.setViewMode(True, True, False, True, False, u'setup') def onModeLiveItemClicked(self): """ Put OpenLP into "Live" view mode. """ - settings = QtCore.QSettings() - settings.setValue(u'%s/view mode' % self.generalSettingsSection, - u'live') - self.setViewMode(False, True, False, False, True) + self.setViewMode(False, True, False, False, True, u'live') def setViewMode(self, media=True, service=True, theme=True, preview=True, - live=True): + live=True, mode=u''): """ Set OpenLP to a different view mode. """ + if mode: + settings = QtCore.QSettings() + settings.setValue(u'%s/view mode' % self.generalSettingsSection, + mode) self.MediaManagerDock.setVisible(media) self.ServiceManagerDock.setVisible(service) self.ThemeManagerDock.setVisible(theme) @@ -939,7 +934,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): True - Visible False - Hidden """ - self.previewController.Panel.setVisible(visible) + self.previewController.panel.setVisible(visible) QtCore.QSettings().setValue(u'user interface/preview panel', QtCore.QVariant(visible)) self.ViewPreviewPanel.setChecked(visible) @@ -954,7 +949,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): True - Visible False - Hidden """ - self.liveController.Panel.setVisible(visible) + self.liveController.panel.setVisible(visible) QtCore.QSettings().setValue(u'user interface/live panel', QtCore.QVariant(visible)) self.ViewLivePanel.setChecked(visible) diff --git a/openlp/core/ui/serviceitemeditdialog.py b/openlp/core/ui/serviceitemeditdialog.py index 3e1079ded..d4c86fa61 100644 --- a/openlp/core/ui/serviceitemeditdialog.py +++ b/openlp/core/ui/serviceitemeditdialog.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate, build_icon +from openlp.core.lib.ui import save_cancel_button_box class Ui_ServiceItemEditDialog(object): def setupUi(self, serviceItemEditDialog): @@ -52,12 +53,8 @@ class Ui_ServiceItemEditDialog(object): self.downButton.setObjectName(u'downButton') self.buttonLayout.addWidget(self.downButton) self.dialogLayout.addLayout(self.buttonLayout, 0, 1) - self.buttonBox = QtGui.QDialogButtonBox(serviceItemEditDialog) - self.buttonBox.setStandardButtons( - QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Save) - self.buttonBox.setObjectName(u'buttonBox') - self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2) - + self.dialogLayout.addWidget( + save_cancel_button_box(serviceItemEditDialog), 1, 0, 1, 2) self.retranslateUi(serviceItemEditDialog) QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog) diff --git a/openlp/core/ui/serviceitemeditform.py b/openlp/core/ui/serviceitemeditform.py index edd4ee29f..0621a44bd 100644 --- a/openlp/core/ui/serviceitemeditform.py +++ b/openlp/core/ui/serviceitemeditform.py @@ -46,10 +46,6 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog): QtCore.SIGNAL(u'clicked()'), self.onItemDown) QtCore.QObject.connect(self.deleteButton, QtCore.SIGNAL(u'clicked()'), self.onItemDelete) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'accepted()'), self.accept) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'rejected()'), self.reject) QtCore.QObject.connect(self.listWidget, QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged) @@ -100,27 +96,30 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog): """ Move the current row up in the list. """ - item = self.listWidget.currentItem() - if not item: - return - row = self.listWidget.row(item) - temp = self.itemList[row] - self.itemList.remove(self.itemList[row]) - self.itemList.insert(row - 1, temp) - self.loadData() - self.listWidget.setCurrentRow(row - 1) + self.__moveItem(u'up') def onItemDown(self): """ Move the current row down in the list """ + self.__moveItem(u'down') + + def __moveItem(self, direction=u''): + """ + Move the current item. + """ + if not direction: + return item = self.listWidget.currentItem() if not item: return row = self.listWidget.row(item) temp = self.itemList[row] self.itemList.remove(self.itemList[row]) - self.itemList.insert(row + 1, temp) + if direction == u'up': + self.itemList.insert(row - 1, temp) + else: + self.itemList.insert(row + 1, temp) self.loadData() self.listWidget.setCurrentRow(row + 1) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 81599085b..4d36f4aec 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -36,8 +36,8 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \ Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \ ThemeLevel -from openlp.core.ui import criticalErrorMessageBox, ServiceNoteForm, \ - ServiceItemEditForm +from openlp.core.lib.ui import critical_error_message_box +from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ split_filename @@ -491,7 +491,7 @@ class ServiceManager(QtGui.QWidget): for file in zip.namelist(): ucsfile = file_is_unicode(file) if not ucsfile: - criticalErrorMessageBox( + critical_error_message_box( message=translate('OpenLP.ServiceManager', 'File is not a valid service.\n' 'The content encoding is not UTF-8.')) @@ -506,6 +506,8 @@ class ServiceManager(QtGui.QWidget): if filePath.endswith(u'osd'): p_file = filePath if 'p_file' in locals(): + Receiver.send_message(u'cursor_busy') + Receiver.send_message(u'openlp_process_events') fileTo = open(p_file, u'r') items = cPickle.load(fileTo) fileTo.close() @@ -520,13 +522,14 @@ class ServiceManager(QtGui.QWidget): Receiver.send_message(u'%s_service_load' % serviceItem.name.lower(), serviceItem) delete_file(p_file) + Receiver.send_message(u'cursor_normal') else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('OpenLP.ServiceManager', 'File is not a valid service.')) log.exception(u'File contains no service data') except (IOError, NameError): - log.exception(u'Problem loading a service file') + log.exception(u'Problem loading service file %s' % fileName) finally: if fileTo: fileTo.close() @@ -536,9 +539,7 @@ class ServiceManager(QtGui.QWidget): self.mainwindow.addRecentFile(fileName) self.setModified(False) QtCore.QSettings(). \ - setValue(u'service/last file',QtCore.QVariant(fileName)) - # Refresh Plugin lists - Receiver.send_message(u'plugin_list_refresh') + setValue(u'service/last file', QtCore.QVariant(fileName)) def loadLastFile(self): """ @@ -993,7 +994,7 @@ class ServiceManager(QtGui.QWidget): self.mainwindow.previewController.addServiceManagerItem( self.serviceItems[item][u'service_item'], child) else: - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Your item cannot be ' 'displayed as there is no handler to display it')) @@ -1027,7 +1028,7 @@ class ServiceManager(QtGui.QWidget): self.serviceItems[item][u'service_item'], 0) self.mainwindow.liveController.previewListWidget.setFocus() else: - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Your item cannot be ' 'displayed as the plugin required to display it is missing ' @@ -1188,7 +1189,7 @@ class ServiceManager(QtGui.QWidget): Print a Service Order Sheet. """ if not self.serviceItems: - criticalErrorMessageBox( + critical_error_message_box( message=translate('OpenLP.ServiceManager', 'There is no service item in this service.')) return diff --git a/openlp/core/ui/servicenotedialog.py b/openlp/core/ui/servicenotedialog.py deleted file mode 100644 index 9a45dae7c..000000000 --- a/openlp/core/ui/servicenotedialog.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2011 Raoul Snyman # -# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # -# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # -# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # -# Carsten Tinggaard, Frode Woldsund # -# --------------------------------------------------------------------------- # -# 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 # -############################################################################### - -from PyQt4 import QtCore, QtGui -from openlp.core.lib import translate - -class Ui_ServiceNoteEdit(object): - def setupUi(self, serviceNoteEdit): - serviceNoteEdit.setObjectName(u'serviceNoteEdit') - self.dialogLayout = QtGui.QVBoxLayout(serviceNoteEdit) - self.dialogLayout.setObjectName(u'verticalLayout') - self.textEdit = QtGui.QTextEdit(serviceNoteEdit) - self.textEdit.setObjectName(u'textEdit') - self.dialogLayout.addWidget(self.textEdit) - self.buttonBox = QtGui.QDialogButtonBox(serviceNoteEdit) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | - QtGui.QDialogButtonBox.Save) - self.buttonBox.setObjectName(u'buttonBox') - self.dialogLayout.addWidget(self.buttonBox) - self.retranslateUi(serviceNoteEdit) - QtCore.QMetaObject.connectSlotsByName(serviceNoteEdit) - - def retranslateUi(self, serviceNoteEdit): - serviceNoteEdit.setWindowTitle( - translate('OpenLP.ServiceNoteForm', 'Service Item Notes')) diff --git a/openlp/core/ui/servicenoteform.py b/openlp/core/ui/servicenoteform.py index de689e842..e659e50db 100644 --- a/openlp/core/ui/servicenoteform.py +++ b/openlp/core/ui/servicenoteform.py @@ -26,9 +26,10 @@ from PyQt4 import QtCore, QtGui -from servicenotedialog import Ui_ServiceNoteEdit +from openlp.core.lib import translate +from openlp.core.lib.ui import save_cancel_button_box -class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit): +class ServiceNoteForm(QtGui.QDialog): """ This is the form that is used to edit the verses of the song. """ @@ -37,8 +38,19 @@ class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit): Constructor """ QtGui.QDialog.__init__(self, parent) - self.setupUi(self) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), - self.accept) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), - self.reject) \ No newline at end of file + self.setupUi() + self.retranslateUi() + + def setupUi(self): + self.setObjectName(u'serviceNoteEdit') + self.dialogLayout = QtGui.QVBoxLayout(self) + self.dialogLayout.setObjectName(u'verticalLayout') + self.textEdit = QtGui.QTextEdit(self) + self.textEdit.setObjectName(u'textEdit') + self.dialogLayout.addWidget(self.textEdit) + self.dialogLayout.addWidget(save_cancel_button_box(self)) + QtCore.QMetaObject.connectSlotsByName(self) + + def retranslateUi(self): + self.setWindowTitle( + translate('OpenLP.ServiceNoteForm', 'Service Item Notes')) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 916bf68c3..ab8a656ff 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -77,14 +77,14 @@ class SlideController(QtGui.QWidget): self.selectedRow = 0 self.serviceItem = None self.alertTab = None - self.Panel = QtGui.QWidget(parent.ControlSplitter) + self.panel = QtGui.QWidget(parent.ControlSplitter) self.slideList = {} # Layout for holding panel - self.panelLayout = QtGui.QVBoxLayout(self.Panel) + self.panelLayout = QtGui.QVBoxLayout(self.panel) self.panelLayout.setSpacing(0) self.panelLayout.setMargin(0) # Type label for the top of the slide controller - self.typeLabel = QtGui.QLabel(self.Panel) + self.typeLabel = QtGui.QLabel(self.panel) if self.isLive: self.typeLabel.setText(translate('OpenLP.SlideController', 'Live')) self.split = 1 @@ -98,7 +98,7 @@ class SlideController(QtGui.QWidget): self.typeLabel.setAlignment(QtCore.Qt.AlignCenter) self.panelLayout.addWidget(self.typeLabel) # Splitter - self.splitter = QtGui.QSplitter(self.Panel) + self.splitter = QtGui.QSplitter(self.panel) self.splitter.setOrientation(QtCore.Qt.Vertical) self.panelLayout.addWidget(self.splitter) # Actual controller section @@ -185,13 +185,13 @@ class SlideController(QtGui.QWidget): u'Stop Loop', u':/media/media_stop.png', translate('OpenLP.SlideController', 'Stop continuous loop'), self.onStopLoop) - self.DelaySpinBox = QtGui.QSpinBox() - self.DelaySpinBox.setMinimum(1) - self.DelaySpinBox.setMaximum(180) - self.toolbar.addToolbarWidget(u'Image SpinBox', self.DelaySpinBox) - self.DelaySpinBox.setSuffix(translate('OpenLP.SlideController', + self.delaySpinBox = QtGui.QSpinBox() + self.delaySpinBox.setMinimum(1) + self.delaySpinBox.setMaximum(180) + self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox) + self.delaySpinBox.setSuffix(translate('OpenLP.SlideController', 's')) - self.DelaySpinBox.setToolTip(translate('OpenLP.SlideController', + self.delaySpinBox.setToolTip(translate('OpenLP.SlideController', 'Delay between slides in seconds')) else: self.toolbar.addToolbarSeparator(u'Close Separator') @@ -482,18 +482,11 @@ class SlideController(QtGui.QWidget): def onSongBarHandler(self): request = unicode(self.sender().text()) slideno = self.slideList[request] - if slideno > self.previewListWidget.rowCount(): - self.previewListWidget.selectRow( - self.previewListWidget.rowCount() - 1) - else: - if slideno + 1 < self.previewListWidget.rowCount(): - self.previewListWidget.scrollToItem( - self.previewListWidget.item(slideno + 1, 0)) - self.previewListWidget.selectRow(slideno) + self.__updatePreviewSelection(slideno) self.onSlideSelected() def receiveSpinDelay(self, value): - self.DelaySpinBox.setValue(int(value)) + self.delaySpinBox.setValue(int(value)) def enableToolBar(self, item): """ @@ -665,14 +658,7 @@ class SlideController(QtGui.QWidget): self.previewListWidget.resizeRowsToContents() self.previewListWidget.setColumnWidth(0, self.previewListWidget.viewport().size().width()) - if slideno > self.previewListWidget.rowCount(): - self.previewListWidget.selectRow( - self.previewListWidget.rowCount() - 1) - else: - if slideno + 1 < self.previewListWidget.rowCount(): - self.previewListWidget.scrollToItem( - self.previewListWidget.item(slideno + 1, 0)) - self.previewListWidget.selectRow(slideno) + self.__updatePreviewSelection(slideno) self.enableToolBar(serviceItem) # Pass to display for viewing self.display.buildHtml(self.serviceItem) @@ -683,6 +669,19 @@ class SlideController(QtGui.QWidget): Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix, [serviceItem]) + def __updatePreviewSelection(self, slideno): + """ + Utility method to update the selected slide in the list. + """ + if slideno > self.previewListWidget.rowCount(): + self.previewListWidget.selectRow( + self.previewListWidget.rowCount() - 1) + else: + if slideno + 1 < self.previewListWidget.rowCount(): + self.previewListWidget.scrollToItem( + self.previewListWidget.item(slideno + 1, 0)) + self.previewListWidget.selectRow(slideno) + def onTextRequest(self): """ Return the text for the current item in controller @@ -999,7 +998,7 @@ class SlideController(QtGui.QWidget): """ if self.previewListWidget.rowCount() > 1: self.timer_id = self.startTimer( - int(self.DelaySpinBox.value()) * 1000) + int(self.delaySpinBox.value()) * 1000) self.toolbar.actions[u'Stop Loop'].setVisible(True) self.toolbar.actions[u'Start Loop'].setVisible(False) diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index 43f1034f4..018df7597 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \ Receiver -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.core.utils import get_images_filter from themewizard import Ui_ThemeWizard @@ -272,14 +272,18 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard): def onMainPositionCheckBoxStateChanged(self, value): """ Change state as Main Area Position check box changed + NOTE the font_main_override is the inverse of the check box value """ - self.theme.font_main_override = (value == QtCore.Qt.Checked) + if self.updateThemeAllowed: + self.theme.font_main_override = not (value == QtCore.Qt.Checked) def onFooterPositionCheckBoxStateChanged(self, value): """ Change state as Footer Area Position check box changed + NOTE the font_footer_override is the inverse of the check box value """ - self.theme.font_footer_override = (value == QtCore.Qt.Checked) + if self.updateThemeAllowed: + self.theme.font_footer_override = not (value == QtCore.Qt.Checked) def exec_(self, edit=False): """ @@ -563,13 +567,13 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard): # Save the theme name self.theme.theme_name = unicode(self.field(u'name').toString()) if not self.theme.theme_name: - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.ThemeForm', 'Theme Name Missing'), translate('OpenLP.ThemeForm', 'There is no name for this theme. Please enter one.')) return if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None': - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.ThemeForm', 'Theme Name Invalid'), translate('OpenLP.ThemeForm', 'Invalid theme name. Please enter one.')) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index df1f1f775..f403d7441 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -32,11 +32,12 @@ import logging from xml.etree.ElementTree import ElementTree, XML from PyQt4 import QtCore, QtGui -from openlp.core.ui import criticalErrorMessageBox, FileRenameForm, ThemeForm -from openlp.core.theme import Theme from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \ build_icon, Receiver, SettingsManager, translate, check_item_selected, \ BackgroundType, BackgroundGradientType, check_directory_exists +from openlp.core.lib.ui import critical_error_message_box +from openlp.core.theme import Theme +from openlp.core.ui import FileRenameForm, ThemeForm from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ get_filesystem_encoding @@ -359,7 +360,7 @@ class ThemeManager(QtGui.QWidget): """ item = self.themeListWidget.currentItem() if item is None: - criticalErrorMessageBox(message=translate('OpenLP.ThemeManager', + critical_error_message_box(message=translate('OpenLP.ThemeManager', 'You have not selected a theme.')) return theme = unicode(item.data(QtCore.Qt.UserRole).toString()) @@ -386,7 +387,7 @@ class ThemeManager(QtGui.QWidget): 'Your theme has been successfully exported.')) except (IOError, OSError): log.exception(u'Export Theme Failed') - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.ThemeManager', 'Theme Export Failed'), translate('OpenLP.ThemeManager', 'Your theme could not be exported due to an error.')) @@ -496,7 +497,7 @@ class ThemeManager(QtGui.QWidget): for file in zip.namelist(): ucsfile = file_is_unicode(file) if not ucsfile: - criticalErrorMessageBox( + critical_error_message_box( message=translate('OpenLP.ThemeManager', 'File is not a valid theme.\n' 'The content encoding is not UTF-8.')) @@ -531,14 +532,14 @@ class ThemeManager(QtGui.QWidget): theme = self._createThemeFromXml(filexml, self.path) self.generateAndSaveImage(dir, themename, theme) else: - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'File is not a valid theme.')) log.exception(u'Theme file does not contain XML data %s' % filename) except (IOError, NameError): - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'File is not a valid theme.')) @@ -558,7 +559,7 @@ class ThemeManager(QtGui.QWidget): """ theme_dir = os.path.join(self.path, themeName) if os.path.exists(theme_dir): - criticalErrorMessageBox( + critical_error_message_box( translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'A theme with this name already exists.')) @@ -688,7 +689,7 @@ class ThemeManager(QtGui.QWidget): return False # should be the same unless default if theme != unicode(item.data(QtCore.Qt.UserRole).toString()): - criticalErrorMessageBox( + critical_error_message_box( message=translate('OpenLP.ThemeManager', 'You are unable to delete the default theme.')) return False @@ -696,7 +697,8 @@ class ThemeManager(QtGui.QWidget): if testPlugin: for plugin in self.mainwindow.pluginManager.plugins: if plugin.usesTheme(theme): - criticalErrorMessageBox(translate('OpenLP.ThemeManager', + critical_error_message_box( + translate('OpenLP.ThemeManager', 'Validation Error'), unicode(translate('OpenLP.ThemeManager', 'Theme %s is used in the %s plugin.')) % \ diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index a440a564e..441b95155 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -165,13 +165,7 @@ class ThemesTab(SettingsTab): self.global_theme = unicode(self.DefaultComboBox.currentText()) self.parent.renderManager.set_global_theme( self.global_theme, self.theme_level) - image = self.parent.ThemeManagerContents.getPreviewImage( - self.global_theme) - preview = QtGui.QPixmap(unicode(image)) - if not preview.isNull(): - preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio, - QtCore.Qt.SmoothTransformation) - self.DefaultListView.setPixmap(preview) + self.__previewGlobalTheme() def updateThemeList(self, theme_list): """ @@ -198,10 +192,16 @@ class ThemesTab(SettingsTab): self.parent.renderManager.set_global_theme( self.global_theme, self.theme_level) if self.global_theme is not u'': - image = self.parent.ThemeManagerContents.getPreviewImage( - self.global_theme) - preview = QtGui.QPixmap(unicode(image)) - if not preview.isNull(): - preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio, - QtCore.Qt.SmoothTransformation) - self.DefaultListView.setPixmap(preview) + self.__previewGlobalTheme() + + def __previewGlobalTheme(self): + """ + Utility method to update the global theme preview image. + """ + image = self.parent.ThemeManagerContents.getPreviewImage( + self.global_theme) + preview = QtGui.QPixmap(unicode(image)) + if not preview.isNull(): + preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio, + QtCore.Qt.SmoothTransformation) + self.DefaultListView.setPixmap(preview) diff --git a/openlp/core/ui/themewizard.py b/openlp/core/ui/themewizard.py index 50e8109c5..e8765b9e2 100644 --- a/openlp/core/ui/themewizard.py +++ b/openlp/core/ui/themewizard.py @@ -27,32 +27,17 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate, build_icon +from openlp.core.lib.ui import add_welcome_page class Ui_ThemeWizard(object): - def setupUi(self, ThemeWizard): - ThemeWizard.setObjectName(u'OpenLP.ThemeWizard') - ThemeWizard.setModal(True) - ThemeWizard.setWizardStyle(QtGui.QWizard.ModernStyle) - ThemeWizard.setOptions( - QtGui.QWizard.IndependentPages | + def setupUi(self, themeWizard): + themeWizard.setObjectName(u'OpenLP.ThemeWizard') + themeWizard.setModal(True) + themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle) + themeWizard.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage) # Welcome Page - self.welcomePage = QtGui.QWizardPage() - self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap, - QtGui.QPixmap(u':/wizards/wizard_createtheme.bmp')) - self.welcomePage.setObjectName(u'WelcomePage') - self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage) - self.welcomeLayout.setObjectName(u'WelcomeLayout') - self.titleLabel = QtGui.QLabel(self.welcomePage) - self.titleLabel.setObjectName(u'TitleLabel') - self.welcomeLayout.addWidget(self.titleLabel) - self.welcomeLayout.addSpacing(40) - self.informationLabel = QtGui.QLabel(self.welcomePage) - self.informationLabel.setWordWrap(True) - self.informationLabel.setObjectName(u'InformationLabel') - self.welcomeLayout.addWidget(self.informationLabel) - self.welcomeLayout.addStretch() - ThemeWizard.addPage(self.welcomePage) + add_welcome_page(themeWizard, u':/wizards/wizard_createtheme.bmp') # Background Page self.backgroundPage = QtGui.QWizardPage() self.backgroundPage.setObjectName(u'BackgroundPage') @@ -142,7 +127,7 @@ class Ui_ThemeWizard(object): self.imageSpacer) self.backgroundStack.addWidget(self.imageWidget) self.backgroundLayout.addLayout(self.backgroundStack) - ThemeWizard.addPage(self.backgroundPage) + themeWizard.addPage(self.backgroundPage) # Main Area Page self.mainAreaPage = QtGui.QWizardPage() self.mainAreaPage.setObjectName(u'MainAreaPage') @@ -225,7 +210,7 @@ class Ui_ThemeWizard(object): self.shadowSizeSpinBox.setObjectName(u'ShadowSizeSpinBox') self.shadowLayout.addWidget(self.shadowSizeSpinBox) self.mainAreaLayout.addRow(self.shadowCheckBox, self.shadowLayout) - ThemeWizard.addPage(self.mainAreaPage) + themeWizard.addPage(self.mainAreaPage) # Footer Area Page self.footerAreaPage = QtGui.QWizardPage() self.footerAreaPage.setObjectName(u'FooterAreaPage') @@ -251,7 +236,7 @@ class Ui_ThemeWizard(object): self.footerSizeSpinBox.setObjectName(u'FooterSizeSpinBox') self.footerAreaLayout.addRow(self.footerSizeLabel, self.footerSizeSpinBox) - ThemeWizard.addPage(self.footerAreaPage) + themeWizard.addPage(self.footerAreaPage) # Alignment Page self.alignmentPage = QtGui.QWizardPage() self.alignmentPage.setObjectName(u'AlignmentPage') @@ -276,7 +261,7 @@ class Ui_ThemeWizard(object): self.transitionsCheckBox.setObjectName(u'TransitionsCheckBox') self.alignmentLayout.addRow(self.transitionsLabel, self.transitionsCheckBox) - ThemeWizard.addPage(self.alignmentPage) + themeWizard.addPage(self.alignmentPage) # Area Position Page self.areaPositionPage = QtGui.QWizardPage() self.areaPositionPage.setObjectName(u'AreaPositionPage') @@ -352,7 +337,7 @@ class Ui_ThemeWizard(object): self.footerPositionLayout.addRow(self.footerHeightLabel, self.footerHeightSpinBox) self.areaPositionLayout.addWidget(self.footerPositionGroupBox) - ThemeWizard.addPage(self.areaPositionPage) + themeWizard.addPage(self.areaPositionPage) # Preview Page self.previewPage = QtGui.QWizardPage() self.previewPage.setObjectName(u'PreviewPage') @@ -381,9 +366,8 @@ class Ui_ThemeWizard(object): self.previewBoxLabel.setObjectName(u'PreviewBoxLabel') self.previewAreaLayout.addWidget(self.previewBoxLabel) self.previewLayout.addWidget(self.previewArea) - ThemeWizard.addPage(self.previewPage) - - self.retranslateUi(ThemeWizard) + themeWizard.addPage(self.previewPage) + self.retranslateUi(themeWizard) QtCore.QObject.connect(self.backgroundComboBox, QtCore.SIGNAL(u'currentIndexChanged(int)'), self.backgroundStack, QtCore.SLOT(u'setCurrentIndex(int)')) @@ -423,10 +407,10 @@ class Ui_ThemeWizard(object): QtCore.QObject.connect(self.footerPositionCheckBox, QtCore.SIGNAL(u'toggled(bool)'), self.footerHeightSpinBox, QtCore.SLOT(u'setDisabled(bool)')) - QtCore.QMetaObject.connectSlotsByName(ThemeWizard) + QtCore.QMetaObject.connectSlotsByName(themeWizard) - def retranslateUi(self, ThemeWizard): - ThemeWizard.setWindowTitle( + def retranslateUi(self, themeWizard): + themeWizard.setWindowTitle( translate('OpenLP.ThemeWizard', 'Theme Wizard')) self.titleLabel.setText( u'%s' % \ diff --git a/openlp/core/ui/wizard.py b/openlp/core/ui/wizard.py index d3a0255b4..2fa448db8 100644 --- a/openlp/core/ui/wizard.py +++ b/openlp/core/ui/wizard.py @@ -31,6 +31,7 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import build_icon, Receiver +from openlp.core.lib.ui import add_welcome_page log = logging.getLogger(__name__) @@ -63,36 +64,12 @@ class OpenLPWizard(QtGui.QWizard): self.setOptions(QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.NoBackButtonOnLastPage) - self.addWelcomePage(image) + add_welcome_page(self, image) self.addCustomPages() self.addProgressPage() self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) - def addWelcomePage(self, image): - """ - Add the opening welcome page to the wizard. - - ``image`` - A splash image for the wizard - """ - self.welcomePage = QtGui.QWizardPage() - self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap, - QtGui.QPixmap(image)) - self.welcomePage.setObjectName(u'WelcomePage') - self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage) - self.welcomeLayout.setObjectName(u'WelcomeLayout') - self.titleLabel = QtGui.QLabel(self.welcomePage) - self.titleLabel.setObjectName(u'TitleLabel') - self.welcomeLayout.addWidget(self.titleLabel) - self.welcomeLayout.addSpacing(40) - self.informationLabel = QtGui.QLabel(self.welcomePage) - self.informationLabel.setWordWrap(True) - self.informationLabel.setObjectName(u'InformationLabel') - self.welcomeLayout.addWidget(self.informationLabel) - self.welcomeLayout.addStretch() - self.addPage(self.welcomePage) - def addProgressPage(self): """ Add the progress page for the wizard. This page informs the user how diff --git a/openlp/plugins/alerts/forms/alertdialog.py b/openlp/plugins/alerts/forms/alertdialog.py index 272a96f3d..2e7e19176 100644 --- a/openlp/plugins/alerts/forms/alertdialog.py +++ b/openlp/plugins/alerts/forms/alertdialog.py @@ -66,6 +66,7 @@ class Ui_AlertDialog(object): self.saveButton.setObjectName(u'saveButton') self.manageButtonLayout.addWidget(self.saveButton) self.deleteButton = QtGui.QPushButton(alertDialog) + self.deleteButton.setEnabled(False) self.deleteButton.setIcon(build_icon(u':/general/general_delete.png')) self.deleteButton.setObjectName(u'deleteButton') self.manageButtonLayout.addWidget(self.deleteButton) @@ -75,11 +76,13 @@ class Ui_AlertDialog(object): self.buttonBox.addButton(QtGui.QDialogButtonBox.Close) displayIcon = build_icon(u':/general/general_live.png') self.displayButton = QtGui.QPushButton(alertDialog) + self.displayButton.setEnabled(False) self.displayButton.setIcon(displayIcon) self.displayButton.setObjectName(u'displayButton') self.buttonBox.addButton(self.displayButton, QtGui.QDialogButtonBox.ActionRole) self.displayCloseButton = QtGui.QPushButton(alertDialog) + self.displayCloseButton.setEnabled(False) self.displayCloseButton.setIcon(displayIcon) self.displayCloseButton.setObjectName(u'displayCloseButton') self.buttonBox.addButton(self.displayCloseButton, diff --git a/openlp/plugins/alerts/forms/alertform.py b/openlp/plugins/alerts/forms/alertform.py index f1a0f7fea..b25ae1dca 100644 --- a/openlp/plugins/alerts/forms/alertform.py +++ b/openlp/plugins/alerts/forms/alertform.py @@ -44,22 +44,24 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): self.item_id = None QtGui.QDialog.__init__(self, plugin.formparent) self.setupUi(self) - QtCore.QObject.connect(self.displayButton, QtCore.SIGNAL(u'clicked()'), - self.onDisplayClicked) + QtCore.QObject.connect(self.displayButton, + QtCore.SIGNAL(u'clicked()'), self.onDisplayClicked) QtCore.QObject.connect(self.displayCloseButton, QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked) QtCore.QObject.connect(self.alertTextEdit, QtCore.SIGNAL(u'textChanged(const QString&)'), self.onTextChanged) - QtCore.QObject.connect(self.newButton, QtCore.SIGNAL(u'clicked()'), - self.onNewClick) - QtCore.QObject.connect(self.deleteButton, QtCore.SIGNAL(u'clicked()'), - self.onDeleteClick) - QtCore.QObject.connect(self.saveButton, QtCore.SIGNAL(u'clicked()'), - self.onSaveClick) + QtCore.QObject.connect(self.newButton, + QtCore.SIGNAL(u'clicked()'), self.onNewClick) + QtCore.QObject.connect(self.deleteButton, + QtCore.SIGNAL(u'clicked()'), self.onDeleteClick) + QtCore.QObject.connect(self.saveButton, + QtCore.SIGNAL(u'clicked()'), self.onSaveClick) QtCore.QObject.connect(self.alertListWidget, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onDoubleClick) QtCore.QObject.connect(self.alertListWidget, QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSingleClick) + QtCore.QObject.connect(self.alertListWidget, + QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged) def loadList(self): """ @@ -72,12 +74,9 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): item_name = QtGui.QListWidgetItem(alert.text) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id)) self.alertListWidget.addItem(item_name) - self.saveButton.setEnabled(False) - self.deleteButton.setEnabled(False) def onDisplayClicked(self): - if self.triggerAlert(unicode(self.alertTextEdit.text())): - self.loadList() + self.triggerAlert(unicode(self.alertTextEdit.text())) def onDisplayCloseClicked(self): if self.triggerAlert(unicode(self.alertTextEdit.text())): @@ -95,8 +94,6 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): self.alertListWidget.takeItem(row) self.item_id = None self.alertTextEdit.setText(u'') - self.saveButton.setEnabled(False) - self.deleteButton.setEnabled(False) def onNewClick(self): if len(self.alertTextEdit.text()) == 0: @@ -135,30 +132,26 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): """ List item has been double clicked to display it """ - items = self.alertListWidget.selectedIndexes() - for item in items: - bitem = self.alertListWidget.item(item.row()) - self.triggerAlert(unicode(bitem.text())) - self.alertTextEdit.setText(unicode(bitem.text())) - self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0] + item = self.alertListWidget.selectedIndexes()[0] + bitem = self.alertListWidget.item(item.row()) + self.triggerAlert(unicode(bitem.text())) + self.alertTextEdit.setText(unicode(bitem.text())) + self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0] self.saveButton.setEnabled(False) - self.deleteButton.setEnabled(True) def onSingleClick(self): """ List item has been single clicked to add it to the edit field so it can be changed. """ - items = self.alertListWidget.selectedIndexes() - for item in items: - bitem = self.alertListWidget.item(item.row()) - self.alertTextEdit.setText(unicode(bitem.text())) - self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0] + item = self.alertListWidget.selectedIndexes()[0] + bitem = self.alertListWidget.item(item.row()) + self.alertTextEdit.setText(unicode(bitem.text())) + self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0] # If the alert does not contain '<>' we clear the ParameterEdit field. if unicode(self.alertTextEdit.text()).find(u'<>') == -1: self.parameterEdit.setText(u'') self.saveButton.setEnabled(False) - self.deleteButton.setEnabled(True) def triggerAlert(self, text): """ @@ -167,30 +160,49 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): ``text`` The alert text (unicode). """ - if text: - # We found '<>' in the alert text, but the ParameterEdit field is - # empty. - if text.find(u'<>') != -1 and not self.parameterEdit.text() and \ - QtGui.QMessageBox.question(self, - translate('AlertPlugin.AlertForm', 'No Parameter found'), - translate('AlertPlugin.AlertForm', 'You have not entered a ' - 'parameter to be replaced.\nDo you want to continue anyway?'), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | - QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: - self.parameterEdit.setFocus() - return False - # The ParameterEdit field is not empty, but we have not found '<>' - # in the alert text. - elif text.find(u'<>') == -1 and self.parameterEdit.text() and \ - QtGui.QMessageBox.question(self, - translate('AlertPlugin.AlertForm', 'No Placeholder found'), - translate('AlertPlugin.AlertForm', 'The alert text does not' - ' contain \'<>\'.\nDo want to continue anyway?'), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | - QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: - self.parameterEdit.setFocus() - return False - text = text.replace(u'<>', unicode(self.parameterEdit.text())) - self.parent.alertsmanager.displayAlert(text) - return True - return False + if not text: + return False + # We found '<>' in the alert text, but the ParameterEdit field is empty. + if text.find(u'<>') != -1 and not self.parameterEdit.text() and \ + QtGui.QMessageBox.question(self, + translate('AlertPlugin.AlertForm', 'No Parameter found'), + translate('AlertPlugin.AlertForm', 'You have not entered a ' + 'parameter to be replaced.\nDo you want to continue anyway?'), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | + QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: + self.parameterEdit.setFocus() + return False + # The ParameterEdit field is not empty, but we have not found '<>' + # in the alert text. + elif text.find(u'<>') == -1 and self.parameterEdit.text() and \ + QtGui.QMessageBox.question(self, + translate('AlertPlugin.AlertForm', 'No Placeholder found'), + translate('AlertPlugin.AlertForm', 'The alert text does not' + ' contain \'<>\'.\nDo want to continue anyway?'), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | + QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: + self.parameterEdit.setFocus() + return False + text = text.replace(u'<>', unicode(self.parameterEdit.text())) + self.parent.alertsmanager.displayAlert(text) + return True + + def onCurrentRowChanged(self, row): + """ + Called when the *alertListWidget*'s current row has been changed. This + enables or disables buttons which require an item to act on. + + ``row`` + The row (int). If there is no current row, the value is -1. + """ + if row == -1: + self.displayButton.setEnabled(False) + self.displayCloseButton.setEnabled(False) + self.saveButton.setEnabled(False) + self.deleteButton.setEnabled(False) + else: + self.displayButton.setEnabled(True) + self.displayCloseButton.setEnabled(True) + self.deleteButton.setEnabled(True) + # We do not need to enable the save button, as it is only enabled + # when typing text in the "alertTextEdit". diff --git a/openlp/plugins/bibles/forms/bibleimportform.py b/openlp/plugins/bibles/forms/bibleimportform.py index 3e43d19aa..a2509ba97 100644 --- a/openlp/plugins/bibles/forms/bibleimportform.py +++ b/openlp/plugins/bibles/forms/bibleimportform.py @@ -35,7 +35,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, SettingsManager, translate from openlp.core.lib.db import delete_database -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui.wizard import OpenLPWizard from openlp.core.utils import AppLocation, string_is_unicode from openlp.plugins.bibles.lib.manager import BibleFormat @@ -486,7 +486,7 @@ class BibleImportForm(OpenLPWizard): elif self.currentPage() == self.selectPage: if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS: if not self.field(u'osis_location').toString(): - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin.ImportWizardForm', 'Invalid Bible Location'), translate('BiblesPlugin.ImportWizardForm', @@ -496,7 +496,7 @@ class BibleImportForm(OpenLPWizard): return False elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV: if not self.field(u'csv_testamentsfile').toString(): - answer = criticalErrorMessageBox(translate( + answer = critical_error_message_box(translate( 'BiblesPlugin.ImportWizardForm', 'No Testaments File'), translate('BiblesPlugin.ImportWizardForm', 'You have not specified a testaments file. Do you ' @@ -505,7 +505,7 @@ class BibleImportForm(OpenLPWizard): self.csvTestamentsEdit.setFocus() return False elif not self.field(u'csv_booksfile').toString(): - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin.ImportWizardForm', 'Invalid Books File'), translate('BiblesPlugin.ImportWizardForm', @@ -514,7 +514,7 @@ class BibleImportForm(OpenLPWizard): self.csvBooksEdit.setFocus() return False elif not self.field(u'csv_versefile').toString(): - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin.ImportWizardForm', 'Invalid Verse File'), translate('BiblesPlugin.ImportWizardForm', @@ -525,7 +525,7 @@ class BibleImportForm(OpenLPWizard): elif self.field(u'source_format').toInt()[0] == \ BibleFormat.OpenSong: if not self.field(u'opensong_file').toString(): - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin.ImportWizardForm', 'Invalid OpenSong Bible'), translate('BiblesPlugin.ImportWizardForm', @@ -535,7 +535,7 @@ class BibleImportForm(OpenLPWizard): return False elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1: if not self.field(u'openlp1_location').toString(): - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin.ImportWizardForm', 'Invalid Bible Location'), translate('BiblesPlugin.ImportWizardForm', @@ -549,7 +549,7 @@ class BibleImportForm(OpenLPWizard): license_copyright = \ unicode(self.field(u'license_copyright').toString()) if not license_version: - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin.ImportWizardForm', 'Empty Version Name'), translate('BiblesPlugin.ImportWizardForm', @@ -557,7 +557,7 @@ class BibleImportForm(OpenLPWizard): self.versionNameEdit.setFocus() return False elif not license_copyright: - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin.ImportWizardForm', 'Empty Copyright'), translate('BiblesPlugin.ImportWizardForm', @@ -566,7 +566,7 @@ class BibleImportForm(OpenLPWizard): self.copyrightEdit.setFocus() return False elif self.manager.exists(license_version): - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'), translate('BiblesPlugin.ImportWizardForm', 'This Bible already exists. Please import ' diff --git a/openlp/plugins/bibles/lib/__init__.py b/openlp/plugins/bibles/lib/__init__.py index 34e1bf5a5..e6fff1cc8 100644 --- a/openlp/plugins/bibles/lib/__init__.py +++ b/openlp/plugins/bibles/lib/__init__.py @@ -77,9 +77,9 @@ def parse_reference(reference): - After a verse reference all further single values are treat as verse in the last selected chapter. ``John 3:16-18`` refers to John chapter 3 verses 16 to 18 - - After a list separator it is possible to refer to additional verses. They - are build analog to the first ones. This way it is possible to define - each number of verse references. It is not possible to refer to verses in + - After a list separator it is possible to refer to additional verses. They + are build analog to the first ones. This way it is possible to define each + number of verse references. It is not possible to refer to verses in additional books. ``John 3:16,18`` refers to John chapter 3 verses 16 and 18 ``John 3:16-18,20`` refers to John chapter 3 verses 16 to 18 and 20 @@ -91,7 +91,7 @@ def parse_reference(reference): ``range_string`` is a regular expression which matches for verse range declarations: - 1. ``(?:(?P[0-9]+)%(sep_v)s)?' + 1. ``(?:(?P[0-9]+)%(sep_v)s)?`` It starts with a optional chapter reference ``from_chapter`` followed by a verse separator. 2. ``(?P[0-9]+)`` @@ -105,7 +105,7 @@ def parse_reference(reference): 5. ``(?P[0-9]+)`` The ``to_verse`` reference is equivalent to group 2. - The full reference is matched against get_reference_match(u'full'). This + The full reference is matched against get_reference_match(u'full'). This regular expression looks like this: 1. ``^\s*(?!\s)(?P[\d]*[^\d]+)(?(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$`` - The second group contains all ``ranges``. This can be multiple + The second group contains all ``ranges``. This can be multiple declarations of a range_string separated by a list separator. The reference list is a list of tuples, with each tuple structured like diff --git a/openlp/plugins/bibles/lib/csvbible.py b/openlp/plugins/bibles/lib/csvbible.py index fd987dfdf..82872e15b 100644 --- a/openlp/plugins/bibles/lib/csvbible.py +++ b/openlp/plugins/bibles/lib/csvbible.py @@ -50,14 +50,17 @@ The format of the books file is: ... 40,2,Matthew,Matt -The format of the verses file is: +There are two acceptable formats of the verses file. They are: ,,, + or + ,,, For example: 1,1,1,"In the beginning God created the heaven and the earth." - 1,1,2,"And the earth was without form, and void; and darkness...." + or + "Genesis",1,2,"And the earth was without form, and void; and...." All CSV files are expected to use a comma (',') as the delimeter and double quotes ('"') as the quote symbol. @@ -172,15 +175,22 @@ class CSVBible(BibleDB): for line in verse_reader: if self.stop_import_flag: break - if book_ptr != book_list[int(line[0])]: - book = self.get_book(book_list[int(line[0])]) + try: + line_book = book_list[int(line[0])] + except ValueError: + line_book = unicode(line[0], details['encoding']) + if book_ptr != line_book: + book = self.get_book(line_book) book_ptr = book.name self.wizard.incrementProgressBar(unicode(translate( 'BibleDB.Wizard', 'Importing verses from %s...', 'Importing verses from ...')) % book.name) self.session.commit() - self.create_verse(book.id, line[1], line[2], - unicode(line[3], details['encoding'])) + try: + verse_text = unicode(line[3], details['encoding']) + except UnicodeError: + verse_text = unicode(line[3], u'cp1252') + self.create_verse(book.id, line[1], line[2], verse_text) self.wizard.incrementProgressBar(translate('BibleDB.Wizard', 'Importing verses... done.')) Receiver.send_message(u'openlp_process_events') diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index a9444d88b..b986b0d66 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -35,7 +35,7 @@ from sqlalchemy.orm.exc import UnmappedClassError from openlp.core.lib import translate from openlp.core.lib.db import BaseModel, init_db, Manager -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box log = logging.getLogger(__name__) @@ -361,7 +361,7 @@ class BibleDB(QtCore.QObject, Manager): verse_list.extend(verses) else: log.debug(u'OpenLP failed to find book %s', book) - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin', 'No Book Found'), translate('BiblesPlugin', 'No matching book ' 'could be found in this Bible. Check that you have ' diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index b844bbe61..8db214140 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -38,7 +38,7 @@ from HTMLParser import HTMLParseError from BeautifulSoup import BeautifulSoup, NavigableString from openlp.core.lib import Receiver, translate -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.core.utils import AppLocation, get_web_page from openlp.plugins.bibles.lib import SearchResults from openlp.plugins.bibles.lib.db import BibleDB, Book @@ -210,7 +210,8 @@ class BGExtract(object): cleaner = [(re.compile(' |
|\'\+\''), lambda match: '')] soup = get_soup_for_bible_ref( u'http://www.biblegateway.com/passage/?%s' % url_params, - cleaner=cleaner) + pre_parse_regex=r'', pre_parse_substitute='', + cleaner=cleaner) if not soup: return None Receiver.send_message(u'openlp_process_events') @@ -430,7 +431,7 @@ class HTTPBible(BibleDB): if not db_book: book_details = HTTPBooks.get_book(book) if not book_details: - criticalErrorMessageBox( + critical_error_message_box( translate('BiblesPlugin', 'No Book Found'), translate('BiblesPlugin', 'No matching ' 'book could be found in this Bible. Check that you ' @@ -499,7 +500,8 @@ class HTTPBible(BibleDB): """ return HTTPBooks.get_verse_count(book, chapter) -def get_soup_for_bible_ref(reference_url, header=None, cleaner=None): +def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None, + pre_parse_substitute=None, cleaner=None): """ Gets a webpage and returns a parsed and optionally cleaned soup or None. @@ -509,6 +511,13 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None): ``header`` An optional HTTP header to pass to the bible web server. + ``pre_parse_regex`` + A regular expression to run on the webpage. Allows manipulation of the + webpage before passing to BeautifulSoup for parsing. + + ``pre_parse_substitute`` + The text to replace any matches to the regular expression with. + ``cleaner`` An optional regex to use during webpage parsing. """ @@ -518,12 +527,15 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None): if not page: send_error_message(u'download') return None + page_source = page.read() + if pre_parse_regex and pre_parse_substitute is not None: + page_source = re.sub(pre_parse_regex, pre_parse_substitute, page_source) soup = None try: if cleaner: - soup = BeautifulSoup(page, markupMassage=cleaner) + soup = BeautifulSoup(page_source, markupMassage=cleaner) else: - soup = BeautifulSoup(page) + soup = BeautifulSoup(page_source) except HTMLParseError: log.exception(u'BeautifulSoup could not parse the bible page.') if not soup: @@ -540,14 +552,14 @@ def send_error_message(error_type): The type of error that occured for the issue. """ if error_type == u'download': - criticalErrorMessageBox( + critical_error_message_box( translate('BiblePlugin.HTTPBible', 'Download Error'), translate('BiblePlugin.HTTPBible', 'There was a ' 'problem downloading your verse selection. Please check your ' 'Internet connection, and if this error continues to occur ' 'please consider reporting a bug.')) elif error_type == u'parse': - criticalErrorMessageBox( + critical_error_message_box( translate('BiblePlugin.HTTPBible', 'Parse Error'), translate('BiblePlugin.HTTPBible', 'There was a ' 'problem extracting your verse selection. If this error continues ' diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 614990654..26f45b6b3 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -30,7 +30,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \ ItemCapabilities, translate -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box, media_item_combo_box from openlp.plugins.bibles.forms import BibleImportForm from openlp.plugins.bibles.lib import get_reference_match @@ -81,33 +81,21 @@ class BibleMediaItem(MediaManagerItem): self.quickLayout.setObjectName(u'quickLayout') self.quickVersionLabel = QtGui.QLabel(self.quickTab) self.quickVersionLabel.setObjectName(u'quickVersionLabel') - self.quickVersionComboBox = QtGui.QComboBox(self.quickTab) - self.quickVersionComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.quickVersionComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.quickVersionComboBox.setObjectName(u'quickVersionComboBox') + self.quickVersionComboBox = media_item_combo_box(self.quickTab, + u'quickVersionComboBox') self.quickVersionLabel.setBuddy(self.quickVersionComboBox) self.quickLayout.addRow(self.quickVersionLabel, self.quickVersionComboBox) self.quickSecondLabel = QtGui.QLabel(self.quickTab) self.quickSecondLabel.setObjectName(u'quickSecondLabel') - self.quickSecondComboBox = QtGui.QComboBox(self.quickTab) - self.quickSecondComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.quickSecondComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.quickSecondComboBox.setObjectName(u'quickSecondComboBox') + self.quickSecondComboBox = media_item_combo_box(self.quickTab, + u'quickSecondComboBox') self.quickSecondLabel.setBuddy(self.quickSecondComboBox) self.quickLayout.addRow(self.quickSecondLabel, self.quickSecondComboBox) self.quickSearchTypeLabel = QtGui.QLabel(self.quickTab) self.quickSearchTypeLabel.setObjectName(u'quickSearchTypeLabel') - self.quickSearchComboBox = QtGui.QComboBox(self.quickTab) - self.quickSearchComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.quickSearchComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.quickSearchComboBox.setObjectName(u'quickSearchComboBox') + self.quickSearchComboBox = media_item_combo_box(self.quickTab, + u'quickSearchComboBox') self.quickSearchTypeLabel.setBuddy(self.quickSearchComboBox) self.quickLayout.addRow(self.quickSearchTypeLabel, self.quickSearchComboBox) @@ -119,12 +107,8 @@ class BibleMediaItem(MediaManagerItem): self.quickLayout.addRow(self.quickSearchLabel, self.quickSearchEdit) self.quickClearLabel = QtGui.QLabel(self.quickTab) self.quickClearLabel.setObjectName(u'quickClearLabel') - self.quickClearComboBox = QtGui.QComboBox(self.quickTab) - self.quickClearComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.quickClearComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.quickClearComboBox.setObjectName(u'quickClearComboBox') + self.quickClearComboBox = media_item_combo_box(self.quickTab, + u'quickClearComboBox') self.quickLayout.addRow(self.quickClearLabel, self.quickClearComboBox) self.quickSearchButtonLayout = QtGui.QHBoxLayout() self.quickSearchButtonLayout.setObjectName(u'quickSearchButtonLayout') @@ -144,36 +128,24 @@ class BibleMediaItem(MediaManagerItem): self.advancedVersionLabel.setObjectName(u'advancedVersionLabel') self.advancedLayout.addWidget(self.advancedVersionLabel, 0, 0, QtCore.Qt.AlignRight) - self.advancedVersionComboBox = QtGui.QComboBox(self.advancedTab) - self.advancedVersionComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.advancedVersionComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.advancedVersionComboBox.setObjectName(u'advancedVersionComboBox') + self.advancedVersionComboBox = media_item_combo_box(self.advancedTab, + u'advancedVersionComboBox') self.advancedVersionLabel.setBuddy(self.advancedVersionComboBox) self.advancedLayout.addWidget(self.advancedVersionComboBox, 0, 1, 1, 2) self.advancedSecondLabel = QtGui.QLabel(self.advancedTab) self.advancedSecondLabel.setObjectName(u'advancedSecondLabel') self.advancedLayout.addWidget(self.advancedSecondLabel, 1, 0, QtCore.Qt.AlignRight) - self.advancedSecondComboBox = QtGui.QComboBox(self.advancedTab) - self.advancedSecondComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.advancedSecondComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.advancedSecondComboBox.setObjectName(u'advancedSecondComboBox') + self.advancedSecondComboBox = media_item_combo_box(self.advancedTab, + u'advancedSecondComboBox') self.advancedSecondLabel.setBuddy(self.advancedSecondComboBox) self.advancedLayout.addWidget(self.advancedSecondComboBox, 1, 1, 1, 2) self.advancedBookLabel = QtGui.QLabel(self.advancedTab) self.advancedBookLabel.setObjectName(u'advancedBookLabel') self.advancedLayout.addWidget(self.advancedBookLabel, 2, 0, QtCore.Qt.AlignRight) - self.advancedBookComboBox = QtGui.QComboBox(self.advancedTab) - self.advancedBookComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.advancedBookComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.advancedBookComboBox.setObjectName(u'advancedBookComboBox') + self.advancedBookComboBox = media_item_combo_box(self.advancedTab, + u'advancedBookComboBox') self.advancedBookLabel.setBuddy(self.advancedBookComboBox) self.advancedLayout.addWidget(self.advancedBookComboBox, 2, 1, 1, 2) self.advancedChapterLabel = QtGui.QLabel(self.advancedTab) @@ -202,17 +174,12 @@ class BibleMediaItem(MediaManagerItem): self.advancedToVerse = QtGui.QComboBox(self.advancedTab) self.advancedToVerse.setObjectName(u'advancedToVerse') self.advancedLayout.addWidget(self.advancedToVerse, 5, 2) - self.advancedClearLabel = QtGui.QLabel(self.quickTab) self.advancedClearLabel.setObjectName(u'advancedClearLabel') self.advancedLayout.addWidget(self.advancedClearLabel, 6, 0, QtCore.Qt.AlignRight) - self.advancedClearComboBox = QtGui.QComboBox(self.quickTab) - self.advancedClearComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.advancedClearComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.advancedClearComboBox.setObjectName(u'advancedClearComboBox') + self.advancedClearComboBox = media_item_combo_box(self.quickTab, + u'advancedClearComboBox') self.advancedClearLabel.setBuddy(self.advancedClearComboBox) self.advancedLayout.addWidget(self.advancedClearComboBox, 6, 1, 1, 2) self.advancedSearchButtonLayout = QtGui.QHBoxLayout() @@ -387,7 +354,8 @@ class BibleMediaItem(MediaManagerItem): verse_count = self.parent.manager.get_verse_count(bible, book, 1) if verse_count == 0: self.advancedSearchButton.setEnabled(False) - criticalErrorMessageBox(message=translate('BiblePlugin.MediaItem', + critical_error_message_box( + message=translate('BiblePlugin.MediaItem', 'Bible not fully loaded')) else: self.advancedSearchButton.setEnabled(True) @@ -525,19 +493,7 @@ class BibleMediaItem(MediaManagerItem): if self.advancedClearComboBox.currentIndex() == 0: self.listView.clear() if self.listView.count() != 0: - # Check if the first item is a second bible item or not. - bitem = self.listView.item(0) - item_second_bible = self._decodeQtObject(bitem, 'second_bible') - if item_second_bible and second_bible or not item_second_bible and \ - not second_bible: - self.displayResults(bible, second_bible) - elif criticalErrorMessageBox( - message=translate('BiblePlugin.MediaItem', - 'You cannot combine single and second bible verses. Do you ' - 'want to delete your search results and start a new search?'), - parent=self, question=True) == QtGui.QMessageBox.Yes: - self.listView.clear() - self.displayResults(bible, second_bible) + self.__checkSecondBible(bible, second_bible) else: self.displayResults(bible, second_bible) Receiver.send_message(u'cursor_normal') @@ -577,24 +533,30 @@ class BibleMediaItem(MediaManagerItem): if self.quickClearComboBox.currentIndex() == 0: self.listView.clear() if self.listView.count() != 0 and self.search_results: - bitem = self.listView.item(0) - item_second_bible = self._decodeQtObject(bitem, 'second_bible') - if item_second_bible and second_bible or not item_second_bible and \ - not second_bible: - self.displayResults(bible, second_bible) - elif criticalErrorMessageBox( - message=translate('BiblePlugin.MediaItem', - 'You cannot combine single and second bible verses. Do you ' - 'want to delete your search results and start a new search?'), - parent=self, question=True) == QtGui.QMessageBox.Yes: - self.listView.clear() - self.displayResults(bible, second_bible) + self.__checkSecondBible(bible, second_bible) elif self.search_results: self.displayResults(bible, second_bible) self.quickSearchButton.setEnabled(True) Receiver.send_message(u'cursor_normal') Receiver.send_message(u'openlp_process_events') + def __checkSecondBible(self, bible, second_bible): + """ + Check if the first item is a second bible item or not. + """ + bitem = self.listView.item(0) + item_second_bible = self._decodeQtObject(bitem, 'second_bible') + if item_second_bible and second_bible or not item_second_bible and \ + not second_bible: + self.displayResults(bible, second_bible) + elif critical_error_message_box( + message=translate('BiblePlugin.MediaItem', + 'You cannot combine single and second bible verses. Do you ' + 'want to delete your search results and start a new search?'), + parent=self, question=True) == QtGui.QMessageBox.Yes: + self.listView.clear() + self.displayResults(bible, second_bible) + def displayResults(self, bible, second_bible=u''): """ Displays the search results in the media manager. All data needed for diff --git a/openlp/plugins/custom/forms/editcustomdialog.py b/openlp/plugins/custom/forms/editcustomdialog.py index d778b1dfe..75717c082 100644 --- a/openlp/plugins/custom/forms/editcustomdialog.py +++ b/openlp/plugins/custom/forms/editcustomdialog.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import build_icon, translate +from openlp.core.lib.ui import save_cancel_button_box class Ui_CustomEditDialog(object): def setupUi(self, customEditDialog): @@ -93,16 +94,9 @@ class Ui_CustomEditDialog(object): self.creditLabel.setBuddy(self.creditEdit) self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit) self.dialogLayout.addLayout(self.bottomFormLayout) - self.buttonBox = QtGui.QDialogButtonBox(customEditDialog) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | - QtGui.QDialogButtonBox.Save) - self.buttonBox.setObjectName(u'buttonBox') + self.buttonBox = save_cancel_button_box(customEditDialog) self.dialogLayout.addWidget(self.buttonBox) self.retranslateUi(customEditDialog) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), - customEditDialog.accept) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), - customEditDialog.closePressed) QtCore.QMetaObject.connectSlotsByName(customEditDialog) def retranslateUi(self, customEditDialog): diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index ebc917e99..e8dfa20aa 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -29,7 +29,7 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, translate -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser from openlp.plugins.custom.lib.db import CustomSlide from editcustomdialog import Ui_CustomEditDialog @@ -136,15 +136,15 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): if preview: self.previewButton.setVisible(True) - def closePressed(self): + def reject(self): Receiver.send_message(u'custom_edit_clear') - self.close() + QtGui.QDialog.reject(self) def accept(self): log.debug(u'accept') if self.saveCustom(): Receiver.send_message(u'custom_load_list') - self.close() + QtGui.QDialog.accept(self) def saveCustom(self): """ @@ -152,7 +152,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): """ valid, message = self._validate() if not valid: - criticalErrorMessageBox(message=message) + critical_error_message_box(message=message) return False sxml = CustomXMLBuilder() sxml.new_document() diff --git a/openlp/plugins/custom/forms/editcustomslidedialog.py b/openlp/plugins/custom/forms/editcustomslidedialog.py index 1f4bf5b14..93bff68b8 100644 --- a/openlp/plugins/custom/forms/editcustomslidedialog.py +++ b/openlp/plugins/custom/forms/editcustomslidedialog.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate, SpellTextEdit +from openlp.core.lib.ui import save_cancel_button_box class Ui_CustomSlideEditDialog(object): def setupUi(self, customSlideEditDialog): @@ -36,20 +37,13 @@ class Ui_CustomSlideEditDialog(object): self.slideTextEdit = SpellTextEdit(self) self.slideTextEdit.setObjectName(u'slideTextEdit') self.dialogLayout.addWidget(self.slideTextEdit) - self.buttonBox = QtGui.QDialogButtonBox(customSlideEditDialog) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | - QtGui.QDialogButtonBox.Save) - self.buttonBox.setObjectName(u'buttonBox') + self.buttonBox = save_cancel_button_box(customSlideEditDialog) self.splitButton = QtGui.QPushButton(customSlideEditDialog) self.splitButton.setObjectName(u'splitButton') self.buttonBox.addButton(self.splitButton, QtGui.QDialogButtonBox.ActionRole) self.dialogLayout.addWidget(self.buttonBox) self.retranslateUi(customSlideEditDialog) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), - customSlideEditDialog.accept) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), - customSlideEditDialog.reject) QtCore.QMetaObject.connectSlotsByName(customSlideEditDialog) def retranslateUi(self, customSlideEditDialog): diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 9b8115956..ec915b0a9 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -146,16 +146,7 @@ class CustomMediaItem(MediaManagerItem): raw_footer = [] slide = None theme = None - if item is None: - if self.remoteTriggered is None: - item = self.listView.currentItem() - if item is None: - return False - item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] - else: - item_id = self.remoteCustom - else: - item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + item_id = self._getIdOfItemToGenerate(item, self.remoteCustom) service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsLoop) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 73f5b80f0..cbefc7171 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ ItemCapabilities, SettingsManager, translate, check_item_selected, \ check_directory_exists, Receiver -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.core.utils import AppLocation, delete_file, get_images_filter log = logging.getLogger(__name__) @@ -142,7 +142,7 @@ class ImageMediaItem(MediaManagerItem): items = self.listView.selectedIndexes() if items: service_item.title = unicode( - translate('ImagePlugin.MediaItem', 'Image(s)')) + translate('ImagePlugin.MediaItem', 'Images')) service_item.add_capability(ItemCapabilities.AllowsMaintain) service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsLoop) @@ -161,7 +161,7 @@ class ImageMediaItem(MediaManagerItem): items.remove(item) # We cannot continue, as all images do not exist. if not items: - criticalErrorMessageBox( + critical_error_message_box( translate('ImagePlugin.MediaItem', 'Missing Image(s)'), unicode(translate('ImagePlugin.MediaItem', 'The following image(s) no longer exist: %s')) % @@ -214,7 +214,7 @@ class ImageMediaItem(MediaManagerItem): self.parent.liveController.display.directImage(name, filename) self.resetAction.setVisible(True) else: - criticalErrorMessageBox( + critical_error_message_box( translate('ImagePlugin.MediaItem', 'Live Background Error'), unicode(translate('ImagePlugin.MediaItem', 'There was a problem replacing your background, ' diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index c68b11c85..ea1b679b4 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ ItemCapabilities, SettingsManager, translate, check_item_selected, Receiver -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box log = logging.getLogger(__name__) @@ -120,7 +120,7 @@ class MediaMediaItem(MediaManagerItem): self.parent.liveController.display.video(filename, 0, True) self.resetAction.setVisible(True) else: - criticalErrorMessageBox(translate('MediaPlugin.MediaItem', + critical_error_message_box(translate('MediaPlugin.MediaItem', 'Live Background Error'), unicode(translate('MediaPlugin.MediaItem', 'There was a problem replacing your background, ' @@ -144,7 +144,7 @@ class MediaMediaItem(MediaManagerItem): return True else: # File is no longer present - criticalErrorMessageBox( + critical_error_message_box( translate('MediaPlugin.MediaItem', 'Missing Media File'), unicode(translate('MediaPlugin.MediaItem', 'The file %s no longer exists.')) % filename) diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 43cb3dab0..a0173cb27 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ SettingsManager, translate, check_item_selected, Receiver, ItemCapabilities -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box, media_item_combo_box from openlp.plugins.presentations.lib import MessageListener log = logging.getLogger(__name__) @@ -116,12 +116,8 @@ class PresentationMediaItem(MediaManagerItem): self.displayLayout.setObjectName(u'displayLayout') self.displayTypeLabel = QtGui.QLabel(self.presentationWidget) self.displayTypeLabel.setObjectName(u'displayTypeLabel') - self.displayTypeComboBox = QtGui.QComboBox(self.presentationWidget) - self.displayTypeComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.displayTypeComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.displayTypeComboBox.setObjectName(u'displayTypeComboBox') + self.displayTypeComboBox = media_item_combo_box( + self.presentationWidget, u'displayTypeComboBox') self.displayTypeLabel.setBuddy(self.displayTypeComboBox) self.displayLayout.addRow(self.displayTypeLabel, self.displayTypeComboBox) @@ -181,7 +177,7 @@ class PresentationMediaItem(MediaManagerItem): filename = os.path.split(unicode(file))[1] if titles.count(filename) > 0: if not initialLoad: - criticalErrorMessageBox( + critical_error_message_box( translate('PresentationPlugin.MediaItem', 'File Exists'), translate('PresentationPlugin.MediaItem', @@ -205,7 +201,7 @@ class PresentationMediaItem(MediaManagerItem): if initialLoad: icon = build_icon(u':/general/general_delete.png') else: - criticalErrorMessageBox( + critical_error_message_box( self, translate('PresentationPlugin.MediaItem', 'Unsupported File'), translate('PresentationPlugin.MediaItem', @@ -278,7 +274,7 @@ class PresentationMediaItem(MediaManagerItem): return True else: # File is no longer present - criticalErrorMessageBox( + critical_error_message_box( translate('PresentationPlugin.MediaItem', 'Missing Presentation'), unicode(translate('PresentationPlugin.MediaItem', @@ -287,7 +283,7 @@ class PresentationMediaItem(MediaManagerItem): return False else: # File is no longer present - criticalErrorMessageBox( + critical_error_message_box( translate('PresentationPlugin.MediaItem', 'Missing Presentation'), unicode(translate('PresentationPlugin.MediaItem', diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index 19abadf0d..4d926ad3d 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -116,7 +116,7 @@ class Controller(object): def last(self): """ - Based on the handler passed at startup triggers the first slide + Based on the handler passed at startup triggers the last slide """ log.debug(u'Live = %s, last' % self.is_live) if not self.is_live: diff --git a/openlp/plugins/songs/forms/authorsdialog.py b/openlp/plugins/songs/forms/authorsdialog.py index 6f1c7f2a4..3fd3c5fef 100644 --- a/openlp/plugins/songs/forms/authorsdialog.py +++ b/openlp/plugins/songs/forms/authorsdialog.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate +from openlp.core.lib.ui import save_cancel_button_box class Ui_AuthorsDialog(object): def setupUi(self, authorsDialog): @@ -55,17 +56,9 @@ class Ui_AuthorsDialog(object): self.displayLabel.setBuddy(self.displayEdit) self.authorLayout.addRow(self.displayLabel, self.displayEdit) self.dialogLayout.addLayout(self.authorLayout) - self.buttonBox = QtGui.QDialogButtonBox(authorsDialog) - self.buttonBox.setStandardButtons( - QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel) - self.buttonBox.setObjectName(u'buttonBox') - self.dialogLayout.addWidget(self.buttonBox) + self.dialogLayout.addWidget(save_cancel_button_box(authorsDialog)) self.retranslateUi(authorsDialog) authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height()) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'accepted()'), authorsDialog.accept) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'rejected()'), authorsDialog.reject) QtCore.QMetaObject.connectSlotsByName(authorsDialog) def retranslateUi(self, authorsDialog): diff --git a/openlp/plugins/songs/forms/authorsform.py b/openlp/plugins/songs/forms/authorsform.py index 091618bde..3a37cf290 100644 --- a/openlp/plugins/songs/forms/authorsform.py +++ b/openlp/plugins/songs/forms/authorsform.py @@ -27,7 +27,7 @@ from PyQt4 import QtGui, QtCore from openlp.core.lib import translate -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog): @@ -80,17 +80,19 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog): def accept(self): if not self.firstNameEdit.text(): - criticalErrorMessageBox(message=translate('SongsPlugin.AuthorsForm', + critical_error_message_box( + message=translate('SongsPlugin.AuthorsForm', 'You need to type in the first name of the author.')) self.firstNameEdit.setFocus() return False elif not self.lastNameEdit.text(): - criticalErrorMessageBox(message=translate('SongsPlugin.AuthorsForm', + critical_error_message_box( + message=translate('SongsPlugin.AuthorsForm', 'You need to type in the last name of the author.')) self.lastNameEdit.setFocus() return False elif not self.displayEdit.text(): - if criticalErrorMessageBox( + if critical_error_message_box( message=translate('SongsPlugin.AuthorsForm', 'You have not set a display name for the ' 'author, combine the first and last names?'), diff --git a/openlp/plugins/songs/forms/editsongdialog.py b/openlp/plugins/songs/forms/editsongdialog.py index 675108af7..c44b42d46 100644 --- a/openlp/plugins/songs/forms/editsongdialog.py +++ b/openlp/plugins/songs/forms/editsongdialog.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import build_icon, translate +from openlp.core.lib.ui import save_cancel_button_box class Ui_EditSongDialog(object): def setupUi(self, editSongDialog): @@ -111,14 +112,8 @@ class Ui_EditSongDialog(object): self.authorsLayout.setObjectName(u'authorsLayout') self.authorAddLayout = QtGui.QHBoxLayout() self.authorAddLayout.setObjectName(u'authorAddLayout') - self.authorsComboBox = QtGui.QComboBox(self.authorsGroupBox) - self.authorsComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.authorsComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.authorsComboBox.setEditable(True) - self.authorsComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert) - self.authorsComboBox.setObjectName(u'authorsComboBox') + self.authorsComboBox = editSongDialogComboBox( + self.authorsGroupBox, u'authorsComboBox') self.authorAddLayout.addWidget(self.authorsComboBox) self.authorAddButton = QtGui.QPushButton(self.authorsGroupBox) self.authorAddButton.setObjectName(u'authorAddButton') @@ -152,14 +147,8 @@ class Ui_EditSongDialog(object): self.topicsLayout.setObjectName(u'topicsLayout') self.topicAddLayout = QtGui.QHBoxLayout() self.topicAddLayout.setObjectName(u'topicAddLayout') - self.topicsComboBox = QtGui.QComboBox(self.topicsGroupBox) - self.topicsComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.topicsComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.topicsComboBox.setEditable(True) - self.topicsComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert) - self.topicsComboBox.setObjectName(u'topicsComboBox') + self.topicsComboBox = editSongDialogComboBox( + self.topicsGroupBox, u'topicsComboBox') self.topicAddLayout.addWidget(self.topicsComboBox) self.topicAddButton = QtGui.QPushButton(self.topicsGroupBox) self.topicAddButton.setObjectName(u'topicAddButton') @@ -183,14 +172,8 @@ class Ui_EditSongDialog(object): self.songBookLayout.setObjectName(u'songBookLayout') self.songBookNameLabel = QtGui.QLabel(self.songBookGroupBox) self.songBookNameLabel.setObjectName(u'songBookNameLabel') - self.songBookComboBox = QtGui.QComboBox(self.songBookGroupBox) - self.songBookComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.songBookComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.songBookComboBox.setEditable(True) - self.songBookComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert) - self.songBookComboBox.setObjectName(u'songBookComboBox') + self.songBookComboBox = editSongDialogComboBox( + self.songBookGroupBox, u'songBookComboBox') self.songBookNameLabel.setBuddy(self.songBookComboBox) self.songBookLayout.addRow(self.songBookNameLabel, self.songBookComboBox) @@ -215,14 +198,8 @@ class Ui_EditSongDialog(object): self.themeGroupBox.setObjectName(u'themeGroupBox') self.themeLayout = QtGui.QHBoxLayout(self.themeGroupBox) self.themeLayout.setObjectName(u'themeLayout') - self.themeComboBox = QtGui.QComboBox(self.themeGroupBox) - self.themeComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToMinimumContentsLength) - self.themeComboBox.setSizePolicy( - QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - self.themeComboBox.setEditable(True) - self.themeComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert) - self.themeComboBox.setObjectName(u'themeComboBox') + self.themeComboBox = editSongDialogComboBox( + self.themeGroupBox, u'themeComboBox') self.themeLayout.addWidget(self.themeComboBox) self.themeAddButton = QtGui.QPushButton(self.themeGroupBox) self.themeAddButton.setObjectName(u'themeAddButton') @@ -264,16 +241,9 @@ class Ui_EditSongDialog(object): self.themeTabLayout.addWidget(self.commentsGroupBox) self.songTabWidget.addTab(self.themeTab, u'') self.dialogLayout.addWidget(self.songTabWidget) - self.buttonBox = QtGui.QDialogButtonBox(editSongDialog) - self.buttonBox.setStandardButtons( - QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Save) - self.buttonBox.setObjectName(u'buttonBox') + self.buttonBox = save_cancel_button_box(editSongDialog) self.dialogLayout.addWidget(self.buttonBox) self.retranslateUi(editSongDialog) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'rejected()'), editSongDialog.closePressed) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'accepted()'), editSongDialog.accept) QtCore.QMetaObject.connectSlotsByName(editSongDialog) def retranslateUi(self, editSongDialog): @@ -338,3 +308,15 @@ class Ui_EditSongDialog(object): self.songTabWidget.indexOf(self.themeTab), translate('SongsPlugin.EditSongForm', 'Theme, Copyright Info && Comments')) + +def editSongDialogComboBox(parent, name): + """ + Utility method to generate a standard combo box for this dialog. + """ + comboBox = QtGui.QComboBox(parent) + comboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength) + comboBox.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) + comboBox.setEditable(True) + comboBox.setInsertPolicy(QtGui.QComboBox.NoInsert) + comboBox.setObjectName(name) + return comboBox diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index b36ea55e1..bf94503ff 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -30,7 +30,7 @@ import re from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, translate -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.plugins.songs.forms import EditVerseForm from openlp.plugins.songs.lib import SongXML, VerseType from openlp.plugins.songs.lib.db import Book, Song, Author, Topic @@ -255,7 +255,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.songBookNumberEdit.setText(self.song.song_number) else: self.songBookNumberEdit.setText(u'') - # lazy xml migration for now self.verseListWidget.clear() self.verseListWidget.setRowCount(0) @@ -333,11 +332,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): author = Author.populate(first_name=text.rsplit(u' ', 1)[0], last_name=text.rsplit(u' ', 1)[1], display_name=text) self.manager.save_object(author) - author_item = QtGui.QListWidgetItem( - unicode(author.display_name)) - author_item.setData(QtCore.Qt.UserRole, - QtCore.QVariant(author.id)) - self.authorsListView.addItem(author_item) + self.__addAuthorToList(author) self.loadAuthors() self.authorsComboBox.setCurrentIndex(0) else: @@ -347,15 +342,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): author = self.manager.get_object(Author, item_id) if self.authorsListView.findItems(unicode(author.display_name), QtCore.Qt.MatchExactly): - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'This author is already in the list.')) else: - author_item = QtGui.QListWidgetItem(unicode( - author.display_name)) - author_item.setData(QtCore.Qt.UserRole, - QtCore.QVariant(author.id)) - self.authorsListView.addItem(author_item) + self.__addAuthorToList(author) self.authorsComboBox.setCurrentIndex(0) else: QtGui.QMessageBox.warning(self, @@ -365,6 +356,14 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): 'or type in a new author and click the "Add Author to ' 'Song" button to add the new author.')) + def __addAuthorToList(self, author): + """ + Add an author to the author list. + """ + author_item = QtGui.QListWidgetItem(unicode(author.display_name)) + author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id)) + self.authorsListView.addItem(author_item) + def onAuthorsListViewPressed(self): if self.authorsListView.count() > 1: self.authorRemoveButton.setEnabled(True) @@ -400,7 +399,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): topic = self.manager.get_object(Topic, item_id) if self.topicsListView.findItems(unicode(topic.name), QtCore.Qt.MatchExactly): - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'This topic is already in the list.')) else: @@ -533,21 +532,21 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if not self.titleEdit.text(): self.songTabWidget.setCurrentIndex(0) self.titleEdit.setFocus() - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'You need to type in a song title.')) return False if self.verseListWidget.rowCount() == 0: self.songTabWidget.setCurrentIndex(0) self.verseListWidget.setFocus() - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'You need to type in at least one verse.')) return False if self.authorsListView.count() == 0: self.songTabWidget.setCurrentIndex(1) self.authorsListView.setFocus() - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'You need to have an author for this song.')) return False @@ -575,7 +574,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): valid = verses.pop(0) for verse in verses: valid = valid + u', ' + verse - criticalErrorMessageBox( + critical_error_message_box( message=unicode(translate('SongsPlugin.EditSongForm', 'The verse order is invalid. There is no verse ' 'corresponding to %s. Valid entries are %s.')) % \ @@ -648,29 +647,31 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): """ Free up autocompletion memory on dialog exit """ + log.debug (u'SongEditForm.clearCaches') self.authors = [] self.themes = [] self.books = [] self.topics = [] - def closePressed(self): + def reject(self): """ Exit Dialog and do not save """ + log.debug (u'SongEditForm.reject') Receiver.send_message(u'songs_edit_clear') self.clearCaches() - self.close() + QtGui.QDialog.reject(self) def accept(self): """ Exit Dialog and save song if valid """ - log.debug(u'accept') + log.debug(u'SongEditForm.accept') self.clearCaches() if self._validate_song(): self.saveSong() Receiver.send_message(u'songs_load_list') - self.close() + QtGui.QDialog.accept(self) def saveSong(self, preview=False): """ diff --git a/openlp/plugins/songs/forms/editversedialog.py b/openlp/plugins/songs/forms/editversedialog.py index 1710d8b93..deaf952e2 100644 --- a/openlp/plugins/songs/forms/editversedialog.py +++ b/openlp/plugins/songs/forms/editversedialog.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import build_icon, translate, SpellTextEdit +from openlp.core.lib.ui import save_cancel_button_box from openlp.plugins.songs.lib import VerseType class Ui_EditVerseDialog(object): @@ -59,17 +60,8 @@ class Ui_EditVerseDialog(object): self.verseTypeLayout.addWidget(self.insertButton) self.verseTypeLayout.addStretch() self.dialogLayout.addLayout(self.verseTypeLayout) - self.buttonBox = QtGui.QDialogButtonBox(editVerseDialog) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | - QtGui.QDialogButtonBox.Save) - self.buttonBox.setObjectName(u'buttonBox') - self.dialogLayout.addWidget(self.buttonBox) + self.dialogLayout.addWidget(save_cancel_button_box(editVerseDialog)) self.retranslateUi(editVerseDialog) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), - editVerseDialog.accept) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), - editVerseDialog.reject) QtCore.QMetaObject.connectSlotsByName(editVerseDialog) def retranslateUi(self, editVerseDialog): diff --git a/openlp/plugins/songs/forms/editverseform.py b/openlp/plugins/songs/forms/editverseform.py index c10e48cb7..e67e0733a 100644 --- a/openlp/plugins/songs/forms/editverseform.py +++ b/openlp/plugins/songs/forms/editverseform.py @@ -29,7 +29,7 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.plugins.songs.lib import VerseType, translate from editversedialog import Ui_EditVerseDialog @@ -168,7 +168,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): else: value = self.getVerse()[0].split(u'\n')[1] if len(value) == 0: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'You need to type some text in to the verse.')) return False diff --git a/openlp/plugins/songs/forms/songbookdialog.py b/openlp/plugins/songs/forms/songbookdialog.py index 9b9da43bf..fcd6bd364 100644 --- a/openlp/plugins/songs/forms/songbookdialog.py +++ b/openlp/plugins/songs/forms/songbookdialog.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate +from openlp.core.lib.ui import save_cancel_button_box class Ui_SongBookDialog(object): def setupUi(self, songBookDialog): @@ -49,17 +50,9 @@ class Ui_SongBookDialog(object): self.publisherLabel.setBuddy(self.publisherEdit) self.bookLayout.addRow(self.publisherLabel, self.publisherEdit) self.dialogLayout.addLayout(self.bookLayout) - self.buttonBox = QtGui.QDialogButtonBox(songBookDialog) - self.buttonBox.setStandardButtons( - QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel) - self.buttonBox.setObjectName(u'buttonBox') - self.dialogLayout.addWidget(self.buttonBox) + self.dialogLayout.addWidget(save_cancel_button_box(songBookDialog)) self.retranslateUi(songBookDialog) songBookDialog.setMaximumHeight(songBookDialog.sizeHint().height()) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'accepted()'), songBookDialog.accept) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'rejected()'), songBookDialog.reject) QtCore.QMetaObject.connectSlotsByName(songBookDialog) def retranslateUi(self, songBookDialog): diff --git a/openlp/plugins/songs/forms/songbookform.py b/openlp/plugins/songs/forms/songbookform.py index 8341a7c4c..3f054fe8d 100644 --- a/openlp/plugins/songs/forms/songbookform.py +++ b/openlp/plugins/songs/forms/songbookform.py @@ -27,7 +27,7 @@ from PyQt4 import QtGui from openlp.core.lib import translate -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog class SongBookForm(QtGui.QDialog, Ui_SongBookDialog): @@ -50,7 +50,7 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog): def accept(self): if not self.nameEdit.text(): - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongBookForm', 'You need to type in a name for the book.')) self.nameEdit.setFocus() diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py index 3de251462..f1e1f82ed 100644 --- a/openlp/plugins/songs/forms/songimportform.py +++ b/openlp/plugins/songs/forms/songimportform.py @@ -32,7 +32,7 @@ import os from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, SettingsManager, translate -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui.wizard import OpenLPWizard from openlp.plugins.songs.lib.importer import SongFormat @@ -165,29 +165,29 @@ class SongImportForm(OpenLPWizard): self.formatStack = QtGui.QStackedLayout() self.formatStack.setObjectName(u'FormatStack') # OpenLP 2.0 - self.addSingleFileSelectItem(u'openLP2') + self.addFileSelectItem(u'openLP2', single_select=True) # openlp.org 1.x - self.addSingleFileSelectItem(u'openLP1', None, True) + self.addFileSelectItem(u'openLP1', None, True, True) # OpenLyrics - self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True) + self.addFileSelectItem(u'openLyrics', u'OpenLyrics', True) # Open Song - self.addMultiFileSelectItem(u'openSong', u'OpenSong') + self.addFileSelectItem(u'openSong', u'OpenSong') # Words of Worship - self.addMultiFileSelectItem(u'wordsOfWorship') + self.addFileSelectItem(u'wordsOfWorship') # CCLI File import - self.addMultiFileSelectItem(u'ccli') + self.addFileSelectItem(u'ccli') # Songs of Fellowship - self.addMultiFileSelectItem(u'songsOfFellowship', None, True) + self.addFileSelectItem(u'songsOfFellowship', None, True) # Generic Document/Presentation import - self.addMultiFileSelectItem(u'generic', None, True) + self.addFileSelectItem(u'generic', None, True) # EasySlides - self.addSingleFileSelectItem(u'easiSlides') + self.addFileSelectItem(u'easiSlides', single_select=True) # EasyWorship - self.addSingleFileSelectItem(u'ew') + self.addFileSelectItem(u'ew', single_select=True) # Words of Worship - self.addMultiFileSelectItem(u'songBeamer') + self.addFileSelectItem(u'songBeamer') # Commented out for future use. -# self.addSingleFileSelectItem(u'csv', u'CSV') +# self.addFileSelectItem(u'csv', u'CSV', single_select=True) self.sourceLayout.addLayout(self.formatStack) self.addPage(self.sourcePage) @@ -318,16 +318,6 @@ class SongImportForm(OpenLPWizard): self.openLP2FilenameLabel.minimumSizeHint().width()) self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.openLP2FormLabelSpacer.changeSize(width, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.openLP1FormLabelSpacer.changeSize(width, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.easiSlidesFormLabelSpacer.changeSize(width, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.ewFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) -# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, -# QtGui.QSizePolicy.Fixed) def validateCurrentPage(self): """ @@ -339,7 +329,7 @@ class SongImportForm(OpenLPWizard): source_format = self.formatComboBox.currentIndex() if source_format == SongFormat.OpenLP2: if self.openLP2FilenameEdit.text().isEmpty(): - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No OpenLP 2.0 Song Database Selected'), translate('SongsPlugin.ImportWizardForm', @@ -349,7 +339,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.OpenLP1: if self.openLP1FilenameEdit.text().isEmpty(): - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No openlp.org 1.x Song Database Selected'), translate('SongsPlugin.ImportWizardForm', @@ -359,7 +349,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.OpenLyrics: if self.openLyricsFileListWidget.count() == 0: - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No OpenLyrics Files Selected'), translate('SongsPlugin.ImportWizardForm', @@ -369,7 +359,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.OpenSong: if self.openSongFileListWidget.count() == 0: - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No OpenSong Files Selected'), translate('SongsPlugin.ImportWizardForm', @@ -379,7 +369,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.WordsOfWorship: if self.wordsOfWorshipFileListWidget.count() == 0: - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No Words of Worship Files Selected'), translate('SongsPlugin.ImportWizardForm', @@ -389,7 +379,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.CCLI: if self.ccliFileListWidget.count() == 0: - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No CCLI Files Selected'), translate('SongsPlugin.ImportWizardForm', @@ -399,7 +389,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.SongsOfFellowship: if self.songsOfFellowshipFileListWidget.count() == 0: - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No Songs of Fellowship File Selected'), translate('SongsPlugin.ImportWizardForm', @@ -409,7 +399,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.Generic: if self.genericFileListWidget.count() == 0: - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No Document/Presentation Selected'), translate('SongsPlugin.ImportWizardForm', @@ -419,7 +409,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.EasiSlides: if self.easiSlidesFilenameEdit.text().isEmpty(): - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No Easislides Songs file selected'), translate('SongsPlugin.ImportWizardForm', @@ -429,7 +419,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.EasyWorship: if self.ewFilenameEdit.text().isEmpty(): - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No EasyWorship Song Database Selected'), translate('SongsPlugin.ImportWizardForm', @@ -439,7 +429,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.SongBeamer: if self.songBeamerFileListWidget.count() == 0: - criticalErrorMessageBox( + critical_error_message_box( translate('SongsPlugin.ImportWizardForm', 'No SongBeamer File Selected'), translate('SongsPlugin.ImportWizardForm', @@ -791,52 +781,8 @@ class SongImportForm(OpenLPWizard): translate('SongsPlugin.SongImportForm', 'Your song import failed.')) - def addSingleFileSelectItem(self, prefix, obj_prefix=None, - can_disable=False): - if not obj_prefix: - obj_prefix = prefix - page = QtGui.QWidget() - page.setObjectName(obj_prefix + u'Page') - if can_disable: - importWidget = self.disablableWidget(page, prefix, obj_prefix) - else: - importWidget = page - importLayout = QtGui.QFormLayout(importWidget) - importLayout.setMargin(0) - if can_disable: - importLayout.setObjectName(obj_prefix + u'ImportLayout') - else: - importLayout.setObjectName(obj_prefix + u'Layout') - filenameLabel = QtGui.QLabel(importWidget) - filenameLabel.setObjectName(obj_prefix + u'FilenameLabel') - fileLayout = QtGui.QHBoxLayout() - fileLayout.setObjectName(obj_prefix + u'FileLayout') - filenameEdit = QtGui.QLineEdit(importWidget) - filenameEdit.setObjectName(obj_prefix + u'FilenameEdit') - fileLayout.addWidget(filenameEdit) - browseButton = QtGui.QToolButton(importWidget) - browseButton.setIcon(self.openIcon) - browseButton.setObjectName(obj_prefix + u'BrowseButton') - fileLayout.addWidget(browseButton) - importLayout.addRow(filenameLabel, fileLayout) - formSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Minimum) - importLayout.setItem(1, QtGui.QFormLayout.LabelRole, formSpacer) - self.formatStack.addWidget(page) - setattr(self, prefix + u'Page', page) - setattr(self, prefix + u'FilenameLabel', filenameLabel) - setattr(self, prefix + u'FormLabelSpacer', formSpacer) - setattr(self, prefix + u'FileLayout', fileLayout) - setattr(self, prefix + u'FilenameEdit', filenameEdit) - setattr(self, prefix + u'BrowseButton', browseButton) - if can_disable: - setattr(self, prefix + u'ImportLayout', importLayout) - else: - setattr(self, prefix + u'Layout', importLayout) - self.formatComboBox.addItem(u'') - - def addMultiFileSelectItem(self, prefix, obj_prefix=None, - can_disable=False): + def addFileSelectItem(self, prefix, obj_prefix=None, can_disable=False, + single_select=False): if not obj_prefix: obj_prefix = prefix page = QtGui.QWidget() @@ -847,37 +793,55 @@ class SongImportForm(OpenLPWizard): importWidget = page importLayout = QtGui.QVBoxLayout(importWidget) importLayout.setMargin(0) - if can_disable: - importLayout.setObjectName(obj_prefix + u'ImportLayout') + importLayout.setObjectName(obj_prefix + u'ImportLayout') + if single_select: + fileLayout = QtGui.QHBoxLayout() + fileLayout.setObjectName(obj_prefix + u'FileLayout') + filenameLabel = QtGui.QLabel(importWidget) + filenameLabel.setObjectName(obj_prefix + u'FilenameLabel') + fileLayout.addWidget(filenameLabel) + filenameEdit = QtGui.QLineEdit(importWidget) + filenameEdit.setObjectName(obj_prefix + u'FilenameEdit') + fileLayout.addWidget(filenameEdit) + browseButton = QtGui.QToolButton(importWidget) + browseButton.setIcon(self.openIcon) + browseButton.setObjectName(obj_prefix + u'BrowseButton') + fileLayout.addWidget(browseButton) + formSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Expanding) + importLayout.addLayout(fileLayout) + importLayout.addSpacerItem(formSpacer) else: - importLayout.setObjectName(obj_prefix + u'Layout') - fileListWidget = QtGui.QListWidget(importWidget) - fileListWidget.setSelectionMode( - QtGui.QAbstractItemView.ExtendedSelection) - fileListWidget.setObjectName(obj_prefix + u'FileListWidget') - importLayout.addWidget(fileListWidget) - buttonLayout = QtGui.QHBoxLayout() - buttonLayout.setObjectName(obj_prefix + u'ButtonLayout') - addButton = QtGui.QPushButton(importWidget) - addButton.setIcon(self.openIcon) - addButton.setObjectName(obj_prefix + u'AddButton') - buttonLayout.addWidget(addButton) - buttonLayout.addStretch() - removeButton = QtGui.QPushButton(importWidget) - removeButton.setIcon(self.deleteIcon) - removeButton.setObjectName(obj_prefix + u'RemoveButton') - buttonLayout.addWidget(removeButton) - importLayout.addLayout(buttonLayout) + fileListWidget = QtGui.QListWidget(importWidget) + fileListWidget.setSelectionMode( + QtGui.QAbstractItemView.ExtendedSelection) + fileListWidget.setObjectName(obj_prefix + u'FileListWidget') + importLayout.addWidget(fileListWidget) + buttonLayout = QtGui.QHBoxLayout() + buttonLayout.setObjectName(obj_prefix + u'ButtonLayout') + addButton = QtGui.QPushButton(importWidget) + addButton.setIcon(self.openIcon) + addButton.setObjectName(obj_prefix + u'AddButton') + buttonLayout.addWidget(addButton) + buttonLayout.addStretch() + removeButton = QtGui.QPushButton(importWidget) + removeButton.setIcon(self.deleteIcon) + removeButton.setObjectName(obj_prefix + u'RemoveButton') + buttonLayout.addWidget(removeButton) + importLayout.addLayout(buttonLayout) self.formatStack.addWidget(page) setattr(self, prefix + u'Page', page) - setattr(self, prefix + u'FileListWidget', fileListWidget) - setattr(self, prefix + u'ButtonLayout', buttonLayout) - setattr(self, prefix + u'AddButton', addButton) - setattr(self, prefix + u'RemoveButton', removeButton) - if can_disable: - setattr(self, prefix + u'ImportLayout', importLayout) + if single_select: + setattr(self, prefix + u'FilenameLabel', filenameLabel) + setattr(self, prefix + u'FileLayout', fileLayout) + setattr(self, prefix + u'FilenameEdit', filenameEdit) + setattr(self, prefix + u'BrowseButton', browseButton) else: - setattr(self, prefix + u'Layout', importLayout) + setattr(self, prefix + u'FileListWidget', fileListWidget) + setattr(self, prefix + u'ButtonLayout', buttonLayout) + setattr(self, prefix + u'AddButton', addButton) + setattr(self, prefix + u'RemoveButton', removeButton) + setattr(self, prefix + u'ImportLayout', importLayout) self.formatComboBox.addItem(u'') def disablableWidget(self, page, prefix, obj_prefix): diff --git a/openlp/plugins/songs/forms/songmaintenanceform.py b/openlp/plugins/songs/forms/songmaintenanceform.py index 6613a050b..28b03ec7d 100644 --- a/openlp/plugins/songs/forms/songmaintenanceform.py +++ b/openlp/plugins/songs/forms/songmaintenanceform.py @@ -29,7 +29,7 @@ from PyQt4 import QtGui, QtCore from sqlalchemy.sql import and_ from openlp.core.lib import Receiver, translate -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.plugins.songs.forms import AuthorsForm, TopicsForm, SongBookForm from openlp.plugins.songs.lib.db import Author, Book, Topic, Song from songmaintenancedialog import Ui_SongMaintenanceDialog @@ -94,8 +94,8 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): self.typeListWidget.setFocus() return QtGui.QDialog.exec_(self) - def _getCurrentItemId(self, ListWidget): - item = ListWidget.currentItem() + def _getCurrentItemId(self, listWidget): + item = listWidget.currentItem() if item: item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] return item_id @@ -108,14 +108,14 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if item_id != -1: item = self.manager.get_object(item_class, item_id) if item and len(item.songs) == 0: - if criticalErrorMessageBox(title=dlg_title, message=del_text, + if critical_error_message_box(title=dlg_title, message=del_text, parent=self, question=True) == QtGui.QMessageBox.Yes: self.manager.delete_object(item_class, item.id) reset_func() else: - criticalErrorMessageBox(dlg_title, err_text) + critical_error_message_box(dlg_title, err_text) else: - criticalErrorMessageBox(dlg_title, sel_text) + critical_error_message_box(dlg_title, sel_text) def resetAuthors(self): """ @@ -159,66 +159,43 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): def checkAuthor(self, new_author, edit=False): """ Returns *False* if the given Author already exists, otherwise *True*. - - ``edit`` - If we edit an item, this should be *True*. """ authors = self.manager.get_all_objects(Author, and_(Author.first_name == new_author.first_name, Author.last_name == new_author.last_name, Author.display_name == new_author.display_name)) - # Check if this author already exists. - if len(authors) > 0: - # If we edit an existing Author, we need to make sure that we do - # not return False when nothing has changed. - if edit: - for author in authors: - if author.id != new_author.id: - return False - return True - else: - return False - else: - return True + return self.__checkObject(authors, new_author, edit) def checkTopic(self, new_topic, edit=False): """ Returns *False* if the given Topic already exists, otherwise *True*. - - ``edit`` - If we edit an item, this should be *True*. """ topics = self.manager.get_all_objects(Topic, Topic.name == new_topic.name) - if len(topics) > 0: - # If we edit an existing Topic, we need to make sure that we do - # not return False when nothing has changed. - if edit: - for topic in topics: - if topic.id != new_topic.id: - return False - return True - else: - return False - else: - return True + return self.__checkObject(topics, new_topic, edit) def checkBook(self, new_book, edit=False): """ Returns *False* if the given Topic already exists, otherwise *True*. - - ``edit`` - If we edit an item, this should be *True*. """ books = self.manager.get_all_objects(Book, and_(Book.name == new_book.name, Book.publisher == new_book.publisher)) - if len(books) > 0: - # If we edit an existing Book, we need to make sure that we do + return self.__checkObject(books, new_book, edit) + + def __checkObject(self, objects, new_object, edit): + """ + Utility method to check for an existing object. + + ``edit`` + If we edit an item, this should be *True*. + """ + if len(objects) > 0: + # If we edit an existing object, we need to make sure that we do # not return False when nothing has changed. if edit: - for book in books: - if book.id != new_book.id: + for object in objects: + if object.id != new_object.id: return False return True else: @@ -237,11 +214,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(author): self.resetAuthors() else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your author.')) else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'This author already exists.')) @@ -252,11 +229,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(topic): self.resetTopics() else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your topic.')) else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'This topic already exists.')) @@ -268,11 +245,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(book): self.resetBooks() else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your book.')) else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'This book already exists.')) @@ -301,28 +278,24 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): self.resetAuthors() Receiver.send_message(u'songs_load_list') else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) - elif criticalErrorMessageBox(message=unicode(translate( + elif critical_error_message_box(message=unicode(translate( 'SongsPlugin.SongMaintenanceForm', 'The author %s already ' 'exists. Would you like to make songs with author %s use ' 'the existing author %s?')) % (author.display_name, temp_display_name, author.display_name), parent=self, question=True) == QtGui.QMessageBox.Yes: - Receiver.send_message(u'cursor_busy') - Receiver.send_message(u'openlp_process_events') - self.mergeAuthors(author) - self.resetAuthors() - Receiver.send_message(u'songs_load_list') - Receiver.send_message(u'cursor_normal') + self.__mergeObjects(author, self.mergeAuthors, + self.resetAuthors) else: # We restore the author's old first and last name as well as # his display name. author.first_name = temp_first_name author.last_name = temp_last_name author.display_name = temp_display_name - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified author, because the ' 'author already exists.')) @@ -341,24 +314,20 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(topic): self.resetTopics() else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) - elif criticalErrorMessageBox( + elif critical_error_message_box( message=unicode(translate('SongsPlugin.SongMaintenanceForm', 'The topic %s already exists. Would you like to make songs ' 'with topic %s use the existing topic %s?')) % (topic.name, temp_name, topic.name), parent=self, question=True) == QtGui.QMessageBox.Yes: - Receiver.send_message(u'cursor_busy') - Receiver.send_message(u'openlp_process_events') - self.mergeTopics(topic) - self.resetTopics() - Receiver.send_message(u'cursor_normal') + self.__mergeObjects(topic, self.mergeTopics, self.resetTopics) else: # We restore the topics's old name. topic.name = temp_name - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified topic, because it ' 'already exists.')) @@ -383,25 +352,32 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(book): self.resetBooks() else: - criticalErrorMessageBox( + critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) - elif criticalErrorMessageBox( + elif critical_error_message_box( message=unicode(translate('SongsPlugin.SongMaintenanceForm', 'The book %s already exists. Would you like to make songs ' 'with book %s use the existing book %s?')) % (book.name, temp_name, book.name), parent=self, question=True) == QtGui.QMessageBox.Yes: - Receiver.send_message(u'cursor_busy') - Receiver.send_message(u'openlp_process_events') - self.mergeBooks(book) - self.resetBooks() - Receiver.send_message(u'cursor_normal') + self.__mergeObjects(book, self.mergeBooks, self.resetBooks) else: # We restore the book's old name and publisher. book.name = temp_name book.publisher = temp_publisher + def __mergeObjects(self, dbObject, merge, reset): + """ + Utility method to merge two objects to leave one in the database. + """ + Receiver.send_message(u'cursor_busy') + Receiver.send_message(u'openlp_process_events') + merge(dbObject) + reset() + Receiver.send_message(u'songs_load_list') + Receiver.send_message(u'cursor_normal') + def mergeAuthors(self, old_author): """ Merges two authors into one author. @@ -508,42 +484,32 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): def onAuthorsListRowChanged(self, row): """ - Called when the *authorsListWidget* current's row has changed. - - ``row`` - The current row. If there is no current row, the value is -1 + Called when the *authorsListWidget*'s current row has changed. """ - if row == -1: - self.authorsDeleteButton.setEnabled(False) - self.authorsEditButton.setEnabled(False) - else: - self.authorsDeleteButton.setEnabled(True) - self.authorsEditButton.setEnabled(True) + self.__rowChange(row, self.authorsEditButton, self.authorsDeleteButton) def onTopicsListRowChanged(self, row): """ - Called when the *booksListWidget* current's row has changed. - - ``row`` - The current row. If there is no current row, the value is -1. + Called when the *topicsListWidget*'s current row has changed. """ - if row == -1: - self.topicsDeleteButton.setEnabled(False) - self.topicsEditButton.setEnabled(False) - else: - self.topicsDeleteButton.setEnabled(True) - self.topicsEditButton.setEnabled(True) + self.__rowChange(row, self.topicsEditButton, self.topicsDeleteButton) def onBooksListRowChanged(self, row): """ - Called when the *booksListWidget* current's row has changed. + Called when the *booksListWidget*'s current row has changed. + """ + self.__rowChange(row, self.booksEditButton, self.booksDeleteButton) + + def __rowChange(self, row, editButton, deleteButton): + """ + Utility method to toggle if buttons are enabled. ``row`` The current row. If there is no current row, the value is -1. """ if row == -1: - self.booksDeleteButton.setEnabled(False) - self.booksEditButton.setEnabled(False) + deleteButton.setEnabled(False) + editButton.setEnabled(False) else: - self.booksDeleteButton.setEnabled(True) - self.booksEditButton.setEnabled(True) + deleteButton.setEnabled(True) + editButton.setEnabled(True) diff --git a/openlp/plugins/songs/forms/topicsdialog.py b/openlp/plugins/songs/forms/topicsdialog.py index ca0bbed97..f2c9fdeba 100644 --- a/openlp/plugins/songs/forms/topicsdialog.py +++ b/openlp/plugins/songs/forms/topicsdialog.py @@ -27,6 +27,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate +from openlp.core.lib.ui import save_cancel_button_box class Ui_TopicsDialog(object): def setupUi(self, topicsDialog): @@ -43,17 +44,9 @@ class Ui_TopicsDialog(object): self.nameLabel.setBuddy(self.nameEdit) self.nameLayout.addRow(self.nameLabel, self.nameEdit) self.dialogLayout.addLayout(self.nameLayout) - self.buttonBox = QtGui.QDialogButtonBox(topicsDialog) - self.buttonBox.setStandardButtons( - QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel) - self.buttonBox.setObjectName(u'buttonBox') - self.dialogLayout.addWidget(self.buttonBox) + self.dialogLayout.addWidget(save_cancel_button_box(topicsDialog)) self.retranslateUi(topicsDialog) topicsDialog.setMaximumHeight(topicsDialog.sizeHint().height()) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'accepted()'), topicsDialog.accept) - QtCore.QObject.connect(self.buttonBox, - QtCore.SIGNAL(u'rejected()'), topicsDialog.reject) QtCore.QMetaObject.connectSlotsByName(topicsDialog) def retranslateUi(self, topicsDialog): diff --git a/openlp/plugins/songs/forms/topicsform.py b/openlp/plugins/songs/forms/topicsform.py index 4ab2b63fa..792570c93 100644 --- a/openlp/plugins/songs/forms/topicsform.py +++ b/openlp/plugins/songs/forms/topicsform.py @@ -27,7 +27,7 @@ from PyQt4 import QtGui from openlp.core.lib import translate -from openlp.core.ui import criticalErrorMessageBox +from openlp.core.lib.ui import critical_error_message_box from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog class TopicsForm(QtGui.QDialog, Ui_TopicsDialog): @@ -49,7 +49,8 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog): def accept(self): if not self.nameEdit.text(): - criticalErrorMessageBox(message=translate('SongsPlugin.TopicsForm', + critical_error_message_box( + message=translate('SongsPlugin.TopicsForm', 'You need to type in a topic name.')) self.nameEdit.setFocus() return False diff --git a/openlp/plugins/songs/lib/db.py b/openlp/plugins/songs/lib/db.py index 838172893..2bbf818b3 100644 --- a/openlp/plugins/songs/lib/db.py +++ b/openlp/plugins/songs/lib/db.py @@ -39,6 +39,7 @@ class Author(BaseModel): """ pass + class Book(BaseModel): """ Book model @@ -47,30 +48,115 @@ class Book(BaseModel): return u'' % ( str(self.id), self.name, self.publisher) + class MediaFile(BaseModel): """ MediaFile model """ pass + class Song(BaseModel): """ Song model """ pass + class Topic(BaseModel): """ Topic model """ pass + def init_schema(url): + """ - Setup the songs database connection and initialise the database schema + Setup the songs database connection and initialise the database schema. ``url`` The database to setup + + The song database contains the following tables: + + * authors + * authors_songs + * media_files + * media_files_songs + * song_books + * songs + * songs_topics + * topics + + **authors** Table + This table holds the names of all the authors. It has the following + columns: + + * id + * first_name + * last_name + * display_name + + **authors_songs Table** + This is a bridging table between the *authors* and *songs* tables, which + serves to create a many-to-many relationship between the two tables. It + has the following columns: + + * author_id + * song_id + + **media_files Table** + * id + * file_name + * type + + **media_files_songs Table** + * media_file_id + * song_id + + **song_books Table** + The *song_books* table holds a list of books that a congregation gets + their songs from, or old hymnals now no longer used. This table has the + following columns: + + * id + * name + * publisher + + **songs Table** + This table contains the songs, and each song has a list of attributes. + The *songs* table has the following columns: + + * id + * song_book_id + * title + * alternate_title + * lyrics + * verse_order + * copyright + * comments + * ccli_number + * song_number + * theme_name + * search_title + * search_lyrics + + **songs_topics Table** + This is a bridging table between the *songs* and *topics* tables, which + serves to create a many-to-many relationship between the two tables. It + has the following columns: + + * song_id + * topic_id + + **topics Table** + The topics table holds a selection of topics that songs can cover. This + is useful when a worship leader wants to select songs with a certain + theme. This table has the following columns: + + * id + * name """ session, metadata = init_db(url) diff --git a/openlp/plugins/songs/lib/easislidesimport.py b/openlp/plugins/songs/lib/easislidesimport.py index 84e7a3841..0b10ce428 100644 --- a/openlp/plugins/songs/lib/easislidesimport.py +++ b/openlp/plugins/songs/lib/easislidesimport.py @@ -133,29 +133,37 @@ class EasiSlidesImport(SongImport): pass def _add_copyright(self, song): - copyright = [] + """ + Assign the copyright information from the import to the song being + created. + + ``song`` + The current song being imported. + """ + copyright_list = [] + self.__add_copyright_element(copyright_list, song.Copyright) + self.__add_copyright_element(copyright_list, song.LicenceAdmin1) + self.__add_copyright_element(copyright_list, song.LicenceAdmin2) + self.add_copyright(u' '.join(copyright_list)) + + def __add_copyright_element(self, copyright_list, element): + """ + Add a piece of copyright to the total copyright information for the + song. + + ``copyright_list`` + The array to add the information to. + + ``element`` + The imported variable to get the data from. + """ try: - copyright.append(unicode(song.Copyright).strip()) + copyright_list.append(unicode(element).strip()) except UnicodeDecodeError: - log.exception(u'Unicode decode error while decoding Copyright') + log.exception(u'Unicode error decoding %s' % element) self._success = False except AttributeError: pass - try: - copyright.append(unicode(song.LicenceAdmin1).strip()) - except UnicodeDecodeError: - log.exception(u'Unicode decode error while decoding LicenceAdmin1') - self._success = False - except AttributeError: - pass - try: - copyright.append(unicode(song.LicenceAdmin2).strip()) - except UnicodeDecodeError: - log.exception(u'Unicode decode error while decoding LicenceAdmin2') - self._success = False - except AttributeError: - pass - self.add_copyright(u' '.join(copyright)) def _parse_and_add_lyrics(self, song): try: diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index dc51f97f5..95337b29f 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -95,8 +95,6 @@ class SongMediaItem(MediaManagerItem): self.searchLayout.addLayout(self.searchButtonLayout) self.pageLayout.addWidget(self.searchWidget) # Signals and slots - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'plugin_list_refresh'), self.onSearchTextButtonClick) QtCore.QObject.connect(self.searchTextEdit, QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick) QtCore.QObject.connect(self.searchTextButton, @@ -337,16 +335,7 @@ class SongMediaItem(MediaManagerItem): author_list = u'' author_audit = [] ccli = u'' - if item is None: - if self.remoteTriggered is None: - item = self.listView.currentItem() - if item is None: - return False - item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] - else: - item_id = self.remoteSong - else: - item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + item_id = self._getIdOfItemToGenerate(item, self.remoteSong) service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsLoop) @@ -442,6 +431,7 @@ class SongMediaItem(MediaManagerItem): if add_song: if self.addSongFromService: editId = self.openLyrics.xml_to_song(item.xml_version) + self.onSearchTextButtonClick() # Update service with correct song id. if editId: Receiver.send_message(u'service_item_update',