This commit is contained in:
Andreas Preikschat 2011-02-06 20:50:39 +01:00
commit a5a394a290
67 changed files with 1566 additions and 2134 deletions

View File

@ -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 <i></i><b></b><u></u> can also be used within the lyrics test.
! Please note that this format has been checked at http://validator.w3.org/#validate_by_upload
<lyrics lang="en_US">
<title>Amazing Grace</title>
<verse name="v1">
<theme>name of verse specific theme (optional)</theme>
<comment>any text (optional)</comment>
<part name="men">
Amazing grace, how ...
</part>
<part name="women">
A b c
D e f
</part>
...
</verse>
<verse name="c">
<theme>name of verse specific theme (optional)</theme>
<comment>any text (optional)</comment>
...
</verse>
</lyrics>
<lyrics lang="de_DE">
<title>Erstaunliche Anmut</title>
<verse name="v1">
Erstaunliche Anmut, wie
...
</verse>
<verse name="c">
...
</verse>
</lyrics>

View File

@ -76,7 +76,7 @@ class OpenLP(QtGui.QApplication):
""" """
Load and store current Application Version Load and store current Application Version
""" """
if u'--dev-version' in sys.argv: if u'--dev-version' in sys.argv or u'-d' in sys.argv:
# If we're running the dev version, let's use bzr to get the version # If we're running the dev version, let's use bzr to get the version
try: try:
# If bzrlib is availble, use it # If bzrlib is availble, use it
@ -216,6 +216,7 @@ class OpenLP(QtGui.QApplication):
Sets the Busy Cursor for the Application Sets the Busy Cursor for the Application
""" """
self.setOverrideCursor(QtCore.Qt.BusyCursor) self.setOverrideCursor(QtCore.Qt.BusyCursor)
self.processEvents()
def setNormalCursor(self): def setNormalCursor(self):
""" """

View File

@ -31,6 +31,8 @@ import logging
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.lib import build_icon
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class OpenLPDockWidget(QtGui.QDockWidget): class OpenLPDockWidget(QtGui.QDockWidget):
@ -47,4 +49,4 @@ class OpenLPDockWidget(QtGui.QDockWidget):
if name: if name:
self.setObjectName(name) self.setObjectName(name)
if icon: if icon:
self.setWindowIcon(icon) self.setWindowIcon(build_icon(icon))

View File

@ -103,7 +103,6 @@ class MediaManagerItem(QtGui.QWidget):
self.icon = build_icon(icon) self.icon = build_icon(icon)
self.toolbar = None self.toolbar = None
self.remoteTriggered = None self.remoteTriggered = None
self.serviceItemIconName = None
self.singleServiceItem = True self.singleServiceItem = True
self.pageLayout = QtGui.QVBoxLayout(self) self.pageLayout = QtGui.QVBoxLayout(self)
self.pageLayout.setSpacing(0) self.pageLayout.setSpacing(0)
@ -159,7 +158,7 @@ class MediaManagerItem(QtGui.QWidget):
``icon`` ``icon``
The icon of the button. This can be an instance of QIcon, or a The icon of the button. This can be an instance of QIcon, or a
string cotaining either the absolute path to the image, or an string containing either the absolute path to the image, or an
internal resource path starting with ':/'. internal resource path starting with ':/'.
``slot`` ``slot``
@ -246,7 +245,7 @@ class MediaManagerItem(QtGui.QWidget):
preview_string[u'title'], preview_string[u'title'],
preview_string[u'tooltip'], preview_string[u'tooltip'],
u':/general/general_preview.png', self.onPreviewClick) u':/general/general_preview.png', self.onPreviewClick)
## Live Button ## ## Live Button ##
live_string = self.plugin.getString(StringContent.Live) live_string = self.plugin.getString(StringContent.Live)
self.addToolbarButton( self.addToolbarButton(
live_string[u'title'], live_string[u'title'],
@ -367,33 +366,34 @@ class MediaManagerItem(QtGui.QWidget):
count += 1 count += 1
return filelist return filelist
def validate(self, file, thumb): def validate(self, image, thumb):
""" """
Validates to see if the file still exists or thumbnail is up to date Validates whether an image still exists and, if it does, is the
thumbnail representation of the image up to date.
""" """
if not os.path.exists(file): if not os.path.exists(image):
return False return False
if os.path.exists(thumb): if os.path.exists(thumb):
filedate = os.stat(file).st_mtime imageDate = os.stat(image).st_mtime
thumbdate = os.stat(thumb).st_mtime thumbDate = os.stat(thumb).st_mtime
# if file updated rebuild icon # If image has been updated rebuild icon
if filedate > thumbdate: if imageDate > thumbDate:
self.iconFromFile(file, thumb) self.iconFromFile(image, thumb)
else: else:
self.iconFromFile(file, thumb) self.iconFromFile(image, thumb)
return True return True
def iconFromFile(self, file, thumb): def iconFromFile(self, image, thumb):
""" """
Create a thumbnail icon from a given file Create a thumbnail icon from a given image.
``file`` ``image``
The file to create the icon from The image file to create the icon from.
``thumb`` ``thumb``
The filename to save the thumbnail to The filename to save the thumbnail to
""" """
icon = build_icon(unicode(file)) icon = build_icon(unicode(image))
pixmap = icon.pixmap(QtCore.QSize(88, 50)) pixmap = icon.pixmap(QtCore.QSize(88, 50))
ext = os.path.splitext(thumb)[1].lower() ext = os.path.splitext(thumb)[1].lower()
pixmap.save(thumb, ext[1:]) pixmap.save(thumb, ext[1:])
@ -404,12 +404,16 @@ class MediaManagerItem(QtGui.QWidget):
u'defined by the plugin') u'defined by the plugin')
def onNewClick(self): def onNewClick(self):
raise NotImplementedError(u'MediaManagerItem.onNewClick needs to be ' """
u'defined by the plugin') Hook for plugins to define behaviour for adding new items.
"""
pass
def onEditClick(self): def onEditClick(self):
raise NotImplementedError(u'MediaManagerItem.onEditClick needs to be ' """
u'defined by the plugin') Hook for plugins to define behaviour for editing items.
"""
pass
def onDeleteClick(self): def onDeleteClick(self):
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to ' raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to '
@ -508,7 +512,7 @@ class MediaManagerItem(QtGui.QWidget):
'No Service Item Selected'), 'No Service Item Selected'),
translate('OpenLP.MediaManagerItem', translate('OpenLP.MediaManagerItem',
'You must select an existing service item to add to.')) '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.generateSlideData(serviceItem)
self.parent.serviceManager.addServiceItem(serviceItem, self.parent.serviceManager.addServiceItem(serviceItem,
replace=True) replace=True)
@ -525,10 +529,7 @@ class MediaManagerItem(QtGui.QWidget):
Common method for generating a service item Common method for generating a service item
""" """
serviceItem = ServiceItem(self.parent) serviceItem = ServiceItem(self.parent)
if self.serviceItemIconName: serviceItem.add_icon(self.parent.icon_path)
serviceItem.add_icon(self.serviceItemIconName)
else:
serviceItem.add_icon(self.parent.icon_path)
if self.generateSlideData(serviceItem, item, xmlVersion): if self.generateSlideData(serviceItem, item, xmlVersion):
return serviceItem return serviceItem
else: else:
@ -540,3 +541,25 @@ class MediaManagerItem(QtGui.QWidget):
individual service items need to be processed by the plugins individual service items need to be processed by the plugins
""" """
pass 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

View File

@ -42,6 +42,7 @@ class PluginStatus(object):
Inactive = 0 Inactive = 0
Disabled = -1 Disabled = -1
class StringContent(object): class StringContent(object):
Name = u'name' Name = u'name'
Import = u'import' Import = u'import'
@ -54,6 +55,7 @@ class StringContent(object):
Service = u'service' Service = u'service'
VisibleName = u'visible_name' VisibleName = u'visible_name'
class Plugin(QtCore.QObject): class Plugin(QtCore.QObject):
""" """
Base class for openlp plugins to inherit from. Base class for openlp plugins to inherit from.
@ -116,7 +118,7 @@ class Plugin(QtCore.QObject):
class MyPlugin(Plugin): class MyPlugin(Plugin):
def __init__(self): def __init__(self):
Plugin.__init(self, u'MyPlugin', u'0.1') Plugin.__init__(self, u'MyPlugin', u'0.1')
``name`` ``name``
Defaults to *None*. The name of the plugin. Defaults to *None*. The name of the plugin.

View File

@ -93,15 +93,15 @@ class SearchEdit(QtGui.QLineEdit):
``event`` ``event``
The event that happened. The event that happened.
""" """
sz = self.clearButton.size() size = self.clearButton.size()
frameWidth = self.style().pixelMetric( frameWidth = self.style().pixelMetric(
QtGui.QStyle.PM_DefaultFrameWidth) QtGui.QStyle.PM_DefaultFrameWidth)
self.clearButton.move(self.rect().right() - frameWidth - sz.width(), self.clearButton.move(self.rect().right() - frameWidth - size.width(),
(self.rect().bottom() + 1 - sz.height()) / 2) (self.rect().bottom() + 1 - size.height()) / 2)
if hasattr(self, u'menuButton'): if hasattr(self, u'menuButton'):
sz = self.menuButton.size() size = self.menuButton.size()
self.menuButton.move(self.rect().left() + frameWidth + 2, 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): def currentSearchType(self):
""" """

View File

@ -91,21 +91,30 @@ class ThemeLevel(object):
Song = 3 Song = 3
class BackgroundType(object): class BackgroundType(object):
"""
Type enumeration for backgrounds.
"""
Solid = 0 Solid = 0
Gradient = 1 Gradient = 1
Image = 2 Image = 2
@staticmethod @staticmethod
def to_string(type): def to_string(background_type):
if type == BackgroundType.Solid: """
Return a string representation of a background type.
"""
if background_type == BackgroundType.Solid:
return u'solid' return u'solid'
elif type == BackgroundType.Gradient: elif background_type == BackgroundType.Gradient:
return u'gradient' return u'gradient'
elif type == BackgroundType.Image: elif background_type == BackgroundType.Image:
return u'image' return u'image'
@staticmethod @staticmethod
def from_string(type_string): def from_string(type_string):
"""
Return a background type for the given string.
"""
if type_string == u'solid': if type_string == u'solid':
return BackgroundType.Solid return BackgroundType.Solid
elif type_string == u'gradient': elif type_string == u'gradient':
@ -114,6 +123,9 @@ class BackgroundType(object):
return BackgroundType.Image return BackgroundType.Image
class BackgroundGradientType(object): class BackgroundGradientType(object):
"""
Type enumeration for background gradients.
"""
Horizontal = 0 Horizontal = 0
Vertical = 1 Vertical = 1
Circular = 2 Circular = 2
@ -121,20 +133,26 @@ class BackgroundGradientType(object):
LeftBottom = 4 LeftBottom = 4
@staticmethod @staticmethod
def to_string(type): def to_string(gradient_type):
if type == BackgroundGradientType.Horizontal: """
Return a string representation of a background gradient type.
"""
if gradient_type == BackgroundGradientType.Horizontal:
return u'horizontal' return u'horizontal'
elif type == BackgroundGradientType.Vertical: elif gradient_type == BackgroundGradientType.Vertical:
return u'vertical' return u'vertical'
elif type == BackgroundGradientType.Circular: elif gradient_type == BackgroundGradientType.Circular:
return u'circular' return u'circular'
elif type == BackgroundGradientType.LeftTop: elif gradient_type == BackgroundGradientType.LeftTop:
return u'leftTop' return u'leftTop'
elif type == BackgroundGradientType.LeftBottom: elif gradient_type == BackgroundGradientType.LeftBottom:
return u'leftBottom' return u'leftBottom'
@staticmethod @staticmethod
def from_string(type_string): def from_string(type_string):
"""
Return a background gradient type for the given string.
"""
if type_string == u'horizontal': if type_string == u'horizontal':
return BackgroundGradientType.Horizontal return BackgroundGradientType.Horizontal
elif type_string == u'vertical': elif type_string == u'vertical':
@ -147,19 +165,25 @@ class BackgroundGradientType(object):
return BackgroundGradientType.LeftBottom return BackgroundGradientType.LeftBottom
class HorizontalType(object): class HorizontalType(object):
"""
Type enumeration for horizontal alignment.
"""
Left = 0 Left = 0
Center = 1 Center = 1
Right = 2 Right = 2
class VerticalType(object): class VerticalType(object):
"""
Type enumeration for vertical alignment.
"""
Top = 0 Top = 0
Middle = 1 Middle = 1
Bottom = 2 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'] 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'width', u'shadow_size', u'outline_size', u'horizontal_align',
u'vertical_align', u'wrap_style'] u'vertical_align', u'wrap_style']
@ -514,9 +538,9 @@ class ThemeXML(object):
return return
field = self._de_hump(element) field = self._de_hump(element)
tag = master + u'_' + field tag = master + u'_' + field
if field in boolean_list: if field in BOOLEAN_LIST:
setattr(self, tag, str_to_bool(value)) setattr(self, tag, str_to_bool(value))
elif field in integer_list: elif field in INTEGER_LIST:
setattr(self, tag, int(value)) setattr(self, tag, int(value))
else: else:
# make string value unicode # make string value unicode

View File

@ -61,7 +61,7 @@ class OpenLPToolbar(QtGui.QToolBar):
``icon`` ``icon``
The icon of the button. This can be an instance of QIcon, or a The icon of the button. This can be an instance of QIcon, or a
string cotaining either the absolute path to the image, or an string containing either the absolute path to the image, or an
internal resource path starting with ':/'. internal resource path starting with ':/'.
``tooltip`` ``tooltip``
@ -73,13 +73,13 @@ class OpenLPToolbar(QtGui.QToolBar):
``checkable`` ``checkable``
If *True* the button has two, *off* and *on*, states. Default is If *True* the button has two, *off* and *on*, states. Default is
*False*, which means the buttons has only one state. *False*, which means the buttons has only one state.
``shortcut`` ``shortcut``
The primary shortcut for this action The primary shortcut for this action
``alternate`` ``alternate``
The alternate shortcut for this action The alternate shortcut for this action
``context`` ``context``
Specify the context in which this shortcut is valid Specify the context in which this shortcut is valid
""" """

221
openlp/core/lib/ui.py Normal file
View File

@ -0,0 +1,221 @@
# -*- 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 build_icon, Receiver, translate
log = logging.getLogger(__name__)
def add_welcome_page(parent, image):
"""
Generate an opening welcome page for a wizard using a provided image.
``parent``
A ``QWizard`` object to add the welcome page to.
``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 create_save_cancel_button_box(parent):
"""
Creates a standard dialog button box with save and cancel buttons. The
button box is connected to the parent's ``accept()`` and ``reject()``
methods to handle the default ``accepted()`` and ``rejected()`` signals.
``parent``
The parent object. This should be a ``QWidget`` descendant.
"""
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
def create_delete_push_button(parent, icon=None):
"""
Creates a standard push button with a delete label and optional icon. The
button is connected to the parent's ``onDeleteButtonClicked()`` method to
handle the ``clicked()`` signal.
``parent``
The parent object. This should be a ``QWidget`` descendant.
``icon``
An icon to display on the button. This can be either a ``QIcon``, a
resource path or a file name.
"""
delete_button = QtGui.QPushButton(parent)
delete_button.setObjectName(u'deleteButton')
delete_icon = icon if icon else u':/general/general_delete.png'
delete_button.setIcon(build_icon(delete_icon))
delete_button.setText(translate('OpenLP.Ui', '&Delete'))
delete_button.setToolTip(
translate('OpenLP.Ui', 'Delete the selected item.'))
QtCore.QObject.connect(delete_button,
QtCore.SIGNAL(u'clicked()'), parent.onDeleteButtonClicked)
return delete_button
def create_up_down_push_button_set(parent):
"""
Creates a standard set of two push buttons, one for up and the other for
down, for use with lists. The buttons use arrow icons and no text and are
connected to the parent's ``onUpButtonClicked()`` and
``onDownButtonClicked()`` to handle their respective ``clicked()`` signals.
``parent``
The parent object. This should be a ``QWidget`` descendant.
"""
up_button = QtGui.QPushButton(parent)
up_button.setIcon(build_icon(u':/services/service_up.png'))
up_button.setObjectName(u'upButton')
up_button.setToolTip(
translate('OpenLP.Ui', 'Move selection up one position.'))
down_button = QtGui.QPushButton(parent)
down_button.setIcon(build_icon(u':/services/service_down.png'))
down_button.setObjectName(u'downButton')
down_button.setToolTip(
translate('OpenLP.Ui', 'Move selection down one position.'))
QtCore.QObject.connect(up_button,
QtCore.SIGNAL(u'clicked()'), parent.onUpButtonClicked)
QtCore.QObject.connect(down_button,
QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked)
return up_button, down_button
def base_action(parent, name):
"""
Return the most basic action with the object name set.
"""
action = QtGui.QAction(parent)
action.setObjectName(name)
return action
def checkable_action(parent, name, checked=None):
"""
Return a standard action with the checkable attribute set.
"""
action = base_action(parent, name)
action.setCheckable(True)
if checked is not None:
action.setChecked(checked)
return action
def icon_action(parent, name, icon, checked=None):
"""
Return a standard action with an icon.
"""
if checked is not None:
action = checkable_action(parent, name, checked)
else:
action = base_action(parent, name)
action.setIcon(build_icon(icon))
return action
def shortcut_action(parent, text, shortcuts, function):
"""
Return a shortcut enabled action.
"""
action = QtGui.QAction(text, parent)
action.setShortcuts(shortcuts)
action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), function)
return action
def add_widget_completer(cache, widget):
"""
Adds a text autocompleter to a widget.
``cache``
The list of items to use as suggestions.
``widget``
The object to use the completer.
"""
completer = QtGui.QCompleter(cache)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
widget.setCompleter(completer)

View File

@ -51,34 +51,6 @@ class HideMode(object):
Theme = 2 Theme = 2
Screen = 3 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 themeform import ThemeForm
from filerenameform import FileRenameForm from filerenameform import FileRenameForm
from maindisplay import MainDisplay from maindisplay import MainDisplay
@ -99,6 +71,6 @@ from mediadockmanager import MediaDockManager
from servicemanager import ServiceManager from servicemanager import ServiceManager
from thememanager import ThemeManager from thememanager import ThemeManager
__all__ = ['criticalErrorMessageBox', 'SplashScreen', 'AboutForm', __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay',
'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager', 'SlideController', 'ServiceManager', 'ThemeManager', 'MediaDockManager',
'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm'] 'ServiceItemEditForm']

View File

@ -80,6 +80,16 @@ class AdvancedTab(SettingsTab):
self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox') self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
self.hideMouseLayout.addWidget(self.hideMouseCheckBox) self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
self.leftLayout.addWidget(self.hideMouseGroupBox) self.leftLayout.addWidget(self.hideMouseGroupBox)
self.serviceOrderGroupBox = QtGui.QGroupBox(self.leftColumn)
self.serviceOrderGroupBox.setObjectName(u'serviceOrderGroupBox')
self.serviceOrderLayout = QtGui.QVBoxLayout(self.serviceOrderGroupBox)
self.serviceOrderLayout.setObjectName(u'serviceOrderLayout')
self.detailedServicePrintCheckBox = QtGui.QCheckBox(
self.serviceOrderGroupBox)
self.detailedServicePrintCheckBox.setObjectName(
u'detailedServicePrintCheckBox')
self.serviceOrderLayout.addWidget(self.detailedServicePrintCheckBox)
self.leftLayout.addWidget(self.serviceOrderGroupBox)
# self.sharedDirGroupBox = QtGui.QGroupBox(self.leftColumn) # self.sharedDirGroupBox = QtGui.QGroupBox(self.leftColumn)
# self.sharedDirGroupBox.setObjectName(u'sharedDirGroupBox') # self.sharedDirGroupBox.setObjectName(u'sharedDirGroupBox')
# self.sharedDirLayout = QtGui.QFormLayout(self.sharedDirGroupBox) # self.sharedDirLayout = QtGui.QFormLayout(self.sharedDirGroupBox)
@ -129,6 +139,11 @@ class AdvancedTab(SettingsTab):
'Mouse Cursor')) 'Mouse Cursor'))
self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab', self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab',
'Hide the mouse cursor when moved over the display window')) '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',
'Print slide texts and service item notes as well'))
# self.sharedDirGroupBox.setTitle( # self.sharedDirGroupBox.setTitle(
# translate('AdvancedTab', 'Central Data Store')) # translate('AdvancedTab', 'Central Data Store'))
# self.sharedCheckBox.setText( # self.sharedCheckBox.setText(
@ -164,6 +179,8 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(True)).toBool()) QtCore.QVariant(True)).toBool())
self.hideMouseCheckBox.setChecked( self.hideMouseCheckBox.setChecked(
settings.value(u'hide mouse', QtCore.QVariant(False)).toBool()) settings.value(u'hide mouse', QtCore.QVariant(False)).toBool())
self.detailedServicePrintCheckBox.setChecked(settings.value(
u'detailed service print', QtCore.QVariant(False)).toBool())
settings.endGroup() settings.endGroup()
def save(self): def save(self):
@ -184,6 +201,8 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(self.enableAutoCloseCheckBox.isChecked())) QtCore.QVariant(self.enableAutoCloseCheckBox.isChecked()))
settings.setValue(u'hide mouse', settings.setValue(u'hide mouse',
QtCore.QVariant(self.hideMouseCheckBox.isChecked())) QtCore.QVariant(self.hideMouseCheckBox.isChecked()))
settings.setValue(u'detailed service print',
QtCore.QVariant(self.detailedServicePrintCheckBox.isChecked()))
settings.endGroup() settings.endGroup()
# def onSharedCheckBoxChanged(self, checked): # def onSharedCheckBoxChanged(self, checked):

View File

@ -34,7 +34,7 @@ import cPickle
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate, DisplayTags 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): class DisplayTagTab(SettingsTab):
''' '''
@ -276,7 +276,7 @@ class DisplayTagTab(SettingsTab):
""" """
for html in DisplayTags.get_html_tags(): for html in DisplayTags.get_html_tags():
if self._strip(html[u'start tag']) == u'n': if self._strip(html[u'start tag']) == u'n':
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.DisplayTagTab', 'Update Error'), translate('OpenLP.DisplayTagTab', 'Update Error'),
translate('OpenLP.DisplayTagTab', translate('OpenLP.DisplayTagTab',
'Tag "n" already defined.')) 'Tag "n" already defined.'))
@ -317,7 +317,7 @@ class DisplayTagTab(SettingsTab):
for linenumber, html1 in enumerate(html_expands): for linenumber, html1 in enumerate(html_expands):
if self._strip(html1[u'start tag']) == tag and \ if self._strip(html1[u'start tag']) == tag and \
linenumber != self.selected: linenumber != self.selected:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.DisplayTagTab', 'Update Error'), translate('OpenLP.DisplayTagTab', 'Update Error'),
unicode(translate('OpenLP.DisplayTagTab', unicode(translate('OpenLP.DisplayTagTab',
'Tag %s already defined.')) % tag) 'Tag %s already defined.')) % tag)

View File

@ -46,6 +46,15 @@ class Ui_ExceptionDialog(object):
self.messageLabel.setObjectName(u'messageLabel') self.messageLabel.setObjectName(u'messageLabel')
self.messageLayout.addWidget(self.messageLabel) self.messageLayout.addWidget(self.messageLabel)
self.exceptionLayout.addLayout(self.messageLayout) self.exceptionLayout.addLayout(self.messageLayout)
self.descriptionExplanation = QtGui.QLabel(exceptionDialog)
self.descriptionExplanation.setObjectName(u'descriptionExplanation')
self.exceptionLayout.addWidget(self.descriptionExplanation)
self.descriptionTextEdit = QtGui.QPlainTextEdit(exceptionDialog)
self.descriptionTextEdit.setObjectName(u'descriptionTextEdit')
self.exceptionLayout.addWidget(self.descriptionTextEdit)
self.descriptionWordCount = QtGui.QLabel(exceptionDialog)
self.descriptionWordCount.setObjectName(u'descriptionWordCount')
self.exceptionLayout.addWidget(self.descriptionWordCount)
self.exceptionTextEdit = QtGui.QPlainTextEdit(exceptionDialog) self.exceptionTextEdit = QtGui.QPlainTextEdit(exceptionDialog)
self.exceptionTextEdit.setReadOnly(True) self.exceptionTextEdit.setReadOnly(True)
self.exceptionTextEdit.setObjectName(u'exceptionTextEdit') self.exceptionTextEdit.setObjectName(u'exceptionTextEdit')
@ -65,19 +74,31 @@ class Ui_ExceptionDialog(object):
self.saveReportButton.setObjectName(u'saveReportButton') self.saveReportButton.setObjectName(u'saveReportButton')
self.exceptionButtonBox.addButton(self.saveReportButton, self.exceptionButtonBox.addButton(self.saveReportButton,
QtGui.QDialogButtonBox.ActionRole) QtGui.QDialogButtonBox.ActionRole)
self.attachFileButton = QtGui.QPushButton(exceptionDialog)
self.attachFileButton.setIcon(build_icon(u':/general/general_open.png'))
self.attachFileButton.setObjectName(u'attachFileButton')
self.exceptionButtonBox.addButton(self.attachFileButton,
QtGui.QDialogButtonBox.ActionRole)
self.retranslateUi(exceptionDialog) self.retranslateUi(exceptionDialog)
QtCore.QObject.connect(self.descriptionTextEdit,
QtCore.SIGNAL(u'textChanged()'), self.onDescriptionUpdated)
QtCore.QObject.connect(self.exceptionButtonBox, QtCore.QObject.connect(self.exceptionButtonBox,
QtCore.SIGNAL(u'rejected()'), exceptionDialog.reject) QtCore.SIGNAL(u'rejected()'), exceptionDialog.reject)
QtCore.QObject.connect(self.sendReportButton, QtCore.QObject.connect(self.sendReportButton,
QtCore.SIGNAL(u'pressed()'), self.onSendReportButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onSendReportButtonPressed)
QtCore.QObject.connect(self.saveReportButton, QtCore.QObject.connect(self.saveReportButton,
QtCore.SIGNAL(u'pressed()'), self.onSaveReportButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onSaveReportButtonPressed)
QtCore.QObject.connect(self.attachFileButton,
QtCore.SIGNAL(u'pressed()'), self.onAttachFileButtonPressed)
QtCore.QMetaObject.connectSlotsByName(exceptionDialog) QtCore.QMetaObject.connectSlotsByName(exceptionDialog)
def retranslateUi(self, exceptionDialog): def retranslateUi(self, exceptionDialog):
exceptionDialog.setWindowTitle( exceptionDialog.setWindowTitle(
translate('OpenLP.ExceptionDialog', 'Error Occurred')) translate('OpenLP.ExceptionDialog', 'Error Occurred'))
self.descriptionExplanation.setText(translate('OpenLP.ExceptionDialog',
'Please enter a description of what you were doing to cause this '
'error \n(Minimum 20 characters)'))
self.messageLabel.setText(translate('OpenLP.ExceptionDialog', 'Oops! ' self.messageLabel.setText(translate('OpenLP.ExceptionDialog', 'Oops! '
'OpenLP hit a problem, and couldn\'t recover. The text in the box ' 'OpenLP hit a problem, and couldn\'t recover. The text in the box '
'below contains information that might be helpful to the OpenLP ' 'below contains information that might be helpful to the OpenLP '
@ -88,3 +109,5 @@ class Ui_ExceptionDialog(object):
'Send E-Mail')) 'Send E-Mail'))
self.saveReportButton.setText(translate('OpenLP.ExceptionDialog', self.saveReportButton.setText(translate('OpenLP.ExceptionDialog',
'Save to File')) 'Save to File'))
self.attachFileButton.setText(translate('OpenLP.ExceptionDialog',
'Attach File'))

View File

@ -70,8 +70,15 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
self.setupUi(self) self.setupUi(self)
self.settingsSection = u'crashreport' self.settingsSection = u'crashreport'
def exec_(self):
self.descriptionTextEdit.setPlainText(u'')
self.onDescriptionUpdated()
self.fileAttachment = None
return QtGui.QDialog.exec_(self)
def _createReport(self): def _createReport(self):
openlp_version = self.parent().applicationVersion[u'full'] openlp_version = self.parent().applicationVersion[u'full']
description = unicode(self.descriptionTextEdit.toPlainText())
traceback = unicode(self.exceptionTextEdit.toPlainText()) traceback = unicode(self.exceptionTextEdit.toPlainText())
system = unicode(translate('OpenLP.ExceptionForm', system = unicode(translate('OpenLP.ExceptionForm',
'Platform: %s\n')) % platform.platform() 'Platform: %s\n')) % platform.platform()
@ -90,7 +97,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
system = system + u'Desktop: KDE SC\n' system = system + u'Desktop: KDE SC\n'
elif os.environ.get(u'GNOME_DESKTOP_SESSION_ID'): elif os.environ.get(u'GNOME_DESKTOP_SESSION_ID'):
system = system + u'Desktop: GNOME\n' system = system + u'Desktop: GNOME\n'
return (openlp_version, traceback, system, libraries) return (openlp_version, description, traceback, system, libraries)
def onSaveReportButtonPressed(self): def onSaveReportButtonPressed(self):
""" """
@ -99,6 +106,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
report = unicode(translate('OpenLP.ExceptionForm', report = unicode(translate('OpenLP.ExceptionForm',
'**OpenLP Bug Report**\n' '**OpenLP Bug Report**\n'
'Version: %s\n\n' 'Version: %s\n\n'
'--- Details of the Exception. ---\n\n%s\n\n '
'--- Exception Traceback ---\n%s\n' '--- Exception Traceback ---\n%s\n'
'--- System information ---\n%s\n' '--- System information ---\n%s\n'
'--- Library Versions ---\n%s\n')) '--- Library Versions ---\n%s\n'))
@ -132,18 +140,48 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
body = unicode(translate('OpenLP.ExceptionForm', body = unicode(translate('OpenLP.ExceptionForm',
'*OpenLP Bug Report*\n' '*OpenLP Bug Report*\n'
'Version: %s\n\n' 'Version: %s\n\n'
'--- Please enter the report below this line. ---\n\n\n' '--- Details of the Exception. ---\n\n%s\n\n '
'--- Exception Traceback ---\n%s\n' '--- Exception Traceback ---\n%s\n'
'--- System information ---\n%s\n' '--- System information ---\n%s\n'
'--- Library Versions ---\n%s\n', '--- Library Versions ---\n%s\n',
'Please add the information that bug reports are favoured written ' 'Please add the information that bug reports are favoured written '
'in English.')) 'in English.'))
content = self._createReport() content = self._createReport()
for line in content[1].split(u'\n'): for line in content[2].split(u'\n'):
if re.search(r'[/\\]openlp[/\\]', line): if re.search(r'[/\\]openlp[/\\]', line):
source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line) source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line)
if u':' in line: if u':' in line:
exception = line.split(u'\n')[-1].split(u':')[0] exception = line.split(u'\n')[-1].split(u':')[0]
subject = u'Bug report: %s in %s' % (exception, source) subject = u'Bug report: %s in %s' % (exception, source)
mailto(address=u'bugs@openlp.org', subject=subject, if self.fileAttachment:
body=body % content) mailto(address=u'bugs@openlp.org', subject=subject,
body=body % content, attach=self.fileAttachment)
else:
mailto(address=u'bugs@openlp.org', subject=subject,
body=body % content)
def onDescriptionUpdated(self):
count = int(20 - len(self.descriptionTextEdit.toPlainText()))
if count < 0:
count = 0
self.__buttonState(True)
else:
self.__buttonState(False)
self.descriptionWordCount.setText(
unicode(translate('OpenLP.ExceptionDialog',
'Description characters to enter : %s')) % count )
def onAttachFileButtonPressed(self):
files = QtGui.QFileDialog.getOpenFileName(
self,translate('ImagePlugin.ExceptionDialog',
'Select Attachment'),
SettingsManager.get_last_dir(u'exceptions'),
u'%s (*.*) (*)' %
unicode(translate('ImagePlugin.MediaItem', 'All Files')))
log.info(u'New files(s) %s', unicode(files))
if files:
self.fileAttachment = unicode(files)
def __buttonState(self, state):
self.saveReportButton.setEnabled(state)
self.sendReportButton.setEnabled(state)

View File

@ -51,6 +51,7 @@ class ValidEdit(QtGui.QLineEdit):
else: else:
return self.text() return self.text()
class GeneralTab(SettingsTab): class GeneralTab(SettingsTab):
""" """
GeneralTab is the general settings tab in the settings dialog. GeneralTab is the general settings tab in the settings dialog.

View File

@ -28,11 +28,12 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate
from openlp.core.lib.ui import base_action, checkable_action, icon_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ThemeManager, SlideController, PluginForm, MediaDockManager, \ ThemeManager, SlideController, PluginForm, MediaDockManager, \
ShortcutListForm ShortcutListForm
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate
from openlp.core.utils import AppLocation, add_actions, LanguageManager, \ from openlp.core.utils import AppLocation, add_actions, LanguageManager, \
ActionList ActionList
@ -87,10 +88,10 @@ class Ui_MainWindow(object):
self.screens, True) self.screens, True)
previewVisible = QtCore.QSettings().value( previewVisible = QtCore.QSettings().value(
u'user interface/preview panel', QtCore.QVariant(True)).toBool() 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', liveVisible = QtCore.QSettings().value(u'user interface/live panel',
QtCore.QVariant(True)).toBool() QtCore.QVariant(True)).toBool()
self.liveController.Panel.setVisible(liveVisible) self.liveController.panel.setVisible(liveVisible)
# Create menu # Create menu
self.MenuBar = QtGui.QMenuBar(mainWindow) self.MenuBar = QtGui.QMenuBar(mainWindow)
self.MenuBar.setObjectName(u'MenuBar') self.MenuBar.setObjectName(u'MenuBar')
@ -124,9 +125,8 @@ class Ui_MainWindow(object):
self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel') self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel')
self.StatusBar.addPermanentWidget(self.DefaultThemeLabel) self.StatusBar.addPermanentWidget(self.DefaultThemeLabel)
# Create the MediaManager # Create the MediaManager
self.MediaManagerDock = OpenLPDockWidget( self.MediaManagerDock = OpenLPDockWidget(mainWindow,
mainWindow, u'MediaManagerDock', u'MediaManagerDock', u':/system/system_mediamanager.png')
build_icon(u':/system/system_mediamanager.png'))
self.MediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE) self.MediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE)
self.MediaManagerDock.setMinimumWidth( self.MediaManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_left) self.settingsmanager.mainwindow_left)
@ -137,9 +137,8 @@ class Ui_MainWindow(object):
mainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea, mainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea,
self.MediaManagerDock) self.MediaManagerDock)
# Create the service manager # Create the service manager
self.ServiceManagerDock = OpenLPDockWidget( self.ServiceManagerDock = OpenLPDockWidget(mainWindow,
mainWindow, u'ServiceManagerDock', u'ServiceManagerDock', u':/system/system_servicemanager.png')
build_icon(u':/system/system_servicemanager.png'))
self.ServiceManagerDock.setMinimumWidth( self.ServiceManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right) self.settingsmanager.mainwindow_right)
self.ServiceManagerContents = ServiceManager(mainWindow, self.ServiceManagerContents = ServiceManager(mainWindow,
@ -148,9 +147,8 @@ class Ui_MainWindow(object):
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self.ServiceManagerDock) self.ServiceManagerDock)
# Create the theme manager # Create the theme manager
self.ThemeManagerDock = OpenLPDockWidget( self.ThemeManagerDock = OpenLPDockWidget(mainWindow,
mainWindow, u'ThemeManagerDock', u'ThemeManagerDock', u':/system/system_thememanager.png')
build_icon(u':/system/system_thememanager.png'))
self.ThemeManagerDock.setMinimumWidth( self.ThemeManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right) self.settingsmanager.mainwindow_right)
self.ThemeManagerContents = ThemeManager(mainWindow, self.ThemeManagerContents = ThemeManager(mainWindow,
@ -160,99 +158,70 @@ class Ui_MainWindow(object):
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self.ThemeManagerDock) self.ThemeManagerDock)
# Create the menu items # Create the menu items
self.FileNewItem = QtGui.QAction(mainWindow) self.FileNewItem = icon_action(mainWindow, u'FileNewItem',
self.FileNewItem.setIcon(build_icon(u':/general/general_new.png')) u':/general/general_new.png')
self.FileNewItem.setObjectName(u'FileNewItem')
mainWindow.actionList.add_action(self.FileNewItem, u'File') mainWindow.actionList.add_action(self.FileNewItem, u'File')
self.FileOpenItem = QtGui.QAction(mainWindow) self.FileOpenItem = icon_action(mainWindow, u'FileOpenItem',
self.FileOpenItem.setIcon(build_icon(u':/general/general_open.png')) u':/general/general_open.png')
self.FileOpenItem.setObjectName(u'FileOpenItem')
mainWindow.actionList.add_action(self.FileOpenItem, u'File') mainWindow.actionList.add_action(self.FileOpenItem, u'File')
self.FileSaveItem = QtGui.QAction(mainWindow) self.FileSaveItem = icon_action(mainWindow, u'FileSaveItem',
self.FileSaveItem.setIcon(build_icon(u':/general/general_save.png')) u':/general/general_save.png')
self.FileSaveItem.setObjectName(u'FileSaveItem')
mainWindow.actionList.add_action(self.FileSaveItem, u'File') mainWindow.actionList.add_action(self.FileSaveItem, u'File')
self.FileSaveAsItem = QtGui.QAction(mainWindow) self.FileSaveAsItem = base_action(mainWindow, u'FileSaveAsItem')
self.FileSaveAsItem.setObjectName(u'FileSaveAsItem')
mainWindow.actionList.add_action(self.FileSaveAsItem, u'File') mainWindow.actionList.add_action(self.FileSaveAsItem, u'File')
self.FileExitItem = QtGui.QAction(mainWindow) self.printServiceOrderItem = base_action(
self.FileExitItem.setIcon(build_icon(u':/system/system_exit.png')) mainWindow, u'printServiceItem')
self.FileExitItem.setObjectName(u'FileExitItem') mainWindow.actionList.add_action(
self.printServiceOrderItem, u'Print Service Order')
self.FileExitItem = icon_action(mainWindow, u'FileExitItem',
u':/system/system_exit.png')
mainWindow.actionList.add_action(self.FileExitItem, u'File') mainWindow.actionList.add_action(self.FileExitItem, u'File')
self.ImportThemeItem = QtGui.QAction(mainWindow) self.ImportThemeItem = base_action(mainWindow, u'ImportThemeItem')
self.ImportThemeItem.setObjectName(u'ImportThemeItem')
mainWindow.actionList.add_action(self.ImportThemeItem, u'Import') mainWindow.actionList.add_action(self.ImportThemeItem, u'Import')
self.ImportLanguageItem = QtGui.QAction(mainWindow) self.ImportLanguageItem = base_action(mainWindow, u'ImportLanguageItem')
self.ImportLanguageItem.setObjectName(u'ImportLanguageItem')
mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import') mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import')
self.ExportThemeItem = QtGui.QAction(mainWindow) self.ExportThemeItem = base_action(mainWindow, u'ExportThemeItem')
self.ExportThemeItem.setObjectName(u'ExportThemeItem')
mainWindow.actionList.add_action(self.ExportThemeItem, u'Export') mainWindow.actionList.add_action(self.ExportThemeItem, u'Export')
self.ExportLanguageItem = QtGui.QAction(mainWindow) self.ExportLanguageItem = base_action(mainWindow, u'ExportLanguageItem')
self.ExportLanguageItem.setObjectName(u'ExportLanguageItem')
mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export') mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export')
self.ViewMediaManagerItem = QtGui.QAction(mainWindow) self.ViewMediaManagerItem = icon_action(mainWindow,
self.ViewMediaManagerItem.setCheckable(True) u'ViewMediaManagerItem', u':/system/system_mediamanager.png',
self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible()) self.MediaManagerDock.isVisible())
self.ViewMediaManagerItem.setIcon( self.ViewThemeManagerItem = icon_action(mainWindow,
build_icon(u':/system/system_mediamanager.png')) u'ViewThemeManagerItem', u':/system/system_thememanager.png',
self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem') self.ThemeManagerDock.isVisible())
self.ViewThemeManagerItem = QtGui.QAction(mainWindow)
self.ViewThemeManagerItem.setCheckable(True)
self.ViewThemeManagerItem.setChecked(self.ThemeManagerDock.isVisible())
self.ViewThemeManagerItem.setIcon(
build_icon(u':/system/system_thememanager.png'))
self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem')
mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View') mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View')
self.ViewServiceManagerItem = QtGui.QAction(mainWindow) self.ViewServiceManagerItem = icon_action(mainWindow,
self.ViewServiceManagerItem.setCheckable(True) u'ViewServiceManagerItem', u':/system/system_servicemanager.png',
self.ViewServiceManagerItem.setChecked(
self.ServiceManagerDock.isVisible()) self.ServiceManagerDock.isVisible())
self.ViewServiceManagerItem.setIcon(
build_icon(u':/system/system_servicemanager.png'))
self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem')
mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View') mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View')
self.ViewPreviewPanel = QtGui.QAction(mainWindow) self.ViewPreviewPanel = checkable_action(mainWindow,
self.ViewPreviewPanel.setCheckable(True) u'ViewPreviewPanel', previewVisible)
self.ViewPreviewPanel.setChecked(previewVisible)
self.ViewPreviewPanel.setObjectName(u'ViewPreviewPanel')
mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View') mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View')
self.ViewLivePanel = QtGui.QAction(mainWindow) self.ViewLivePanel = checkable_action(mainWindow, u'ViewLivePanel',
self.ViewLivePanel.setCheckable(True) liveVisible)
self.ViewLivePanel.setChecked(liveVisible)
self.ViewLivePanel.setObjectName(u'ViewLivePanel')
mainWindow.actionList.add_action(self.ViewLivePanel, u'View') mainWindow.actionList.add_action(self.ViewLivePanel, u'View')
self.ModeDefaultItem = QtGui.QAction(mainWindow) self.ModeDefaultItem = checkable_action(mainWindow, u'ModeDefaultItem')
self.ModeDefaultItem.setCheckable(True)
self.ModeDefaultItem.setObjectName(u'ModeDefaultItem')
mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode') mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode')
self.ModeSetupItem = QtGui.QAction(mainWindow) self.ModeSetupItem = checkable_action(mainWindow, u'ModeLiveItem')
self.ModeSetupItem.setCheckable(True)
self.ModeSetupItem.setObjectName(u'ModeLiveItem')
mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode') mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode')
self.ModeLiveItem = QtGui.QAction(mainWindow) self.ModeLiveItem = checkable_action(mainWindow, u'ModeLiveItem')
self.ModeLiveItem.setCheckable(True)
self.ModeLiveItem.setObjectName(u'ModeLiveItem')
mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode') mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode')
self.ModeGroup = QtGui.QActionGroup(mainWindow) self.ModeGroup = QtGui.QActionGroup(mainWindow)
self.ModeGroup.addAction(self.ModeDefaultItem) self.ModeGroup.addAction(self.ModeDefaultItem)
self.ModeGroup.addAction(self.ModeSetupItem) self.ModeGroup.addAction(self.ModeSetupItem)
self.ModeGroup.addAction(self.ModeLiveItem) self.ModeGroup.addAction(self.ModeLiveItem)
self.ModeDefaultItem.setChecked(True) self.ModeDefaultItem.setChecked(True)
self.ToolsAddToolItem = QtGui.QAction(mainWindow) self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png')) u':/tools/tools_add.png')
self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem')
mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools') mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools')
self.SettingsPluginListItem = QtGui.QAction(mainWindow) self.SettingsPluginListItem = icon_action(mainWindow,
self.SettingsPluginListItem.setIcon( u'SettingsPluginListItem', u':/system/settings_plugin_list.png')
build_icon(u':/system/settings_plugin_list.png'))
self.SettingsPluginListItem.setObjectName(u'SettingsPluginListItem')
mainWindow.actionList.add_action(self.SettingsPluginListItem, mainWindow.actionList.add_action(self.SettingsPluginListItem,
u'Settings') u'Settings')
# i18n Language Items # i18n Language Items
self.AutoLanguageItem = QtGui.QAction(mainWindow) self.AutoLanguageItem = checkable_action(mainWindow,
self.AutoLanguageItem.setObjectName(u'AutoLanguageItem') u'AutoLanguageItem')
self.AutoLanguageItem.setCheckable(True)
mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings') mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings')
self.LanguageGroup = QtGui.QActionGroup(mainWindow) self.LanguageGroup = QtGui.QActionGroup(mainWindow)
self.LanguageGroup.setExclusive(True) self.LanguageGroup.setExclusive(True)
@ -262,39 +231,28 @@ class Ui_MainWindow(object):
qmList = LanguageManager.get_qm_list() qmList = LanguageManager.get_qm_list()
savedLanguage = LanguageManager.get_language() savedLanguage = LanguageManager.get_language()
for key in sorted(qmList.keys()): for key in sorted(qmList.keys()):
languageItem = QtGui.QAction(mainWindow) languageItem = checkable_action(mainWindow, key)
languageItem.setObjectName(key)
languageItem.setCheckable(True)
if qmList[key] == savedLanguage: if qmList[key] == savedLanguage:
languageItem.setChecked(True) languageItem.setChecked(True)
add_actions(self.LanguageGroup, [languageItem]) add_actions(self.LanguageGroup, [languageItem])
self.SettingsShortcutsItem = QtGui.QAction(mainWindow) self.SettingsShortcutsItem = icon_action(mainWindow,
self.SettingsShortcutsItem.setIcon( u'SettingsShortcutsItem',
build_icon(u':/system/system_configure_shortcuts.png')) u':/system/system_configure_shortcuts.png')
self.SettingsShortcutsItem.setObjectName(u'SettingsShortcutsItem') self.SettingsConfigureItem = icon_action(mainWindow,
self.SettingsConfigureItem = QtGui.QAction(mainWindow) u'SettingsConfigureItem', u':/system/system_settings.png')
self.SettingsConfigureItem.setIcon(
build_icon(u':/system/system_settings.png'))
self.SettingsConfigureItem.setObjectName(u'SettingsConfigureItem')
mainWindow.actionList.add_action(self.SettingsShortcutsItem, mainWindow.actionList.add_action(self.SettingsShortcutsItem,
u'Settings') u'Settings')
self.HelpDocumentationItem = QtGui.QAction(mainWindow) self.HelpDocumentationItem = icon_action(mainWindow,
self.HelpDocumentationItem.setIcon( u'HelpDocumentationItem', u':/system/system_help_contents.png')
build_icon(u':/system/system_help_contents.png'))
self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem')
self.HelpDocumentationItem.setEnabled(False) self.HelpDocumentationItem.setEnabled(False)
mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help') mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help')
self.HelpAboutItem = QtGui.QAction(mainWindow) self.HelpAboutItem = icon_action(mainWindow, u'HelpAboutItem',
self.HelpAboutItem.setIcon( u':/system/system_about.png')
build_icon(u':/system/system_about.png'))
self.HelpAboutItem.setObjectName(u'HelpAboutItem')
mainWindow.actionList.add_action(self.HelpAboutItem, u'Help') mainWindow.actionList.add_action(self.HelpAboutItem, u'Help')
self.HelpOnlineHelpItem = QtGui.QAction(mainWindow) self.HelpOnlineHelpItem = base_action(mainWindow, u'HelpOnlineHelpItem')
self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem')
self.HelpOnlineHelpItem.setEnabled(False) self.HelpOnlineHelpItem.setEnabled(False)
mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help') mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help')
self.HelpWebSiteItem = QtGui.QAction(mainWindow) self.HelpWebSiteItem = base_action(mainWindow, u'HelpWebSiteItem')
self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem')
mainWindow.actionList.add_action(self.HelpWebSiteItem, u'Help') mainWindow.actionList.add_action(self.HelpWebSiteItem, u'Help')
add_actions(self.FileImportMenu, add_actions(self.FileImportMenu,
(self.ImportThemeItem, self.ImportLanguageItem)) (self.ImportThemeItem, self.ImportLanguageItem))
@ -302,8 +260,8 @@ class Ui_MainWindow(object):
(self.ExportThemeItem, self.ExportLanguageItem)) (self.ExportThemeItem, self.ExportLanguageItem))
self.FileMenuActions = (self.FileNewItem, self.FileOpenItem, self.FileMenuActions = (self.FileNewItem, self.FileOpenItem,
self.FileSaveItem, self.FileSaveAsItem, None, self.FileSaveItem, self.FileSaveAsItem, None,
self.FileImportMenu.menuAction(), self.FileExportMenu.menuAction(), self.printServiceOrderItem, None, self.FileImportMenu.menuAction(),
self.FileExitItem) self.FileExportMenu.menuAction(), self.FileExitItem)
add_actions(self.ViewModeMenu, (self.ModeDefaultItem, add_actions(self.ViewModeMenu, (self.ModeDefaultItem,
self.ModeSetupItem, self.ModeLiveItem)) self.ModeSetupItem, self.ModeLiveItem))
add_actions(self.ViewMenu, (self.ViewModeMenu.menuAction(), add_actions(self.ViewMenu, (self.ViewModeMenu.menuAction(),
@ -381,6 +339,12 @@ class Ui_MainWindow(object):
'Save the current service under a new name.')) 'Save the current service under a new name.'))
self.FileSaveAsItem.setShortcut( self.FileSaveAsItem.setShortcut(
translate('OpenLP.MainWindow', 'Ctrl+Shift+S')) translate('OpenLP.MainWindow', 'Ctrl+Shift+S'))
self.printServiceOrderItem.setText(
translate('OpenLP.MainWindow', 'Print Service Order'))
self.printServiceOrderItem.setStatusTip(translate('OpenLP.MainWindow',
'Print the current Service Order.'))
self.printServiceOrderItem.setShortcut(
translate('OpenLP.MainWindow', 'Ctrl+P'))
self.FileExitItem.setText( self.FileExitItem.setText(
translate('OpenLP.MainWindow', 'E&xit')) translate('OpenLP.MainWindow', 'E&xit'))
self.FileExitItem.setStatusTip( self.FileExitItem.setStatusTip(
@ -567,6 +531,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.FileSaveAsItem, QtCore.QObject.connect(self.FileSaveAsItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.saveFileAs) self.ServiceManagerContents.saveFileAs)
QtCore.QObject.connect(self.printServiceOrderItem,
QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.printServiceOrder)
# i18n set signals for languages # i18n set signals for languages
QtCore.QObject.connect(self.AutoLanguageItem, QtCore.QObject.connect(self.AutoLanguageItem,
QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage) QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage)
@ -758,34 +725,29 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
""" """
Put OpenLP into "Default" view mode. Put OpenLP into "Default" view mode.
""" """
settings = QtCore.QSettings() self.setViewMode(True, True, True, True, True, u'default')
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'default')
self.setViewMode(True, True, True, True, True)
def onModeSetupItemClicked(self): def onModeSetupItemClicked(self):
""" """
Put OpenLP into "Setup" view mode. Put OpenLP into "Setup" view mode.
""" """
settings = QtCore.QSettings() self.setViewMode(True, True, False, True, False, u'setup')
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'setup')
self.setViewMode(True, True, False, True, False)
def onModeLiveItemClicked(self): def onModeLiveItemClicked(self):
""" """
Put OpenLP into "Live" view mode. Put OpenLP into "Live" view mode.
""" """
settings = QtCore.QSettings() self.setViewMode(False, True, False, False, True, u'live')
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'live')
self.setViewMode(False, True, False, False, True)
def setViewMode(self, media=True, service=True, theme=True, preview=True, def setViewMode(self, media=True, service=True, theme=True, preview=True,
live=True): live=True, mode=u''):
""" """
Set OpenLP to a different view mode. 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.MediaManagerDock.setVisible(media)
self.ServiceManagerDock.setVisible(service) self.ServiceManagerDock.setVisible(service)
self.ThemeManagerDock.setVisible(theme) self.ThemeManagerDock.setVisible(theme)
@ -926,7 +888,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
True - Visible True - Visible
False - Hidden False - Hidden
""" """
self.previewController.Panel.setVisible(visible) self.previewController.panel.setVisible(visible)
QtCore.QSettings().setValue(u'user interface/preview panel', QtCore.QSettings().setValue(u'user interface/preview panel',
QtCore.QVariant(visible)) QtCore.QVariant(visible))
self.ViewPreviewPanel.setChecked(visible) self.ViewPreviewPanel.setChecked(visible)
@ -941,7 +903,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
True - Visible True - Visible
False - Hidden False - Hidden
""" """
self.liveController.Panel.setVisible(visible) self.liveController.panel.setVisible(visible)
QtCore.QSettings().setValue(u'user interface/live panel', QtCore.QSettings().setValue(u'user interface/live panel',
QtCore.QVariant(visible)) QtCore.QVariant(visible))
self.ViewLivePanel.setChecked(visible) self.ViewLivePanel.setChecked(visible)
@ -991,8 +953,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0] u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
self.FileMenu.clear() self.FileMenu.clear()
add_actions(self.FileMenu, self.FileMenuActions[:-1]) add_actions(self.FileMenu, self.FileMenuActions[:-1])
existingRecentFiles = [file for file in self.recentFiles existingRecentFiles = [recentFile for recentFile in self.recentFiles
if QtCore.QFile.exists(file)] if QtCore.QFile.exists(recentFile)]
recentFilesToDisplay = existingRecentFiles[0:recentFileCount] recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
if recentFilesToDisplay: if recentFilesToDisplay:
self.FileMenu.addSeparator() self.FileMenu.addSeparator()

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import PluginStatus, StringContent, translate from openlp.core.lib import PluginStatus, Receiver, StringContent, translate
from plugindialog import Ui_PluginViewDialog from plugindialog import Ui_PluginViewDialog
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -129,7 +129,9 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
if self.programaticChange: if self.programaticChange:
return return
if status == 0: if status == 0:
Receiver.send_message(u'cursor_busy')
self.activePlugin.toggleStatus(PluginStatus.Active) self.activePlugin.toggleStatus(PluginStatus.Active)
Receiver.send_message(u'cursor_normal')
else: else:
self.activePlugin.toggleStatus(PluginStatus.Inactive) self.activePlugin.toggleStatus(PluginStatus.Inactive)
status_text = unicode( status_text = unicode(

View File

@ -26,7 +26,9 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, build_icon from openlp.core.lib import translate
from openlp.core.lib.ui import create_save_cancel_button_box, \
create_delete_push_button, create_up_down_push_button_set
class Ui_ServiceItemEditDialog(object): class Ui_ServiceItemEditDialog(object):
def setupUi(self, serviceItemEditDialog): def setupUi(self, serviceItemEditDialog):
@ -39,30 +41,19 @@ class Ui_ServiceItemEditDialog(object):
self.dialogLayout.addWidget(self.listWidget, 0, 0) self.dialogLayout.addWidget(self.listWidget, 0, 0)
self.buttonLayout = QtGui.QVBoxLayout() self.buttonLayout = QtGui.QVBoxLayout()
self.buttonLayout.setObjectName(u'buttonLayout') self.buttonLayout.setObjectName(u'buttonLayout')
self.deleteButton = QtGui.QPushButton(serviceItemEditDialog) self.deleteButton = create_delete_push_button(serviceItemEditDialog)
self.deleteButton.setObjectName(u'deleteButton')
self.buttonLayout.addWidget(self.deleteButton) self.buttonLayout.addWidget(self.deleteButton)
self.buttonLayout.addStretch() self.buttonLayout.addStretch()
self.upButton = QtGui.QPushButton(serviceItemEditDialog) self.upButton, self.downButton = create_up_down_push_button_set(
self.upButton.setIcon(build_icon(u':/services/service_up.png')) serviceItemEditDialog)
self.upButton.setObjectName(u'upButton')
self.buttonLayout.addWidget(self.upButton) self.buttonLayout.addWidget(self.upButton)
self.downButton = QtGui.QPushButton(serviceItemEditDialog)
self.downButton.setIcon(build_icon(u':/services/service_down.png'))
self.downButton.setObjectName(u'downButton')
self.buttonLayout.addWidget(self.downButton) self.buttonLayout.addWidget(self.downButton)
self.dialogLayout.addLayout(self.buttonLayout, 0, 1) self.dialogLayout.addLayout(self.buttonLayout, 0, 1)
self.buttonBox = QtGui.QDialogButtonBox(serviceItemEditDialog) self.dialogLayout.addWidget(
self.buttonBox.setStandardButtons( create_save_cancel_button_box(serviceItemEditDialog), 1, 0, 1, 2)
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2)
self.retranslateUi(serviceItemEditDialog) self.retranslateUi(serviceItemEditDialog)
QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog) QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog)
def retranslateUi(self, serviceItemEditDialog): def retranslateUi(self, serviceItemEditDialog):
serviceItemEditDialog.setWindowTitle( serviceItemEditDialog.setWindowTitle(
translate('OpenLP.ServiceItemEditForm', 'Reorder Service Item')) translate('OpenLP.ServiceItemEditForm', 'Reorder Service Item'))
self.deleteButton.setText(translate('OpenLP.ServiceItemEditForm',
'Delete'))

View File

@ -39,17 +39,6 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self.itemList = [] self.itemList = []
# enable drop
QtCore.QObject.connect(self.upButton,
QtCore.SIGNAL(u'clicked()'), self.onItemUp)
QtCore.QObject.connect(self.downButton,
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.QObject.connect(self.listWidget,
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged) QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
@ -81,7 +70,7 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
item_name = QtGui.QListWidgetItem(frame[u'title']) item_name = QtGui.QListWidgetItem(frame[u'title'])
self.listWidget.addItem(item_name) self.listWidget.addItem(item_name)
def onItemDelete(self): def onDeleteButtonClicked(self):
""" """
Delete the current row. Delete the current row.
""" """
@ -96,31 +85,34 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
else: else:
self.listWidget.setCurrentRow(row) self.listWidget.setCurrentRow(row)
def onItemUp(self): def onUpButtonClicked(self):
""" """
Move the current row up in the list. Move the current row up in the list.
""" """
item = self.listWidget.currentItem() self.__moveItem(u'up')
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)
def onItemDown(self): def onDownButtonClicked(self):
""" """
Move the current row down in the list 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() item = self.listWidget.currentItem()
if not item: if not item:
return return
row = self.listWidget.row(item) row = self.listWidget.row(item)
temp = self.itemList[row] temp = self.itemList[row]
self.itemList.remove(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.loadData()
self.listWidget.setCurrentRow(row + 1) self.listWidget.setCurrentRow(row + 1)

View File

@ -36,8 +36,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \ from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \ Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \
ThemeLevel ThemeLevel
from openlp.core.ui import criticalErrorMessageBox, ServiceNoteForm, \ from openlp.core.lib.ui import critical_error_message_box
ServiceItemEditForm from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
split_filename split_filename
@ -491,7 +491,7 @@ class ServiceManager(QtGui.QWidget):
for file in zip.namelist(): for file in zip.namelist():
ucsfile = file_is_unicode(file) ucsfile = file_is_unicode(file)
if not ucsfile: if not ucsfile:
criticalErrorMessageBox( critical_error_message_box(
message=translate('OpenLP.ServiceManager', message=translate('OpenLP.ServiceManager',
'File is not a valid service.\n' 'File is not a valid service.\n'
'The content encoding is not UTF-8.')) 'The content encoding is not UTF-8.'))
@ -506,6 +506,7 @@ class ServiceManager(QtGui.QWidget):
if filePath.endswith(u'osd'): if filePath.endswith(u'osd'):
p_file = filePath p_file = filePath
if 'p_file' in locals(): if 'p_file' in locals():
Receiver.send_message(u'cursor_busy')
fileTo = open(p_file, u'r') fileTo = open(p_file, u'r')
items = cPickle.load(fileTo) items = cPickle.load(fileTo)
fileTo.close() fileTo.close()
@ -520,13 +521,14 @@ class ServiceManager(QtGui.QWidget):
Receiver.send_message(u'%s_service_load' % Receiver.send_message(u'%s_service_load' %
serviceItem.name.lower(), serviceItem) serviceItem.name.lower(), serviceItem)
delete_file(p_file) delete_file(p_file)
Receiver.send_message(u'cursor_normal')
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('OpenLP.ServiceManager', message=translate('OpenLP.ServiceManager',
'File is not a valid service.')) 'File is not a valid service.'))
log.exception(u'File contains no service data') log.exception(u'File contains no service data')
except (IOError, NameError): except (IOError, NameError):
log.exception(u'Problem loading a service file') log.exception(u'Problem loading service file %s' % fileName)
finally: finally:
if fileTo: if fileTo:
fileTo.close() fileTo.close()
@ -536,9 +538,7 @@ class ServiceManager(QtGui.QWidget):
self.mainwindow.addRecentFile(fileName) self.mainwindow.addRecentFile(fileName)
self.setModified(False) self.setModified(False)
QtCore.QSettings(). \ QtCore.QSettings(). \
setValue(u'service/last file',QtCore.QVariant(fileName)) setValue(u'service/last file', QtCore.QVariant(fileName))
# Refresh Plugin lists
Receiver.send_message(u'plugin_list_refresh')
def loadLastFile(self): def loadLastFile(self):
""" """
@ -856,7 +856,7 @@ class ServiceManager(QtGui.QWidget):
one it allows the item to be displayed. one it allows the item to be displayed.
""" """
if serviceItem.is_command(): if serviceItem.is_command():
type = serviceItem._raw_frames[0][u'title'].split(u'.')[1] type = serviceItem._raw_frames[0][u'title'].split(u'.')[-1]
if type not in self.suffixes: if type not in self.suffixes:
serviceItem.is_valid = False serviceItem.is_valid = False
@ -993,7 +993,7 @@ class ServiceManager(QtGui.QWidget):
self.mainwindow.previewController.addServiceManagerItem( self.mainwindow.previewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], child) self.serviceItems[item][u'service_item'], child)
else: else:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', 'Your item cannot be ' translate('OpenLP.ServiceManager', 'Your item cannot be '
'displayed as there is no handler to display it')) 'displayed as there is no handler to display it'))
@ -1027,7 +1027,7 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems[item][u'service_item'], 0) self.serviceItems[item][u'service_item'], 0)
self.mainwindow.liveController.previewListWidget.setFocus() self.mainwindow.liveController.previewListWidget.setFocus()
else: else:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', 'Your item cannot be ' translate('OpenLP.ServiceManager', 'Your item cannot be '
'displayed as the plugin required to display it is missing ' 'displayed as the plugin required to display it is missing '
@ -1182,3 +1182,46 @@ class ServiceManager(QtGui.QWidget):
data_item[u'selected'] = (item == curitem) data_item[u'selected'] = (item == curitem)
data.append(data_item) data.append(data_item)
Receiver.send_message(u'servicemanager_list_response', data) Receiver.send_message(u'servicemanager_list_response', data)
def printServiceOrder(self):
"""
Print a Service Order Sheet.
"""
if not self.serviceItems:
critical_error_message_box(
message=translate('OpenLP.ServiceManager',
'There is no service item in this service.'))
return
printDialog = QtGui.QPrintDialog()
if not printDialog.exec_():
return
text = u'<h2>%s</h2>' % translate('OpenLP.ServiceManager',
'Service Order Sheet')
for item in self.serviceItems:
item = item[u'service_item']
# add the title
text += u'<h4><img src="%s" /> %s</h4>' % (item.icon,
item.get_display_title())
if not QtCore.QSettings().value(u'advanced' +
u'/detailed service print', QtCore.QVariant(True)).toBool():
continue
if item.is_text():
# Add the text of the service item.
for slide in item.get_frames():
text += u'<p>' + slide[u'text'] + u'</p>'
elif item.is_image():
# Add the image names of the service item.
text += u'<ol>'
for slide in range(len(item.get_frames())):
text += u'<li><p>%s</p></li>' % item.get_frame_title(slide)
text += u'</ol>'
if item.foot_text:
# add footer
text += u'<p>%s</p>' % item.foot_text
if item.notes:
# add notes
text += u'<p><b>%s</b> %s</p>' % (translate(
'OpenLP.ServiceManager', 'Notes:'), item.notes)
serviceDocument = QtGui.QTextDocument()
serviceDocument.setHtml(text)
serviceDocument.print_(printDialog.printer())

View File

@ -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'))

View File

@ -26,9 +26,10 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from servicenotedialog import Ui_ServiceNoteEdit from openlp.core.lib import translate
from openlp.core.lib.ui import create_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. 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 Constructor
""" """
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi()
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), self.retranslateUi()
self.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), def setupUi(self):
self.reject) 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(create_save_cancel_button_box(self))
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self):
self.setWindowTitle(
translate('OpenLP.ServiceNoteForm', 'Service Item Notes'))

View File

@ -30,9 +30,10 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
from openlp.core.ui import HideMode, MainDisplay
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \ from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
ItemCapabilities, translate ItemCapabilities, translate
from openlp.core.lib.ui import shortcut_action
from openlp.core.ui import HideMode, MainDisplay
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -77,14 +78,14 @@ class SlideController(QtGui.QWidget):
self.selectedRow = 0 self.selectedRow = 0
self.serviceItem = None self.serviceItem = None
self.alertTab = None self.alertTab = None
self.Panel = QtGui.QWidget(parent.ControlSplitter) self.panel = QtGui.QWidget(parent.ControlSplitter)
self.slideList = {} self.slideList = {}
# Layout for holding panel # Layout for holding panel
self.panelLayout = QtGui.QVBoxLayout(self.Panel) self.panelLayout = QtGui.QVBoxLayout(self.panel)
self.panelLayout.setSpacing(0) self.panelLayout.setSpacing(0)
self.panelLayout.setMargin(0) self.panelLayout.setMargin(0)
# Type label for the top of the slide controller # Type label for the top of the slide controller
self.typeLabel = QtGui.QLabel(self.Panel) self.typeLabel = QtGui.QLabel(self.panel)
if self.isLive: if self.isLive:
self.typeLabel.setText(translate('OpenLP.SlideController', 'Live')) self.typeLabel.setText(translate('OpenLP.SlideController', 'Live'))
self.split = 1 self.split = 1
@ -98,7 +99,7 @@ class SlideController(QtGui.QWidget):
self.typeLabel.setAlignment(QtCore.Qt.AlignCenter) self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
self.panelLayout.addWidget(self.typeLabel) self.panelLayout.addWidget(self.typeLabel)
# Splitter # Splitter
self.splitter = QtGui.QSplitter(self.Panel) self.splitter = QtGui.QSplitter(self.panel)
self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setOrientation(QtCore.Qt.Vertical)
self.panelLayout.addWidget(self.splitter) self.panelLayout.addWidget(self.splitter)
# Actual controller section # Actual controller section
@ -185,13 +186,13 @@ class SlideController(QtGui.QWidget):
u'Stop Loop', u':/media/media_stop.png', u'Stop Loop', u':/media/media_stop.png',
translate('OpenLP.SlideController', 'Stop continuous loop'), translate('OpenLP.SlideController', 'Stop continuous loop'),
self.onStopLoop) self.onStopLoop)
self.DelaySpinBox = QtGui.QSpinBox() self.delaySpinBox = QtGui.QSpinBox()
self.DelaySpinBox.setMinimum(1) self.delaySpinBox.setMinimum(1)
self.DelaySpinBox.setMaximum(180) self.delaySpinBox.setMaximum(180)
self.toolbar.addToolbarWidget(u'Image SpinBox', self.DelaySpinBox) self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
self.DelaySpinBox.setSuffix(translate('OpenLP.SlideController', self.delaySpinBox.setSuffix(translate('OpenLP.SlideController',
's')) 's'))
self.DelaySpinBox.setToolTip(translate('OpenLP.SlideController', self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
'Delay between slides in seconds')) 'Delay between slides in seconds'))
else: else:
self.toolbar.addToolbarSeparator(u'Close Separator') self.toolbar.addToolbarSeparator(u'Close Separator')
@ -317,18 +318,8 @@ class SlideController(QtGui.QWidget):
self.mediabar.setVisible(False) self.mediabar.setVisible(False)
if self.isLive: if self.isLive:
self.setLiveHotkeys(self) self.setLiveHotkeys(self)
self.previewListWidget.addActions( self.__addActionsToWidget(self.previewListWidget)
[self.previousItem, self.__addActionsToWidget(self.display)
self.nextItem,
self.previousService,
self.nextService,
self.escapeItem])
self.display.addActions(
[self.previousItem,
self.nextItem,
self.previousService,
self.nextService,
self.escapeItem])
else: else:
self.setPreviewHotkeys() self.setPreviewHotkeys()
self.previewListWidget.addActions( self.previewListWidget.addActions(
@ -390,28 +381,17 @@ class SlideController(QtGui.QWidget):
self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown]) self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown])
self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut) self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
actionList.add_action(self.nextItem, u'Live') actionList.add_action(self.nextItem, u'Live')
self.previousService = QtGui.QAction(translate( self.previousService = shortcut_action(parent,
'OpenLP.SlideController', 'Previous Service'), parent) translate('OpenLP.SlideController', 'Previous Service'),
self.previousService.setShortcuts([QtCore.Qt.Key_Left, 0]) [QtCore.Qt.Key_Left, 0], self.servicePrevious)
self.previousService.setShortcutContext(
QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(self.previousService,
QtCore.SIGNAL(u'triggered()'), self.servicePrevious)
actionList.add_action(self.previousService, u'Live') actionList.add_action(self.previousService, u'Live')
self.nextService = QtGui.QAction(translate( self.nextService = shortcut_action(parent,
'OpenLP.SlideController', 'Next Service'), parent) translate('OpenLP.SlideController', 'Next Service'),
self.nextService.setShortcuts([QtCore.Qt.Key_Right, 0]) [QtCore.Qt.Key_Right, 0], self.serviceNext)
self.nextService.setShortcutContext(
QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(self.nextService,
QtCore.SIGNAL(u'triggered()'), self.serviceNext)
actionList.add_action(self.nextService, u'Live') actionList.add_action(self.nextService, u'Live')
self.escapeItem = QtGui.QAction(translate( self.escapeItem = shortcut_action(parent,
'OpenLP.SlideController', 'Escape Item'), parent) translate('OpenLP.SlideController', 'Escape Item'),
self.escapeItem.setShortcuts([QtCore.Qt.Key_Escape, 0]) [QtCore.Qt.Key_Escape, 0], self.liveEscape)
self.escapeItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(self.escapeItem,
QtCore.SIGNAL(u'triggered()'), self.liveEscape)
actionList.add_action(self.escapeItem, u'Live') actionList.add_action(self.escapeItem, u'Live')
def liveEscape(self): def liveEscape(self):
@ -435,12 +415,7 @@ class SlideController(QtGui.QWidget):
self.display.alertTab = self.alertTab self.display.alertTab = self.alertTab
self.display.setup() self.display.setup()
if self.isLive: if self.isLive:
self.display.addActions( self.__addActionsToWidget(self.display)
[self.previousItem,
self.nextItem,
self.previousService,
self.nextService,
self.escapeItem])
# The SlidePreview's ratio. # The SlidePreview's ratio.
self.ratio = float(self.screens.current[u'size'].width()) / \ self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height()) float(self.screens.current[u'size'].height())
@ -448,6 +423,12 @@ class SlideController(QtGui.QWidget):
if self.serviceItem: if self.serviceItem:
self.refreshServiceItem() self.refreshServiceItem()
def __addActionsToWidget(self, widget):
widget.addActions([
self.previousItem, self.nextItem,
self.previousService, self.nextService,
self.escapeItem])
def previewSizeChanged(self): def previewSizeChanged(self):
""" """
Takes care of the SlidePreview's size. Is called when one of the the Takes care of the SlidePreview's size. Is called when one of the the
@ -482,18 +463,11 @@ class SlideController(QtGui.QWidget):
def onSongBarHandler(self): def onSongBarHandler(self):
request = unicode(self.sender().text()) request = unicode(self.sender().text())
slideno = self.slideList[request] slideno = self.slideList[request]
if slideno > self.previewListWidget.rowCount(): self.__updatePreviewSelection(slideno)
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.onSlideSelected() self.onSlideSelected()
def receiveSpinDelay(self, value): def receiveSpinDelay(self, value):
self.DelaySpinBox.setValue(int(value)) self.delaySpinBox.setValue(int(value))
def enableToolBar(self, item): def enableToolBar(self, item):
""" """
@ -582,10 +556,7 @@ class SlideController(QtGui.QWidget):
slideno = 0 slideno = 0
# If service item is the same as the current on only change slide # If service item is the same as the current on only change slide
if item.__eq__(self.serviceItem): if item.__eq__(self.serviceItem):
if slideno + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(slideno)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(slideno + 1, 0))
self.previewListWidget.selectRow(slideno)
self.onSlideSelected() self.onSlideSelected()
return return
self._processItem(item, slideno) self._processItem(item, slideno)
@ -665,14 +636,7 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.resizeRowsToContents() self.previewListWidget.resizeRowsToContents()
self.previewListWidget.setColumnWidth(0, self.previewListWidget.setColumnWidth(0,
self.previewListWidget.viewport().size().width()) self.previewListWidget.viewport().size().width())
if slideno > self.previewListWidget.rowCount(): self.__updatePreviewSelection(slideno)
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.enableToolBar(serviceItem) self.enableToolBar(serviceItem)
# Pass to display for viewing # Pass to display for viewing
self.display.buildHtml(self.serviceItem) self.display.buildHtml(self.serviceItem)
@ -683,6 +647,16 @@ class SlideController(QtGui.QWidget):
Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix, Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix,
[serviceItem]) [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:
self.__checkUpdateSelectedSlide(slideno)
def onTextRequest(self): def onTextRequest(self):
""" """
Return the text for the current item in controller Return the text for the current item in controller
@ -730,10 +704,7 @@ class SlideController(QtGui.QWidget):
[self.serviceItem, self.isLive, index]) [self.serviceItem, self.isLive, index])
self.updatePreview() self.updatePreview()
else: else:
if index + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(index)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(index + 1, 0))
self.previewListWidget.selectRow(index)
self.onSlideSelected() self.onSlideSelected()
def mainDisplaySetBackground(self): def mainDisplaySetBackground(self):
@ -892,10 +863,7 @@ class SlideController(QtGui.QWidget):
""" """
The slide has been changed. Update the slidecontroller accordingly The slide has been changed. Update the slidecontroller accordingly
""" """
if row + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(row)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
self.updatePreview() self.updatePreview()
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix, Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row) row)
@ -946,10 +914,7 @@ class SlideController(QtGui.QWidget):
else: else:
Receiver.send_message('servicemanager_next_item') Receiver.send_message('servicemanager_next_item')
return return
if row + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(row)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
self.onSlideSelected() self.onSlideSelected()
def onSlideSelectedPreviousNoloop(self): def onSlideSelectedPreviousNoloop(self):
@ -972,12 +937,15 @@ class SlideController(QtGui.QWidget):
row = self.previewListWidget.rowCount() - 1 row = self.previewListWidget.rowCount() - 1
else: else:
row = 0 row = 0
if row + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(row)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
self.onSlideSelected() self.onSlideSelected()
def __checkUpdateSelectedSlide(self, row):
if row + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
def onSlideSelectedLast(self): def onSlideSelectedLast(self):
""" """
Go to the last slide. Go to the last slide.
@ -999,7 +967,7 @@ class SlideController(QtGui.QWidget):
""" """
if self.previewListWidget.rowCount() > 1: if self.previewListWidget.rowCount() > 1:
self.timer_id = self.startTimer( 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'Stop Loop'].setVisible(True)
self.toolbar.actions[u'Start Loop'].setVisible(False) self.toolbar.actions[u'Start Loop'].setVisible(False)

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \ from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \
Receiver 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 openlp.core.utils import get_images_filter
from themewizard import Ui_ThemeWizard from themewizard import Ui_ThemeWizard
@ -567,13 +567,13 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
# Save the theme name # Save the theme name
self.theme.theme_name = unicode(self.field(u'name').toString()) self.theme.theme_name = unicode(self.field(u'name').toString())
if not self.theme.theme_name: if not self.theme.theme_name:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeForm', 'Theme Name Missing'), translate('OpenLP.ThemeForm', 'Theme Name Missing'),
translate('OpenLP.ThemeForm', translate('OpenLP.ThemeForm',
'There is no name for this theme. Please enter one.')) 'There is no name for this theme. Please enter one.'))
return return
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None': 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', 'Theme Name Invalid'),
translate('OpenLP.ThemeForm', translate('OpenLP.ThemeForm',
'Invalid theme name. Please enter one.')) 'Invalid theme name. Please enter one.'))

View File

@ -32,11 +32,12 @@ import logging
from xml.etree.ElementTree import ElementTree, XML from xml.etree.ElementTree import ElementTree, XML
from PyQt4 import QtCore, QtGui 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, \ from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \
build_icon, Receiver, SettingsManager, translate, check_item_selected, \ build_icon, Receiver, SettingsManager, translate, check_item_selected, \
BackgroundType, BackgroundGradientType, check_directory_exists 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, \ from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
get_filesystem_encoding get_filesystem_encoding
@ -240,7 +241,7 @@ class ThemeManager(QtGui.QWidget):
QtCore.QVariant(self.global_theme)) QtCore.QVariant(self.global_theme))
Receiver.send_message(u'theme_update_global', Receiver.send_message(u'theme_update_global',
self.global_theme) self.global_theme)
self.pushThemes() self._pushThemes()
def onAddTheme(self): def onAddTheme(self):
""" """
@ -259,7 +260,7 @@ class ThemeManager(QtGui.QWidget):
'You must select a theme to rename.')), 'You must select a theme to rename.')),
unicode(translate('OpenLP.ThemeManager', 'Rename Confirmation')), unicode(translate('OpenLP.ThemeManager', 'Rename Confirmation')),
unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')), unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')),
False): False, False):
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(oldThemeName) self.fileRenameForm.fileNameEdit.setText(oldThemeName)
@ -267,11 +268,12 @@ class ThemeManager(QtGui.QWidget):
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
if self.checkIfThemeExists(newThemeName): if self.checkIfThemeExists(newThemeName):
oldThemeData = self.getThemeData(oldThemeName) oldThemeData = self.getThemeData(oldThemeName)
self.deleteTheme(oldThemeName)
self.cloneThemeData(oldThemeData, newThemeName) self.cloneThemeData(oldThemeData, newThemeName)
self.deleteTheme(oldThemeName)
for plugin in self.mainwindow.pluginManager.plugins: for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(oldThemeName): if plugin.usesTheme(oldThemeName):
plugin.renameTheme(oldThemeName, newThemeName) plugin.renameTheme(oldThemeName, newThemeName)
self.loadThemes()
def onCopyTheme(self): def onCopyTheme(self):
""" """
@ -299,6 +301,7 @@ class ThemeManager(QtGui.QWidget):
os.path.split(unicode(themeData.background_filename))[1]) os.path.split(unicode(themeData.background_filename))[1])
saveFrom = themeData.background_filename saveFrom = themeData.background_filename
themeData.theme_name = newThemeName themeData.theme_name = newThemeName
themeData.extend_image_filename(self.path)
self.saveTheme(themeData, saveFrom, saveTo) self.saveTheme(themeData, saveFrom, saveTo)
def onEditTheme(self): def onEditTheme(self):
@ -331,6 +334,9 @@ class ThemeManager(QtGui.QWidget):
row = self.themeListWidget.row(item) row = self.themeListWidget.row(item)
self.themeListWidget.takeItem(row) self.themeListWidget.takeItem(row)
self.deleteTheme(theme) self.deleteTheme(theme)
# As we do not reload the themes, push out the change. Reload the
# list as the internal lists and events need to be triggered.
self._pushThemes()
def deleteTheme(self, theme): def deleteTheme(self, theme):
""" """
@ -348,10 +354,6 @@ class ThemeManager(QtGui.QWidget):
shutil.rmtree(os.path.join(self.path, theme).encode(encoding)) shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
except OSError: except OSError:
log.exception(u'Error deleting theme %s', theme) log.exception(u'Error deleting theme %s', theme)
# As we do not reload the themes push out the change
# Reaload the list as the internal lists and events need
# to be triggered
self.pushThemes()
def onExportTheme(self): def onExportTheme(self):
""" """
@ -359,7 +361,7 @@ class ThemeManager(QtGui.QWidget):
""" """
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
if item is None: if item is None:
criticalErrorMessageBox(message=translate('OpenLP.ThemeManager', critical_error_message_box(message=translate('OpenLP.ThemeManager',
'You have not selected a theme.')) 'You have not selected a theme.'))
return return
theme = unicode(item.data(QtCore.Qt.UserRole).toString()) theme = unicode(item.data(QtCore.Qt.UserRole).toString())
@ -386,7 +388,7 @@ class ThemeManager(QtGui.QWidget):
'Your theme has been successfully exported.')) 'Your theme has been successfully exported.'))
except (IOError, OSError): except (IOError, OSError):
log.exception(u'Export Theme Failed') log.exception(u'Export Theme Failed')
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Theme Export Failed'), translate('OpenLP.ThemeManager', 'Theme Export Failed'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
'Your theme could not be exported due to an error.')) 'Your theme could not be exported due to an error.'))
@ -448,9 +450,9 @@ class ThemeManager(QtGui.QWidget):
QtCore.QVariant(textName)) QtCore.QVariant(textName))
self.themeListWidget.addItem(item_name) self.themeListWidget.addItem(item_name)
self.themelist.append(textName) self.themelist.append(textName)
self.pushThemes() self._pushThemes()
def pushThemes(self): def _pushThemes(self):
""" """
Notify listeners that the theme list has been updated Notify listeners that the theme list has been updated
""" """
@ -496,7 +498,7 @@ class ThemeManager(QtGui.QWidget):
for file in zip.namelist(): for file in zip.namelist():
ucsfile = file_is_unicode(file) ucsfile = file_is_unicode(file)
if not ucsfile: if not ucsfile:
criticalErrorMessageBox( critical_error_message_box(
message=translate('OpenLP.ThemeManager', message=translate('OpenLP.ThemeManager',
'File is not a valid theme.\n' 'File is not a valid theme.\n'
'The content encoding is not UTF-8.')) 'The content encoding is not UTF-8.'))
@ -531,14 +533,14 @@ class ThemeManager(QtGui.QWidget):
theme = self._createThemeFromXml(filexml, self.path) theme = self._createThemeFromXml(filexml, self.path)
self.generateAndSaveImage(dir, themename, theme) self.generateAndSaveImage(dir, themename, theme)
else: else:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
'File is not a valid theme.')) 'File is not a valid theme.'))
log.exception(u'Theme file does not contain XML data %s' % log.exception(u'Theme file does not contain XML data %s' %
filename) filename)
except (IOError, NameError): except (IOError, NameError):
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
'File is not a valid theme.')) 'File is not a valid theme.'))
@ -558,7 +560,7 @@ class ThemeManager(QtGui.QWidget):
""" """
theme_dir = os.path.join(self.path, themeName) theme_dir = os.path.join(self.path, themeName)
if os.path.exists(theme_dir): if os.path.exists(theme_dir):
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
'A theme with this name already exists.')) 'A theme with this name already exists.'))
@ -570,6 +572,14 @@ class ThemeManager(QtGui.QWidget):
Called by thememaintenance Dialog to save the theme Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list and to trigger the reload of the theme list
""" """
self._writeTheme(theme, imageFrom, imageTo)
self.loadThemes()
def _writeTheme(self, theme, imageFrom, imageTo):
"""
Writes the theme to the disk and handles the background image if
necessary
"""
name = theme.theme_name name = theme.theme_name
theme_pretty_xml = theme.extract_formatted_xml() theme_pretty_xml = theme.extract_formatted_xml()
log.debug(u'saveTheme %s %s', name, theme_pretty_xml) log.debug(u'saveTheme %s %s', name, theme_pretty_xml)
@ -597,12 +607,9 @@ class ThemeManager(QtGui.QWidget):
except IOError: except IOError:
log.exception(u'Failed to save theme image') log.exception(u'Failed to save theme image')
self.generateAndSaveImage(self.path, name, theme) self.generateAndSaveImage(self.path, name, theme)
self.loadThemes()
self.pushThemes()
def generateAndSaveImage(self, dir, name, theme): def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s', dir, name) log.debug(u'generateAndSaveImage %s %s', dir, name)
theme_xml = theme.extract_xml()
frame = self.generateImage(theme) frame = self.generateImage(theme)
samplepathname = os.path.join(self.path, name + u'.png') samplepathname = os.path.join(self.path, name + u'.png')
if os.path.exists(samplepathname): if os.path.exists(samplepathname):
@ -668,7 +675,7 @@ class ThemeManager(QtGui.QWidget):
return theme return theme
def _validate_theme_action(self, select_text, confirm_title, confirm_text, def _validate_theme_action(self, select_text, confirm_title, confirm_text,
testPlugin=True): testPlugin=True, confirm=True):
""" """
Check to see if theme has been selected and the destructive action Check to see if theme has been selected and the destructive action
is allowed. is allowed.
@ -680,15 +687,16 @@ class ThemeManager(QtGui.QWidget):
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
theme = unicode(item.text()) theme = unicode(item.text())
# confirm deletion # confirm deletion
answer = QtGui.QMessageBox.question(self, confirm_title, if confirm:
confirm_text % theme, QtGui.QMessageBox.StandardButtons( answer = QtGui.QMessageBox.question(self, confirm_title,
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), confirm_text % theme, QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.No) QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
if answer == QtGui.QMessageBox.No: QtGui.QMessageBox.No)
return False if answer == QtGui.QMessageBox.No:
return False
# should be the same unless default # should be the same unless default
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()): if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
criticalErrorMessageBox( critical_error_message_box(
message=translate('OpenLP.ThemeManager', message=translate('OpenLP.ThemeManager',
'You are unable to delete the default theme.')) 'You are unable to delete the default theme.'))
return False return False
@ -696,7 +704,8 @@ class ThemeManager(QtGui.QWidget):
if testPlugin: if testPlugin:
for plugin in self.mainwindow.pluginManager.plugins: for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(theme): if plugin.usesTheme(theme):
criticalErrorMessageBox(translate('OpenLP.ThemeManager', critical_error_message_box(
translate('OpenLP.ThemeManager',
'Validation Error'), 'Validation Error'),
unicode(translate('OpenLP.ThemeManager', unicode(translate('OpenLP.ThemeManager',
'Theme %s is used in the %s plugin.')) % \ 'Theme %s is used in the %s plugin.')) % \

View File

@ -165,13 +165,7 @@ class ThemesTab(SettingsTab):
self.global_theme = unicode(self.DefaultComboBox.currentText()) self.global_theme = unicode(self.DefaultComboBox.currentText())
self.parent.renderManager.set_global_theme( self.parent.renderManager.set_global_theme(
self.global_theme, self.theme_level) self.global_theme, self.theme_level)
image = self.parent.ThemeManagerContents.getPreviewImage( self.__previewGlobalTheme()
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)
def updateThemeList(self, theme_list): def updateThemeList(self, theme_list):
""" """
@ -198,10 +192,16 @@ class ThemesTab(SettingsTab):
self.parent.renderManager.set_global_theme( self.parent.renderManager.set_global_theme(
self.global_theme, self.theme_level) self.global_theme, self.theme_level)
if self.global_theme is not u'': if self.global_theme is not u'':
image = self.parent.ThemeManagerContents.getPreviewImage( self.__previewGlobalTheme()
self.global_theme)
preview = QtGui.QPixmap(unicode(image)) def __previewGlobalTheme(self):
if not preview.isNull(): """
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio, Utility method to update the global theme preview image.
QtCore.Qt.SmoothTransformation) """
self.DefaultListView.setPixmap(preview) 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)

View File

@ -27,32 +27,19 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, build_icon from openlp.core.lib import translate, build_icon
from openlp.core.lib.ui import add_welcome_page
class Ui_ThemeWizard(object): class Ui_ThemeWizard(object):
def setupUi(self, ThemeWizard): def setupUi(self, themeWizard):
ThemeWizard.setObjectName(u'OpenLP.ThemeWizard') themeWizard.setObjectName(u'OpenLP.ThemeWizard')
ThemeWizard.setModal(True) themeWizard.setModal(True)
ThemeWizard.setWizardStyle(QtGui.QWizard.ModernStyle) themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
ThemeWizard.setOptions( themeWizard.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage) QtGui.QWizard.NoBackButtonOnStartPage)
self.spacer = QtGui.QSpacerItem(10, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
# Welcome Page # Welcome Page
self.welcomePage = QtGui.QWizardPage() add_welcome_page(themeWizard, u':/wizards/wizard_createtheme.bmp')
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)
# Background Page # Background Page
self.backgroundPage = QtGui.QWizardPage() self.backgroundPage = QtGui.QWizardPage()
self.backgroundPage.setObjectName(u'BackgroundPage') self.backgroundPage.setObjectName(u'BackgroundPage')
@ -67,10 +54,8 @@ class Ui_ThemeWizard(object):
self.backgroundComboBox.setObjectName(u'BackgroundComboBox') self.backgroundComboBox.setObjectName(u'BackgroundComboBox')
self.backgroundTypeLayout.addRow(self.backgroundLabel, self.backgroundTypeLayout.addRow(self.backgroundLabel,
self.backgroundComboBox) self.backgroundComboBox)
self.backgroundTypeSpacer = QtGui.QSpacerItem(10, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
self.backgroundTypeLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.backgroundTypeLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.backgroundTypeSpacer) self.spacer)
self.backgroundLayout.addLayout(self.backgroundTypeLayout) self.backgroundLayout.addLayout(self.backgroundTypeLayout)
self.backgroundStack = QtGui.QStackedLayout() self.backgroundStack = QtGui.QStackedLayout()
self.backgroundStack.setObjectName(u'BackgroundStack') self.backgroundStack.setObjectName(u'BackgroundStack')
@ -84,10 +69,7 @@ class Ui_ThemeWizard(object):
self.colorButton = QtGui.QPushButton(self.colorWidget) self.colorButton = QtGui.QPushButton(self.colorWidget)
self.colorButton.setObjectName(u'ColorButton') self.colorButton.setObjectName(u'ColorButton')
self.colorLayout.addRow(self.colorLabel, self.colorButton) self.colorLayout.addRow(self.colorLabel, self.colorButton)
self.colorSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.colorLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.colorLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.colorSpacer)
self.backgroundStack.addWidget(self.colorWidget) self.backgroundStack.addWidget(self.colorWidget)
self.gradientWidget = QtGui.QWidget(self.backgroundPage) self.gradientWidget = QtGui.QWidget(self.backgroundPage)
self.gradientWidget.setObjectName(u'GradientWidget') self.gradientWidget.setObjectName(u'GradientWidget')
@ -113,10 +95,7 @@ class Ui_ThemeWizard(object):
self.gradientComboBox.addItems([u'', u'', u'', u'', u'']) self.gradientComboBox.addItems([u'', u'', u'', u'', u''])
self.gradientLayout.addRow(self.gradientTypeLabel, self.gradientLayout.addRow(self.gradientTypeLabel,
self.gradientComboBox) self.gradientComboBox)
self.gradientSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.gradientLayout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.gradientLayout.setItem(3, QtGui.QFormLayout.LabelRole,
self.gradientSpacer)
self.backgroundStack.addWidget(self.gradientWidget) self.backgroundStack.addWidget(self.gradientWidget)
self.imageWidget = QtGui.QWidget(self.backgroundPage) self.imageWidget = QtGui.QWidget(self.backgroundPage)
self.imageWidget.setObjectName(u'ImageWidget') self.imageWidget.setObjectName(u'ImageWidget')
@ -136,13 +115,10 @@ class Ui_ThemeWizard(object):
build_icon(u':/general/general_open.png')) build_icon(u':/general/general_open.png'))
self.imageFileLayout.addWidget(self.imageBrowseButton) self.imageFileLayout.addWidget(self.imageBrowseButton)
self.imageLayout.addRow(self.imageLabel, self.imageFileLayout) self.imageLayout.addRow(self.imageLabel, self.imageFileLayout)
self.imageSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.imageSpacer)
self.backgroundStack.addWidget(self.imageWidget) self.backgroundStack.addWidget(self.imageWidget)
self.backgroundLayout.addLayout(self.backgroundStack) self.backgroundLayout.addLayout(self.backgroundStack)
ThemeWizard.addPage(self.backgroundPage) themeWizard.addPage(self.backgroundPage)
# Main Area Page # Main Area Page
self.mainAreaPage = QtGui.QWizardPage() self.mainAreaPage = QtGui.QWizardPage()
self.mainAreaPage.setObjectName(u'MainAreaPage') self.mainAreaPage.setObjectName(u'MainAreaPage')
@ -225,7 +201,7 @@ class Ui_ThemeWizard(object):
self.shadowSizeSpinBox.setObjectName(u'ShadowSizeSpinBox') self.shadowSizeSpinBox.setObjectName(u'ShadowSizeSpinBox')
self.shadowLayout.addWidget(self.shadowSizeSpinBox) self.shadowLayout.addWidget(self.shadowSizeSpinBox)
self.mainAreaLayout.addRow(self.shadowCheckBox, self.shadowLayout) self.mainAreaLayout.addRow(self.shadowCheckBox, self.shadowLayout)
ThemeWizard.addPage(self.mainAreaPage) themeWizard.addPage(self.mainAreaPage)
# Footer Area Page # Footer Area Page
self.footerAreaPage = QtGui.QWizardPage() self.footerAreaPage = QtGui.QWizardPage()
self.footerAreaPage.setObjectName(u'FooterAreaPage') self.footerAreaPage.setObjectName(u'FooterAreaPage')
@ -251,7 +227,9 @@ class Ui_ThemeWizard(object):
self.footerSizeSpinBox.setObjectName(u'FooterSizeSpinBox') self.footerSizeSpinBox.setObjectName(u'FooterSizeSpinBox')
self.footerAreaLayout.addRow(self.footerSizeLabel, self.footerAreaLayout.addRow(self.footerSizeLabel,
self.footerSizeSpinBox) self.footerSizeSpinBox)
ThemeWizard.addPage(self.footerAreaPage) self.footerAreaLayout.setItem(3, QtGui.QFormLayout.LabelRole,
self.spacer)
themeWizard.addPage(self.footerAreaPage)
# Alignment Page # Alignment Page
self.alignmentPage = QtGui.QWizardPage() self.alignmentPage = QtGui.QWizardPage()
self.alignmentPage.setObjectName(u'AlignmentPage') self.alignmentPage.setObjectName(u'AlignmentPage')
@ -276,7 +254,9 @@ class Ui_ThemeWizard(object):
self.transitionsCheckBox.setObjectName(u'TransitionsCheckBox') self.transitionsCheckBox.setObjectName(u'TransitionsCheckBox')
self.alignmentLayout.addRow(self.transitionsLabel, self.alignmentLayout.addRow(self.transitionsLabel,
self.transitionsCheckBox) self.transitionsCheckBox)
ThemeWizard.addPage(self.alignmentPage) self.alignmentLayout.setItem(3, QtGui.QFormLayout.LabelRole,
self.spacer)
themeWizard.addPage(self.alignmentPage)
# Area Position Page # Area Position Page
self.areaPositionPage = QtGui.QWizardPage() self.areaPositionPage = QtGui.QWizardPage()
self.areaPositionPage.setObjectName(u'AreaPositionPage') self.areaPositionPage.setObjectName(u'AreaPositionPage')
@ -352,7 +332,7 @@ class Ui_ThemeWizard(object):
self.footerPositionLayout.addRow(self.footerHeightLabel, self.footerPositionLayout.addRow(self.footerHeightLabel,
self.footerHeightSpinBox) self.footerHeightSpinBox)
self.areaPositionLayout.addWidget(self.footerPositionGroupBox) self.areaPositionLayout.addWidget(self.footerPositionGroupBox)
ThemeWizard.addPage(self.areaPositionPage) themeWizard.addPage(self.areaPositionPage)
# Preview Page # Preview Page
self.previewPage = QtGui.QWizardPage() self.previewPage = QtGui.QWizardPage()
self.previewPage.setObjectName(u'PreviewPage') self.previewPage.setObjectName(u'PreviewPage')
@ -381,9 +361,8 @@ class Ui_ThemeWizard(object):
self.previewBoxLabel.setObjectName(u'PreviewBoxLabel') self.previewBoxLabel.setObjectName(u'PreviewBoxLabel')
self.previewAreaLayout.addWidget(self.previewBoxLabel) self.previewAreaLayout.addWidget(self.previewBoxLabel)
self.previewLayout.addWidget(self.previewArea) self.previewLayout.addWidget(self.previewArea)
ThemeWizard.addPage(self.previewPage) themeWizard.addPage(self.previewPage)
self.retranslateUi(themeWizard)
self.retranslateUi(ThemeWizard)
QtCore.QObject.connect(self.backgroundComboBox, QtCore.QObject.connect(self.backgroundComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'), self.backgroundStack, QtCore.SIGNAL(u'currentIndexChanged(int)'), self.backgroundStack,
QtCore.SLOT(u'setCurrentIndex(int)')) QtCore.SLOT(u'setCurrentIndex(int)'))
@ -423,10 +402,10 @@ class Ui_ThemeWizard(object):
QtCore.QObject.connect(self.footerPositionCheckBox, QtCore.QObject.connect(self.footerPositionCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.footerHeightSpinBox, QtCore.SIGNAL(u'toggled(bool)'), self.footerHeightSpinBox,
QtCore.SLOT(u'setDisabled(bool)')) QtCore.SLOT(u'setDisabled(bool)'))
QtCore.QMetaObject.connectSlotsByName(ThemeWizard) QtCore.QMetaObject.connectSlotsByName(themeWizard)
def retranslateUi(self, ThemeWizard): def retranslateUi(self, themeWizard):
ThemeWizard.setWindowTitle( themeWizard.setWindowTitle(
translate('OpenLP.ThemeWizard', 'Theme Wizard')) translate('OpenLP.ThemeWizard', 'Theme Wizard'))
self.titleLabel.setText( self.titleLabel.setText(
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \ u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
@ -568,16 +547,6 @@ class Ui_ThemeWizard(object):
translate('OpenLP.ThemeWizard', 'Theme name:')) translate('OpenLP.ThemeWizard', 'Theme name:'))
# Align all QFormLayouts towards each other. # Align all QFormLayouts towards each other.
labelWidth = max(self.backgroundLabel.minimumSizeHint().width(), labelWidth = max(self.backgroundLabel.minimumSizeHint().width(),
self.colorLabel.minimumSizeHint().width(), self.horizontalLabel.minimumSizeHint().width())
self.gradientStartLabel.minimumSizeHint().width(), self.spacer.changeSize(labelWidth, 0,
self.gradientEndLabel.minimumSizeHint().width(),
self.gradientTypeLabel.minimumSizeHint().width(),
self.imageLabel.minimumSizeHint().width())
self.backgroundTypeSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.colorSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.gradientSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.imageSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)

View File

@ -31,6 +31,7 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, Receiver from openlp.core.lib import build_icon, Receiver
from openlp.core.lib.ui import add_welcome_page
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -63,36 +64,12 @@ class OpenLPWizard(QtGui.QWizard):
self.setOptions(QtGui.QWizard.IndependentPages | self.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.NoBackButtonOnLastPage) QtGui.QWizard.NoBackButtonOnLastPage)
self.addWelcomePage(image) add_welcome_page(self, image)
self.addCustomPages() self.addCustomPages()
self.addProgressPage() self.addProgressPage()
self.retranslateUi() self.retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self) 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): def addProgressPage(self):
""" """
Add the progress page for the wizard. This page informs the user how Add the progress page for the wizard. This page informs the user how

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate from openlp.core.lib import build_icon, translate
from openlp.core.lib.ui import create_delete_push_button
class Ui_AlertDialog(object): class Ui_AlertDialog(object):
def setupUi(self, alertDialog): def setupUi(self, alertDialog):
@ -65,9 +66,8 @@ class Ui_AlertDialog(object):
self.saveButton.setIcon(build_icon(u':/general/general_save.png')) self.saveButton.setIcon(build_icon(u':/general/general_save.png'))
self.saveButton.setObjectName(u'saveButton') self.saveButton.setObjectName(u'saveButton')
self.manageButtonLayout.addWidget(self.saveButton) self.manageButtonLayout.addWidget(self.saveButton)
self.deleteButton = QtGui.QPushButton(alertDialog) self.deleteButton = create_delete_push_button(alertDialog)
self.deleteButton.setIcon(build_icon(u':/general/general_delete.png')) self.deleteButton.setEnabled(False)
self.deleteButton.setObjectName(u'deleteButton')
self.manageButtonLayout.addWidget(self.deleteButton) self.manageButtonLayout.addWidget(self.deleteButton)
self.manageButtonLayout.addStretch() self.manageButtonLayout.addStretch()
self.alertDialogLayout.addLayout(self.manageButtonLayout, 1, 1) self.alertDialogLayout.addLayout(self.manageButtonLayout, 1, 1)
@ -75,11 +75,13 @@ class Ui_AlertDialog(object):
self.buttonBox.addButton(QtGui.QDialogButtonBox.Close) self.buttonBox.addButton(QtGui.QDialogButtonBox.Close)
displayIcon = build_icon(u':/general/general_live.png') displayIcon = build_icon(u':/general/general_live.png')
self.displayButton = QtGui.QPushButton(alertDialog) self.displayButton = QtGui.QPushButton(alertDialog)
self.displayButton.setEnabled(False)
self.displayButton.setIcon(displayIcon) self.displayButton.setIcon(displayIcon)
self.displayButton.setObjectName(u'displayButton') self.displayButton.setObjectName(u'displayButton')
self.buttonBox.addButton(self.displayButton, self.buttonBox.addButton(self.displayButton,
QtGui.QDialogButtonBox.ActionRole) QtGui.QDialogButtonBox.ActionRole)
self.displayCloseButton = QtGui.QPushButton(alertDialog) self.displayCloseButton = QtGui.QPushButton(alertDialog)
self.displayCloseButton.setEnabled(False)
self.displayCloseButton.setIcon(displayIcon) self.displayCloseButton.setIcon(displayIcon)
self.displayCloseButton.setObjectName(u'displayCloseButton') self.displayCloseButton.setObjectName(u'displayCloseButton')
self.buttonBox.addButton(self.displayCloseButton, self.buttonBox.addButton(self.displayCloseButton,
@ -101,8 +103,6 @@ class Ui_AlertDialog(object):
translate('AlertsPlugin.AlertForm', '&New')) translate('AlertsPlugin.AlertForm', '&New'))
self.saveButton.setText( self.saveButton.setText(
translate('AlertsPlugin.AlertForm', '&Save')) translate('AlertsPlugin.AlertForm', '&Save'))
self.deleteButton.setText(
translate('AlertsPlugin.AlertForm', '&Delete'))
self.displayButton.setText( self.displayButton.setText(
translate('AlertsPlugin.AlertForm', 'Displ&ay')) translate('AlertsPlugin.AlertForm', 'Displ&ay'))
self.displayCloseButton.setText( self.displayCloseButton.setText(

View File

@ -44,22 +44,22 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
self.item_id = None self.item_id = None
QtGui.QDialog.__init__(self, plugin.formparent) QtGui.QDialog.__init__(self, plugin.formparent)
self.setupUi(self) self.setupUi(self)
QtCore.QObject.connect(self.displayButton, QtCore.SIGNAL(u'clicked()'), QtCore.QObject.connect(self.displayButton,
self.onDisplayClicked) QtCore.SIGNAL(u'clicked()'), self.onDisplayClicked)
QtCore.QObject.connect(self.displayCloseButton, QtCore.QObject.connect(self.displayCloseButton,
QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked) QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked)
QtCore.QObject.connect(self.alertTextEdit, QtCore.QObject.connect(self.alertTextEdit,
QtCore.SIGNAL(u'textChanged(const QString&)'), self.onTextChanged) QtCore.SIGNAL(u'textChanged(const QString&)'), self.onTextChanged)
QtCore.QObject.connect(self.newButton, QtCore.SIGNAL(u'clicked()'), QtCore.QObject.connect(self.newButton,
self.onNewClick) QtCore.SIGNAL(u'clicked()'), self.onNewClick)
QtCore.QObject.connect(self.deleteButton, QtCore.SIGNAL(u'clicked()'), QtCore.QObject.connect(self.saveButton,
self.onDeleteClick) QtCore.SIGNAL(u'clicked()'), self.onSaveClick)
QtCore.QObject.connect(self.saveButton, QtCore.SIGNAL(u'clicked()'),
self.onSaveClick)
QtCore.QObject.connect(self.alertListWidget, QtCore.QObject.connect(self.alertListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onDoubleClick) QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onDoubleClick)
QtCore.QObject.connect(self.alertListWidget, QtCore.QObject.connect(self.alertListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSingleClick) QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSingleClick)
QtCore.QObject.connect(self.alertListWidget,
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
def loadList(self): def loadList(self):
""" """
@ -72,18 +72,15 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
item_name = QtGui.QListWidgetItem(alert.text) item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
self.alertListWidget.addItem(item_name) self.alertListWidget.addItem(item_name)
self.saveButton.setEnabled(False)
self.deleteButton.setEnabled(False)
def onDisplayClicked(self): def onDisplayClicked(self):
if self.triggerAlert(unicode(self.alertTextEdit.text())): self.triggerAlert(unicode(self.alertTextEdit.text()))
self.loadList()
def onDisplayCloseClicked(self): def onDisplayCloseClicked(self):
if self.triggerAlert(unicode(self.alertTextEdit.text())): if self.triggerAlert(unicode(self.alertTextEdit.text())):
self.close() self.close()
def onDeleteClick(self): def onDeleteButtonClicked(self):
""" """
Deletes the selected item. Deletes the selected item.
""" """
@ -95,8 +92,6 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
self.alertListWidget.takeItem(row) self.alertListWidget.takeItem(row)
self.item_id = None self.item_id = None
self.alertTextEdit.setText(u'') self.alertTextEdit.setText(u'')
self.saveButton.setEnabled(False)
self.deleteButton.setEnabled(False)
def onNewClick(self): def onNewClick(self):
if len(self.alertTextEdit.text()) == 0: if len(self.alertTextEdit.text()) == 0:
@ -135,30 +130,26 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
""" """
List item has been double clicked to display it List item has been double clicked to display it
""" """
items = self.alertListWidget.selectedIndexes() item = self.alertListWidget.selectedIndexes()[0]
for item in items: bitem = self.alertListWidget.item(item.row())
bitem = self.alertListWidget.item(item.row()) self.triggerAlert(unicode(bitem.text()))
self.triggerAlert(unicode(bitem.text())) self.alertTextEdit.setText(unicode(bitem.text()))
self.alertTextEdit.setText(unicode(bitem.text())) self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
self.saveButton.setEnabled(False) self.saveButton.setEnabled(False)
self.deleteButton.setEnabled(True)
def onSingleClick(self): def onSingleClick(self):
""" """
List item has been single clicked to add it to List item has been single clicked to add it to
the edit field so it can be changed. the edit field so it can be changed.
""" """
items = self.alertListWidget.selectedIndexes() item = self.alertListWidget.selectedIndexes()[0]
for item in items: bitem = self.alertListWidget.item(item.row())
bitem = self.alertListWidget.item(item.row()) self.alertTextEdit.setText(unicode(bitem.text()))
self.alertTextEdit.setText(unicode(bitem.text())) self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
# If the alert does not contain '<>' we clear the ParameterEdit field. # If the alert does not contain '<>' we clear the ParameterEdit field.
if unicode(self.alertTextEdit.text()).find(u'<>') == -1: if unicode(self.alertTextEdit.text()).find(u'<>') == -1:
self.parameterEdit.setText(u'') self.parameterEdit.setText(u'')
self.saveButton.setEnabled(False) self.saveButton.setEnabled(False)
self.deleteButton.setEnabled(True)
def triggerAlert(self, text): def triggerAlert(self, text):
""" """
@ -167,30 +158,49 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
``text`` ``text``
The alert text (unicode). The alert text (unicode).
""" """
if text: if not text:
# We found '<>' in the alert text, but the ParameterEdit field is return False
# empty. # We found '<>' in the alert text, but the ParameterEdit field is empty.
if text.find(u'<>') != -1 and not self.parameterEdit.text() and \ if text.find(u'<>') != -1 and not self.parameterEdit.text() and \
QtGui.QMessageBox.question(self, QtGui.QMessageBox.question(self,
translate('AlertPlugin.AlertForm', 'No Parameter found'), translate('AlertPlugin.AlertForm', 'No Parameter found'),
translate('AlertPlugin.AlertForm', 'You have not entered a ' translate('AlertPlugin.AlertForm', 'You have not entered a '
'parameter to be replaced.\nDo you want to continue anyway?'), 'parameter to be replaced.\nDo you want to continue anyway?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No:
self.parameterEdit.setFocus() self.parameterEdit.setFocus()
return False return False
# The ParameterEdit field is not empty, but we have not found '<>' # The ParameterEdit field is not empty, but we have not found '<>'
# in the alert text. # in the alert text.
elif text.find(u'<>') == -1 and self.parameterEdit.text() and \ elif text.find(u'<>') == -1 and self.parameterEdit.text() and \
QtGui.QMessageBox.question(self, QtGui.QMessageBox.question(self,
translate('AlertPlugin.AlertForm', 'No Placeholder found'), translate('AlertPlugin.AlertForm', 'No Placeholder found'),
translate('AlertPlugin.AlertForm', 'The alert text does not' translate('AlertPlugin.AlertForm', 'The alert text does not'
' contain \'<>\'.\nDo want to continue anyway?'), ' contain \'<>\'.\nDo want to continue anyway?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No:
self.parameterEdit.setFocus() self.parameterEdit.setFocus()
return False return False
text = text.replace(u'<>', unicode(self.parameterEdit.text())) text = text.replace(u'<>', unicode(self.parameterEdit.text()))
self.parent.alertsmanager.displayAlert(text) self.parent.alertsmanager.displayAlert(text)
return True return True
return False
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".

View File

@ -102,7 +102,7 @@ class BiblePlugin(Plugin):
Called to find out if the bible plugin is currently using a theme. Called to find out if the bible plugin is currently using a theme.
Returns True if the theme is being used, otherwise returns False. Returns True if the theme is being used, otherwise returns False.
""" """
if self.settings_tab.bible_theme == theme: if unicode(self.settings_tab.bible_theme) == theme:
return True return True
return False return False
@ -119,6 +119,7 @@ class BiblePlugin(Plugin):
The new name the plugin should now use. The new name the plugin should now use.
""" """
self.settings_tab.bible_theme = newTheme self.settings_tab.bible_theme = newTheme
self.settings_tab.save()
def setPluginTextStrings(self): def setPluginTextStrings(self):
""" """

View File

@ -35,7 +35,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsManager, translate from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.lib.db import delete_database 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.ui.wizard import OpenLPWizard
from openlp.core.utils import AppLocation, string_is_unicode from openlp.core.utils import AppLocation, string_is_unicode
from openlp.plugins.bibles.lib.manager import BibleFormat from openlp.plugins.bibles.lib.manager import BibleFormat
@ -157,10 +157,9 @@ class BibleImportForm(OpenLPWizard):
self.formatComboBox.addItems([u'', u'', u'', u'', u'']) self.formatComboBox.addItems([u'', u'', u'', u'', u''])
self.formatComboBox.setObjectName(u'FormatComboBox') self.formatComboBox.setObjectName(u'FormatComboBox')
self.formatLayout.addRow(self.formatLabel, self.formatComboBox) self.formatLayout.addRow(self.formatLabel, self.formatComboBox)
self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum) QtGui.QSizePolicy.Minimum)
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
self.formatSpacer)
self.selectPageLayout.addLayout(self.formatLayout) self.selectPageLayout.addLayout(self.formatLayout)
self.selectStack = QtGui.QStackedLayout() self.selectStack = QtGui.QStackedLayout()
self.selectStack.setObjectName(u'SelectStack') self.selectStack.setObjectName(u'SelectStack')
@ -181,9 +180,7 @@ class BibleImportForm(OpenLPWizard):
self.osisBrowseButton.setObjectName(u'OsisBrowseButton') self.osisBrowseButton.setObjectName(u'OsisBrowseButton')
self.osisFileLayout.addWidget(self.osisBrowseButton) self.osisFileLayout.addWidget(self.osisBrowseButton)
self.osisLayout.addRow(self.osisFileLabel, self.osisFileLayout) self.osisLayout.addRow(self.osisFileLabel, self.osisFileLayout)
self.osisSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.osisSpacer)
self.selectStack.addWidget(self.osisWidget) self.selectStack.addWidget(self.osisWidget)
self.csvWidget = QtGui.QWidget(self.selectPage) self.csvWidget = QtGui.QWidget(self.selectPage)
self.csvWidget.setObjectName(u'CsvWidget') self.csvWidget.setObjectName(u'CsvWidget')
@ -226,9 +223,7 @@ class BibleImportForm(OpenLPWizard):
self.csvVersesButton.setObjectName(u'CsvVersesButton') self.csvVersesButton.setObjectName(u'CsvVersesButton')
self.csvVersesLayout.addWidget(self.csvVersesButton) self.csvVersesLayout.addWidget(self.csvVersesButton)
self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout) self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout)
self.csvSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.csvLayout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.csvLayout.setItem(3, QtGui.QFormLayout.LabelRole, self.csvSpacer)
self.selectStack.addWidget(self.csvWidget) self.selectStack.addWidget(self.csvWidget)
self.openSongWidget = QtGui.QWidget(self.selectPage) self.openSongWidget = QtGui.QWidget(self.selectPage)
self.openSongWidget.setObjectName(u'OpenSongWidget') self.openSongWidget.setObjectName(u'OpenSongWidget')
@ -248,10 +243,7 @@ class BibleImportForm(OpenLPWizard):
self.openSongFileLayout.addWidget(self.openSongBrowseButton) self.openSongFileLayout.addWidget(self.openSongBrowseButton)
self.openSongLayout.addRow(self.openSongFileLabel, self.openSongLayout.addRow(self.openSongFileLabel,
self.openSongFileLayout) self.openSongFileLayout)
self.openSongSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.openSongSpacer)
self.selectStack.addWidget(self.openSongWidget) self.selectStack.addWidget(self.openSongWidget)
self.webTabWidget = QtGui.QTabWidget(self.selectPage) self.webTabWidget = QtGui.QTabWidget(self.selectPage)
self.webTabWidget.setObjectName(u'WebTabWidget') self.webTabWidget.setObjectName(u'WebTabWidget')
@ -330,10 +322,7 @@ class BibleImportForm(OpenLPWizard):
self.openlp1DisabledLabel.setWordWrap(True) self.openlp1DisabledLabel.setWordWrap(True)
self.openlp1DisabledLabel.setObjectName(u'Openlp1DisabledLabel') self.openlp1DisabledLabel.setObjectName(u'Openlp1DisabledLabel')
self.openlp1Layout.addRow(self.openlp1DisabledLabel) self.openlp1Layout.addRow(self.openlp1DisabledLabel)
self.openlp1Spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole,
self.openlp1Spacer)
self.selectStack.addWidget(self.openlp1Widget) self.selectStack.addWidget(self.openlp1Widget)
self.selectPageLayout.addLayout(self.selectStack) self.selectPageLayout.addLayout(self.selectStack)
self.addPage(self.selectPage) self.addPage(self.selectPage)
@ -401,17 +390,17 @@ class BibleImportForm(OpenLPWizard):
self.formatComboBox.setItemText(4, self.formatComboBox.setItemText(4,
translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x')) translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x'))
self.openlp1FileLabel.setText( self.openlp1FileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'File location:')) translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
self.osisFileLabel.setText( self.osisFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'File location:')) translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
self.csvTestamentsLabel.setText( self.csvTestamentsLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Testaments location:')) translate('BiblesPlugin.ImportWizardForm', 'Testaments file:'))
self.csvBooksLabel.setText( self.csvBooksLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Books location:')) translate('BiblesPlugin.ImportWizardForm', 'Books file:'))
self.csvVersesLabel.setText( self.csvVersesLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Verse location:')) translate('BiblesPlugin.ImportWizardForm', 'Verses file:'))
self.openSongFileLabel.setText( self.openSongFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Bible filename:')) translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
self.webSourceLabel.setText( self.webSourceLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Location:')) translate('BiblesPlugin.ImportWizardForm', 'Location:'))
self.webSourceComboBox.setItemText(0, self.webSourceComboBox.setItemText(0,
@ -462,19 +451,12 @@ class BibleImportForm(OpenLPWizard):
# Align all QFormLayouts towards each other. # Align all QFormLayouts towards each other.
labelWidth = max(self.formatLabel.minimumSizeHint().width(), labelWidth = max(self.formatLabel.minimumSizeHint().width(),
self.osisFileLabel.minimumSizeHint().width(), self.osisFileLabel.minimumSizeHint().width(),
self.csvTestamentsLabel.minimumSizeHint().width(),
self.csvBooksLabel.minimumSizeHint().width(), self.csvBooksLabel.minimumSizeHint().width(),
self.csvVersesLabel.minimumSizeHint().width(), self.csvVersesLabel.minimumSizeHint().width(),
self.openSongFileLabel.minimumSizeHint().width(), self.openSongFileLabel.minimumSizeHint().width(),
self.openlp1FileLabel.minimumSizeHint().width()) self.openlp1FileLabel.minimumSizeHint().width())
self.formatSpacer.changeSize(labelWidth, 0, self.spacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.osisSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.csvSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openSongSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openlp1Spacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
def validateCurrentPage(self): def validateCurrentPage(self):
@ -486,7 +468,7 @@ class BibleImportForm(OpenLPWizard):
elif self.currentPage() == self.selectPage: elif self.currentPage() == self.selectPage:
if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS: if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS:
if not self.field(u'osis_location').toString(): if not self.field(u'osis_location').toString():
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Bible Location'), 'Invalid Bible Location'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -496,7 +478,7 @@ class BibleImportForm(OpenLPWizard):
return False return False
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV: elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
if not self.field(u'csv_testamentsfile').toString(): if not self.field(u'csv_testamentsfile').toString():
answer = criticalErrorMessageBox(translate( answer = critical_error_message_box(translate(
'BiblesPlugin.ImportWizardForm', 'No Testaments File'), 'BiblesPlugin.ImportWizardForm', 'No Testaments File'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'You have not specified a testaments file. Do you ' 'You have not specified a testaments file. Do you '
@ -505,7 +487,7 @@ class BibleImportForm(OpenLPWizard):
self.csvTestamentsEdit.setFocus() self.csvTestamentsEdit.setFocus()
return False return False
elif not self.field(u'csv_booksfile').toString(): elif not self.field(u'csv_booksfile').toString():
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Books File'), 'Invalid Books File'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -514,7 +496,7 @@ class BibleImportForm(OpenLPWizard):
self.csvBooksEdit.setFocus() self.csvBooksEdit.setFocus()
return False return False
elif not self.field(u'csv_versefile').toString(): elif not self.field(u'csv_versefile').toString():
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Verse File'), 'Invalid Verse File'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -525,7 +507,7 @@ class BibleImportForm(OpenLPWizard):
elif self.field(u'source_format').toInt()[0] == \ elif self.field(u'source_format').toInt()[0] == \
BibleFormat.OpenSong: BibleFormat.OpenSong:
if not self.field(u'opensong_file').toString(): if not self.field(u'opensong_file').toString():
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid OpenSong Bible'), 'Invalid OpenSong Bible'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -535,7 +517,7 @@ class BibleImportForm(OpenLPWizard):
return False return False
elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1: elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1:
if not self.field(u'openlp1_location').toString(): if not self.field(u'openlp1_location').toString():
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Bible Location'), 'Invalid Bible Location'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -549,7 +531,7 @@ class BibleImportForm(OpenLPWizard):
license_copyright = \ license_copyright = \
unicode(self.field(u'license_copyright').toString()) unicode(self.field(u'license_copyright').toString())
if not license_version: if not license_version:
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Empty Version Name'), 'Empty Version Name'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -557,7 +539,7 @@ class BibleImportForm(OpenLPWizard):
self.versionNameEdit.setFocus() self.versionNameEdit.setFocus()
return False return False
elif not license_copyright: elif not license_copyright:
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Empty Copyright'), 'Empty Copyright'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -566,7 +548,7 @@ class BibleImportForm(OpenLPWizard):
self.copyrightEdit.setFocus() self.copyrightEdit.setFocus()
return False return False
elif self.manager.exists(license_version): elif self.manager.exists(license_version):
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'), translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'This Bible already exists. Please import ' 'This Bible already exists. Please import '

View File

@ -77,9 +77,9 @@ def parse_reference(reference):
- After a verse reference all further single values are treat as verse in - After a verse reference all further single values are treat as verse in
the last selected chapter. the last selected chapter.
``John 3:16-18`` refers to John chapter 3 verses 16 to 18 ``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 - 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 are build analog to the first ones. This way it is possible to define each
each number of verse references. It is not possible to refer to verses in number of verse references. It is not possible to refer to verses in
additional books. additional books.
``John 3:16,18`` refers to John chapter 3 verses 16 and 18 ``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 ``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 ``range_string`` is a regular expression which matches for verse range
declarations: declarations:
1. ``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?' 1. ``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?``
It starts with a optional chapter reference ``from_chapter`` followed by It starts with a optional chapter reference ``from_chapter`` followed by
a verse separator. a verse separator.
2. ``(?P<from_verse>[0-9]+)`` 2. ``(?P<from_verse>[0-9]+)``
@ -105,7 +105,7 @@ def parse_reference(reference):
5. ``(?P<to_verse>[0-9]+)`` 5. ``(?P<to_verse>[0-9]+)``
The ``to_verse`` reference is equivalent to group 2. 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: regular expression looks like this:
1. ``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*`` 1. ``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*``
@ -113,7 +113,7 @@ def parse_reference(reference):
are optional leading digits followed by non-digits. The group ends are optional leading digits followed by non-digits. The group ends
before the whitspace in front of the next digit. before the whitspace in front of the next digit.
2. ``(?P<ranges>(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$`` 2. ``(?P<ranges>(?:`` + 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. declarations of a range_string separated by a list separator.
The reference list is a list of tuples, with each tuple structured like The reference list is a list of tuples, with each tuple structured like

View File

@ -35,7 +35,7 @@ from sqlalchemy.orm.exc import UnmappedClassError
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.lib.db import BaseModel, init_db, Manager 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__) log = logging.getLogger(__name__)
@ -361,7 +361,7 @@ class BibleDB(QtCore.QObject, Manager):
verse_list.extend(verses) verse_list.extend(verses)
else: else:
log.debug(u'OpenLP failed to find book %s', book) log.debug(u'OpenLP failed to find book %s', book)
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'), translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching book ' translate('BiblesPlugin', 'No matching book '
'could be found in this Bible. Check that you have ' 'could be found in this Bible. Check that you have '

View File

@ -38,7 +38,7 @@ from HTMLParser import HTMLParseError
from BeautifulSoup import BeautifulSoup, NavigableString from BeautifulSoup import BeautifulSoup, NavigableString
from openlp.core.lib import Receiver, translate 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.core.utils import AppLocation, get_web_page
from openlp.plugins.bibles.lib import SearchResults from openlp.plugins.bibles.lib import SearchResults
from openlp.plugins.bibles.lib.db import BibleDB, Book from openlp.plugins.bibles.lib.db import BibleDB, Book
@ -431,7 +431,7 @@ class HTTPBible(BibleDB):
if not db_book: if not db_book:
book_details = HTTPBooks.get_book(book) book_details = HTTPBooks.get_book(book)
if not book_details: if not book_details:
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'), translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching ' translate('BiblesPlugin', 'No matching '
'book could be found in this Bible. Check that you ' 'book could be found in this Bible. Check that you '
@ -443,7 +443,6 @@ class HTTPBible(BibleDB):
book = db_book.name book = db_book.name
if BibleDB.get_verse_count(self, book, reference[1]) == 0: if BibleDB.get_verse_count(self, book, reference[1]) == 0:
Receiver.send_message(u'cursor_busy') Receiver.send_message(u'cursor_busy')
Receiver.send_message(u'openlp_process_events')
search_results = self.get_chapter(book, reference[1]) search_results = self.get_chapter(book, reference[1])
if search_results and search_results.has_verselist(): if search_results and search_results.has_verselist():
## We have found a book of the bible lets check to see ## We have found a book of the bible lets check to see
@ -552,14 +551,14 @@ def send_error_message(error_type):
The type of error that occured for the issue. The type of error that occured for the issue.
""" """
if error_type == u'download': if error_type == u'download':
criticalErrorMessageBox( critical_error_message_box(
translate('BiblePlugin.HTTPBible', 'Download Error'), translate('BiblePlugin.HTTPBible', 'Download Error'),
translate('BiblePlugin.HTTPBible', 'There was a ' translate('BiblePlugin.HTTPBible', 'There was a '
'problem downloading your verse selection. Please check your ' 'problem downloading your verse selection. Please check your '
'Internet connection, and if this error continues to occur ' 'Internet connection, and if this error continues to occur '
'please consider reporting a bug.')) 'please consider reporting a bug.'))
elif error_type == u'parse': elif error_type == u'parse':
criticalErrorMessageBox( critical_error_message_box(
translate('BiblePlugin.HTTPBible', 'Parse Error'), translate('BiblePlugin.HTTPBible', 'Parse Error'),
translate('BiblePlugin.HTTPBible', 'There was a ' translate('BiblePlugin.HTTPBible', 'There was a '
'problem extracting your verse selection. If this error continues ' 'problem extracting your verse selection. If this error continues '

View File

@ -30,7 +30,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \ from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \
ItemCapabilities, translate ItemCapabilities, translate
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import add_widget_completer, media_item_combo_box, \
critical_error_message_box
from openlp.plugins.bibles.forms import BibleImportForm from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib import get_reference_match from openlp.plugins.bibles.lib import get_reference_match
@ -81,33 +82,21 @@ class BibleMediaItem(MediaManagerItem):
self.quickLayout.setObjectName(u'quickLayout') self.quickLayout.setObjectName(u'quickLayout')
self.quickVersionLabel = QtGui.QLabel(self.quickTab) self.quickVersionLabel = QtGui.QLabel(self.quickTab)
self.quickVersionLabel.setObjectName(u'quickVersionLabel') self.quickVersionLabel.setObjectName(u'quickVersionLabel')
self.quickVersionComboBox = QtGui.QComboBox(self.quickTab) self.quickVersionComboBox = media_item_combo_box(self.quickTab,
self.quickVersionComboBox.setSizeAdjustPolicy( u'quickVersionComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickVersionComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickVersionComboBox.setObjectName(u'quickVersionComboBox')
self.quickVersionLabel.setBuddy(self.quickVersionComboBox) self.quickVersionLabel.setBuddy(self.quickVersionComboBox)
self.quickLayout.addRow(self.quickVersionLabel, self.quickLayout.addRow(self.quickVersionLabel,
self.quickVersionComboBox) self.quickVersionComboBox)
self.quickSecondLabel = QtGui.QLabel(self.quickTab) self.quickSecondLabel = QtGui.QLabel(self.quickTab)
self.quickSecondLabel.setObjectName(u'quickSecondLabel') self.quickSecondLabel.setObjectName(u'quickSecondLabel')
self.quickSecondComboBox = QtGui.QComboBox(self.quickTab) self.quickSecondComboBox = media_item_combo_box(self.quickTab,
self.quickSecondComboBox.setSizeAdjustPolicy( u'quickSecondComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickSecondComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickSecondComboBox.setObjectName(u'quickSecondComboBox')
self.quickSecondLabel.setBuddy(self.quickSecondComboBox) self.quickSecondLabel.setBuddy(self.quickSecondComboBox)
self.quickLayout.addRow(self.quickSecondLabel, self.quickSecondComboBox) self.quickLayout.addRow(self.quickSecondLabel, self.quickSecondComboBox)
self.quickSearchTypeLabel = QtGui.QLabel(self.quickTab) self.quickSearchTypeLabel = QtGui.QLabel(self.quickTab)
self.quickSearchTypeLabel.setObjectName(u'quickSearchTypeLabel') self.quickSearchTypeLabel.setObjectName(u'quickSearchTypeLabel')
self.quickSearchComboBox = QtGui.QComboBox(self.quickTab) self.quickSearchComboBox = media_item_combo_box(self.quickTab,
self.quickSearchComboBox.setSizeAdjustPolicy( u'quickSearchComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickSearchComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickSearchComboBox.setObjectName(u'quickSearchComboBox')
self.quickSearchTypeLabel.setBuddy(self.quickSearchComboBox) self.quickSearchTypeLabel.setBuddy(self.quickSearchComboBox)
self.quickLayout.addRow(self.quickSearchTypeLabel, self.quickLayout.addRow(self.quickSearchTypeLabel,
self.quickSearchComboBox) self.quickSearchComboBox)
@ -119,12 +108,8 @@ class BibleMediaItem(MediaManagerItem):
self.quickLayout.addRow(self.quickSearchLabel, self.quickSearchEdit) self.quickLayout.addRow(self.quickSearchLabel, self.quickSearchEdit)
self.quickClearLabel = QtGui.QLabel(self.quickTab) self.quickClearLabel = QtGui.QLabel(self.quickTab)
self.quickClearLabel.setObjectName(u'quickClearLabel') self.quickClearLabel.setObjectName(u'quickClearLabel')
self.quickClearComboBox = QtGui.QComboBox(self.quickTab) self.quickClearComboBox = media_item_combo_box(self.quickTab,
self.quickClearComboBox.setSizeAdjustPolicy( u'quickClearComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickClearComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickClearComboBox.setObjectName(u'quickClearComboBox')
self.quickLayout.addRow(self.quickClearLabel, self.quickClearComboBox) self.quickLayout.addRow(self.quickClearLabel, self.quickClearComboBox)
self.quickSearchButtonLayout = QtGui.QHBoxLayout() self.quickSearchButtonLayout = QtGui.QHBoxLayout()
self.quickSearchButtonLayout.setObjectName(u'quickSearchButtonLayout') self.quickSearchButtonLayout.setObjectName(u'quickSearchButtonLayout')
@ -144,36 +129,24 @@ class BibleMediaItem(MediaManagerItem):
self.advancedVersionLabel.setObjectName(u'advancedVersionLabel') self.advancedVersionLabel.setObjectName(u'advancedVersionLabel')
self.advancedLayout.addWidget(self.advancedVersionLabel, 0, 0, self.advancedLayout.addWidget(self.advancedVersionLabel, 0, 0,
QtCore.Qt.AlignRight) QtCore.Qt.AlignRight)
self.advancedVersionComboBox = QtGui.QComboBox(self.advancedTab) self.advancedVersionComboBox = media_item_combo_box(self.advancedTab,
self.advancedVersionComboBox.setSizeAdjustPolicy( u'advancedVersionComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedVersionComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedVersionComboBox.setObjectName(u'advancedVersionComboBox')
self.advancedVersionLabel.setBuddy(self.advancedVersionComboBox) self.advancedVersionLabel.setBuddy(self.advancedVersionComboBox)
self.advancedLayout.addWidget(self.advancedVersionComboBox, 0, 1, 1, 2) self.advancedLayout.addWidget(self.advancedVersionComboBox, 0, 1, 1, 2)
self.advancedSecondLabel = QtGui.QLabel(self.advancedTab) self.advancedSecondLabel = QtGui.QLabel(self.advancedTab)
self.advancedSecondLabel.setObjectName(u'advancedSecondLabel') self.advancedSecondLabel.setObjectName(u'advancedSecondLabel')
self.advancedLayout.addWidget(self.advancedSecondLabel, 1, 0, self.advancedLayout.addWidget(self.advancedSecondLabel, 1, 0,
QtCore.Qt.AlignRight) QtCore.Qt.AlignRight)
self.advancedSecondComboBox = QtGui.QComboBox(self.advancedTab) self.advancedSecondComboBox = media_item_combo_box(self.advancedTab,
self.advancedSecondComboBox.setSizeAdjustPolicy( u'advancedSecondComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedSecondComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedSecondComboBox.setObjectName(u'advancedSecondComboBox')
self.advancedSecondLabel.setBuddy(self.advancedSecondComboBox) self.advancedSecondLabel.setBuddy(self.advancedSecondComboBox)
self.advancedLayout.addWidget(self.advancedSecondComboBox, 1, 1, 1, 2) self.advancedLayout.addWidget(self.advancedSecondComboBox, 1, 1, 1, 2)
self.advancedBookLabel = QtGui.QLabel(self.advancedTab) self.advancedBookLabel = QtGui.QLabel(self.advancedTab)
self.advancedBookLabel.setObjectName(u'advancedBookLabel') self.advancedBookLabel.setObjectName(u'advancedBookLabel')
self.advancedLayout.addWidget(self.advancedBookLabel, 2, 0, self.advancedLayout.addWidget(self.advancedBookLabel, 2, 0,
QtCore.Qt.AlignRight) QtCore.Qt.AlignRight)
self.advancedBookComboBox = QtGui.QComboBox(self.advancedTab) self.advancedBookComboBox = media_item_combo_box(self.advancedTab,
self.advancedBookComboBox.setSizeAdjustPolicy( u'advancedBookComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedBookComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedBookComboBox.setObjectName(u'advancedBookComboBox')
self.advancedBookLabel.setBuddy(self.advancedBookComboBox) self.advancedBookLabel.setBuddy(self.advancedBookComboBox)
self.advancedLayout.addWidget(self.advancedBookComboBox, 2, 1, 1, 2) self.advancedLayout.addWidget(self.advancedBookComboBox, 2, 1, 1, 2)
self.advancedChapterLabel = QtGui.QLabel(self.advancedTab) self.advancedChapterLabel = QtGui.QLabel(self.advancedTab)
@ -202,17 +175,12 @@ class BibleMediaItem(MediaManagerItem):
self.advancedToVerse = QtGui.QComboBox(self.advancedTab) self.advancedToVerse = QtGui.QComboBox(self.advancedTab)
self.advancedToVerse.setObjectName(u'advancedToVerse') self.advancedToVerse.setObjectName(u'advancedToVerse')
self.advancedLayout.addWidget(self.advancedToVerse, 5, 2) self.advancedLayout.addWidget(self.advancedToVerse, 5, 2)
self.advancedClearLabel = QtGui.QLabel(self.quickTab) self.advancedClearLabel = QtGui.QLabel(self.quickTab)
self.advancedClearLabel.setObjectName(u'advancedClearLabel') self.advancedClearLabel.setObjectName(u'advancedClearLabel')
self.advancedLayout.addWidget(self.advancedClearLabel, 6, 0, self.advancedLayout.addWidget(self.advancedClearLabel, 6, 0,
QtCore.Qt.AlignRight) QtCore.Qt.AlignRight)
self.advancedClearComboBox = QtGui.QComboBox(self.quickTab) self.advancedClearComboBox = media_item_combo_box(self.quickTab,
self.advancedClearComboBox.setSizeAdjustPolicy( u'advancedClearComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedClearComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedClearComboBox.setObjectName(u'advancedClearComboBox')
self.advancedClearLabel.setBuddy(self.advancedClearComboBox) self.advancedClearLabel.setBuddy(self.advancedClearComboBox)
self.advancedLayout.addWidget(self.advancedClearComboBox, 6, 1, 1, 2) self.advancedLayout.addWidget(self.advancedClearComboBox, 6, 1, 1, 2)
self.advancedSearchButtonLayout = QtGui.QHBoxLayout() self.advancedSearchButtonLayout = QtGui.QHBoxLayout()
@ -387,7 +355,8 @@ class BibleMediaItem(MediaManagerItem):
verse_count = self.parent.manager.get_verse_count(bible, book, 1) verse_count = self.parent.manager.get_verse_count(bible, book, 1)
if verse_count == 0: if verse_count == 0:
self.advancedSearchButton.setEnabled(False) self.advancedSearchButton.setEnabled(False)
criticalErrorMessageBox(message=translate('BiblePlugin.MediaItem', critical_error_message_box(
message=translate('BiblePlugin.MediaItem',
'Bible not fully loaded')) 'Bible not fully loaded'))
else: else:
self.advancedSearchButton.setEnabled(True) self.advancedSearchButton.setEnabled(True)
@ -411,9 +380,7 @@ class BibleMediaItem(MediaManagerItem):
book_data = bibles[bible].get_books() book_data = bibles[bible].get_books()
books = [book.name for book in book_data] books = [book.name for book in book_data]
books.sort() books.sort()
completer = QtGui.QCompleter(books) add_widget_completer(books, self.quickSearchEdit)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.quickSearchEdit.setCompleter(completer)
def onAdvancedVersionComboBox(self): def onAdvancedVersionComboBox(self):
self.initialiseBible( self.initialiseBible(
@ -525,19 +492,7 @@ class BibleMediaItem(MediaManagerItem):
if self.advancedClearComboBox.currentIndex() == 0: if self.advancedClearComboBox.currentIndex() == 0:
self.listView.clear() self.listView.clear()
if self.listView.count() != 0: if self.listView.count() != 0:
# Check if the first item is a second bible item or not. self.__checkSecondBible(bible, second_bible)
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)
else: else:
self.displayResults(bible, second_bible) self.displayResults(bible, second_bible)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
@ -577,24 +532,30 @@ class BibleMediaItem(MediaManagerItem):
if self.quickClearComboBox.currentIndex() == 0: if self.quickClearComboBox.currentIndex() == 0:
self.listView.clear() self.listView.clear()
if self.listView.count() != 0 and self.search_results: if self.listView.count() != 0 and self.search_results:
bitem = self.listView.item(0) self.__checkSecondBible(bible, second_bible)
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)
elif self.search_results: elif self.search_results:
self.displayResults(bible, second_bible) self.displayResults(bible, second_bible)
self.quickSearchButton.setEnabled(True) self.quickSearchButton.setEnabled(True)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
Receiver.send_message(u'openlp_process_events') 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''): def displayResults(self, bible, second_bible=u''):
""" """
Displays the search results in the media manager. All data needed for Displays the search results in the media manager. All data needed for

View File

@ -38,7 +38,6 @@ class OpenSongBible(BibleDB):
""" """
OpenSong Bible format importer class. OpenSong Bible format importer class.
""" """
def __init__(self, parent, **kwargs): def __init__(self, parent, **kwargs):
""" """
Constructor to create and set up an instance of the OpenSongBible Constructor to create and set up an instance of the OpenSongBible
@ -81,14 +80,13 @@ class OpenSongBible(BibleDB):
db_book.id, db_book.id,
int(chapter.attrib[u'n'].split()[-1]), int(chapter.attrib[u'n'].split()[-1]),
int(verse.attrib[u'n']), int(verse.attrib[u'n']),
unicode(verse.text) unicode(verse.text))
)
Receiver.send_message(u'openlp_process_events')
self.wizard.incrementProgressBar(unicode(translate( self.wizard.incrementProgressBar(unicode(translate(
'BiblesPlugin.Opensong', 'Importing %s %s...', 'BiblesPlugin.Opensong', 'Importing %s %s...',
'Importing <book name> <chapter>...')) % 'Importing <book name> <chapter>...')) %
(db_book.name, int(chapter.attrib[u'n'].split()[-1]))) (db_book.name, int(chapter.attrib[u'n'].split()[-1])))
self.session.commit() self.session.commit()
Receiver.send_message(u'openlp_process_events')
except (IOError, AttributeError): except (IOError, AttributeError):
log.exception(u'Loading bible from OpenSong file failed') log.exception(u'Loading bible from OpenSong file failed')
success = False success = False

View File

@ -27,6 +27,8 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate from openlp.core.lib import build_icon, translate
from openlp.core.lib.ui import create_save_cancel_button_box, \
create_delete_push_button, create_up_down_push_button_set
class Ui_CustomEditDialog(object): class Ui_CustomEditDialog(object):
def setupUi(self, customEditDialog): def setupUi(self, customEditDialog):
@ -58,22 +60,21 @@ class Ui_CustomEditDialog(object):
self.addButton.setObjectName(u'addButton') self.addButton.setObjectName(u'addButton')
self.buttonLayout.addWidget(self.addButton) self.buttonLayout.addWidget(self.addButton)
self.editButton = QtGui.QPushButton(customEditDialog) self.editButton = QtGui.QPushButton(customEditDialog)
self.editButton.setEnabled(False)
self.editButton.setObjectName(u'editButton') self.editButton.setObjectName(u'editButton')
self.buttonLayout.addWidget(self.editButton) self.buttonLayout.addWidget(self.editButton)
self.editAllButton = QtGui.QPushButton(customEditDialog) self.editAllButton = QtGui.QPushButton(customEditDialog)
self.editAllButton.setObjectName(u'editAllButton') self.editAllButton.setObjectName(u'editAllButton')
self.buttonLayout.addWidget(self.editAllButton) self.buttonLayout.addWidget(self.editAllButton)
self.deleteButton = QtGui.QPushButton(customEditDialog) self.deleteButton = create_delete_push_button(customEditDialog)
self.deleteButton.setObjectName(u'deleteButton') self.deleteButton.setEnabled(False)
self.buttonLayout.addWidget(self.deleteButton) self.buttonLayout.addWidget(self.deleteButton)
self.buttonLayout.addStretch() self.buttonLayout.addStretch()
self.upButton = QtGui.QPushButton(customEditDialog) self.upButton, self.downButton = create_up_down_push_button_set(
self.upButton.setIcon(build_icon(u':/services/service_up.png')) customEditDialog)
self.upButton.setObjectName(u'upButton') self.upButton.setEnabled(False)
self.downButton.setEnabled(False)
self.buttonLayout.addWidget(self.upButton) self.buttonLayout.addWidget(self.upButton)
self.downButton = QtGui.QPushButton(customEditDialog)
self.downButton.setIcon(build_icon(u':/services/service_down.png'))
self.downButton.setObjectName(u'downButton')
self.buttonLayout.addWidget(self.downButton) self.buttonLayout.addWidget(self.downButton)
self.centralLayout.addLayout(self.buttonLayout) self.centralLayout.addLayout(self.buttonLayout)
self.dialogLayout.addLayout(self.centralLayout) self.dialogLayout.addLayout(self.centralLayout)
@ -93,27 +94,17 @@ class Ui_CustomEditDialog(object):
self.creditLabel.setBuddy(self.creditEdit) self.creditLabel.setBuddy(self.creditEdit)
self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit) self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit)
self.dialogLayout.addLayout(self.bottomFormLayout) self.dialogLayout.addLayout(self.bottomFormLayout)
self.buttonBox = QtGui.QDialogButtonBox(customEditDialog) self.buttonBox = create_save_cancel_button_box(customEditDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | self.previewButton = QtGui.QPushButton()
QtGui.QDialogButtonBox.Save) self.buttonBox.addButton(
self.buttonBox.setObjectName(u'buttonBox') self.previewButton, QtGui.QDialogButtonBox.ActionRole)
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(customEditDialog) 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) QtCore.QMetaObject.connectSlotsByName(customEditDialog)
def retranslateUi(self, customEditDialog): def retranslateUi(self, customEditDialog):
customEditDialog.setWindowTitle( customEditDialog.setWindowTitle(
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides')) translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
self.upButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide up one '
'position.'))
self.downButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide down one '
'position.'))
self.titleLabel.setText( self.titleLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Title:')) translate('CustomPlugin.EditCustomForm', '&Title:'))
self.addButton.setText( self.addButton.setText(
@ -131,12 +122,9 @@ class Ui_CustomEditDialog(object):
self.editAllButton.setToolTip( self.editAllButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit all the slides at ' translate('CustomPlugin.EditCustomForm', 'Edit all the slides at '
'once.')) 'once.'))
self.deleteButton.setText(
translate('CustomPlugin.EditCustomForm', '&Delete'))
self.deleteButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Delete the selected '
'slide.'))
self.themeLabel.setText( self.themeLabel.setText(
translate('CustomPlugin.EditCustomForm', 'The&me:')) translate('CustomPlugin.EditCustomForm', 'The&me:'))
self.creditLabel.setText( self.creditLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Credits:')) translate('CustomPlugin.EditCustomForm', '&Credits:'))
self.previewButton.setText(
translate('CustomPlugin.EditCustomForm', 'Save && Preview'))

View File

@ -29,7 +29,7 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, translate 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 import CustomXMLBuilder, CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide from openlp.plugins.custom.lib.db import CustomSlide
from editcustomdialog import Ui_CustomEditDialog from editcustomdialog import Ui_CustomEditDialog
@ -48,52 +48,22 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
""" """
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
# Create other objects and forms.
self.manager = manager
self.editSlideForm = EditCustomSlideForm(self)
# Connecting signals and slots # Connecting signals and slots
self.previewButton = QtGui.QPushButton() QtCore.QObject.connect(self.previewButton,
self.previewButton.setText( QtCore.SIGNAL(u'pressed()'), self.onPreviewButtonPressed)
translate('CustomPlugin.EditCustomForm', 'Save && Preview'))
self.buttonBox.addButton(
self.previewButton, QtGui.QDialogButtonBox.ActionRole)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview)
QtCore.QObject.connect(self.addButton, QtCore.QObject.connect(self.addButton,
QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed)
QtCore.QObject.connect(self.editButton, QtCore.QObject.connect(self.editButton,
QtCore.SIGNAL(u'pressed()'), self.onEditButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onEditButtonPressed)
QtCore.QObject.connect(self.editAllButton, QtCore.QObject.connect(self.editAllButton,
QtCore.SIGNAL(u'pressed()'), self.onEditAllButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onEditAllButtonPressed)
QtCore.QObject.connect(self.deleteButton,
QtCore.SIGNAL(u'pressed()'), self.onDeleteButtonPressed)
QtCore.QObject.connect(self.upButton,
QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed)
QtCore.QObject.connect(self.downButton,
QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed)
QtCore.QObject.connect(self.slideListView,
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
self.onSlideListViewPressed)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.loadThemes) QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
# Create other objects and forms. QtCore.QObject.connect(self.slideListView,
self.manager = manager QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
self.editSlideForm = EditCustomSlideForm(self)
self.initialise()
def onPreview(self, button):
log.debug(u'onPreview')
if button.text() == unicode(translate('CustomPlugin.EditCustomForm',
'Save && Preview')) and self.saveCustom():
Receiver.send_message(u'custom_preview')
def initialise(self):
self.addButton.setEnabled(True)
self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(True)
self.titleEdit.setText(u'')
self.creditEdit.setText(u'')
self.slideListView.clear()
# Make sure we have a new item.
self.customSlide = CustomSlide()
def loadThemes(self, themelist): def loadThemes(self, themelist):
self.themeComboBox.clear() self.themeComboBox.clear()
@ -112,9 +82,13 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
States whether the custom is edited while being previewed in the States whether the custom is edited while being previewed in the
preview panel. preview panel.
""" """
self.customSlide = CustomSlide() self.slideListView.clear()
self.initialise() if id == 0:
if id != 0: self.customSlide = CustomSlide()
self.titleEdit.setText(u'')
self.creditEdit.setText(u'')
self.themeComboBox.setCurrentIndex(0)
else:
self.customSlide = self.manager.get_object(CustomSlide, id) self.customSlide = self.manager.get_object(CustomSlide, id)
self.titleEdit.setText(self.customSlide.title) self.titleEdit.setText(self.customSlide.title)
self.creditEdit.setText(self.customSlide.credits) self.creditEdit.setText(self.customSlide.credits)
@ -128,31 +102,26 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
if id == -1: if id == -1:
id = 0 id = 0
self.themeComboBox.setCurrentIndex(id) self.themeComboBox.setCurrentIndex(id)
else:
self.themeComboBox.setCurrentIndex(0)
self.editAllButton.setEnabled(False)
# If not preview hide the preview button. # If not preview hide the preview button.
self.previewButton.setVisible(False) self.previewButton.setVisible(False)
if preview: if preview:
self.previewButton.setVisible(True) self.previewButton.setVisible(True)
def closePressed(self): def reject(self):
Receiver.send_message(u'custom_edit_clear') Receiver.send_message(u'custom_edit_clear')
self.close() QtGui.QDialog.reject(self)
def accept(self): def accept(self):
log.debug(u'accept') log.debug(u'accept')
if self.saveCustom(): if self.saveCustom():
Receiver.send_message(u'custom_load_list') Receiver.send_message(u'custom_load_list')
self.close() QtGui.QDialog.accept(self)
def saveCustom(self): def saveCustom(self):
""" """
Saves the custom. Saves the custom.
""" """
valid, message = self._validate() if not self._validate():
if not valid:
criticalErrorMessageBox(message=message)
return False return False
sxml = CustomXMLBuilder() sxml = CustomXMLBuilder()
sxml.new_document() sxml.new_document()
@ -168,14 +137,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.customSlide.theme_name = unicode(self.themeComboBox.currentText()) self.customSlide.theme_name = unicode(self.themeComboBox.currentText())
return self.manager.save_object(self.customSlide) return self.manager.save_object(self.customSlide)
def onUpButtonPressed(self): def onUpButtonClicked(self):
selectedRow = self.slideListView.currentRow() selectedRow = self.slideListView.currentRow()
if selectedRow != 0: if selectedRow != 0:
qw = self.slideListView.takeItem(selectedRow) qw = self.slideListView.takeItem(selectedRow)
self.slideListView.insertItem(selectedRow - 1, qw) self.slideListView.insertItem(selectedRow - 1, qw)
self.slideListView.setCurrentRow(selectedRow - 1) self.slideListView.setCurrentRow(selectedRow - 1)
def onDownButtonPressed(self): def onDownButtonClicked(self):
selectedRow = self.slideListView.currentRow() selectedRow = self.slideListView.currentRow()
# zero base arrays # zero base arrays
if selectedRow != self.slideListView.count() - 1: if selectedRow != self.slideListView.count() - 1:
@ -183,16 +152,11 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.slideListView.insertItem(selectedRow + 1, qw) self.slideListView.insertItem(selectedRow + 1, qw)
self.slideListView.setCurrentRow(selectedRow + 1) self.slideListView.setCurrentRow(selectedRow + 1)
def onSlideListViewPressed(self, item):
self.deleteButton.setEnabled(True)
self.editButton.setEnabled(True)
def onAddButtonPressed(self): def onAddButtonPressed(self):
self.editSlideForm.setText(u'') self.editSlideForm.setText(u'')
if self.editSlideForm.exec_(): if self.editSlideForm.exec_():
for slide in self.editSlideForm.getText(): for slide in self.editSlideForm.getText():
self.slideListView.addItem(slide) self.slideListView.addItem(slide)
self.editAllButton.setEnabled(True)
def onEditButtonPressed(self): def onEditButtonPressed(self):
self.editSlideForm.setText(self.slideListView.currentItem().text()) self.editSlideForm.setText(self.slideListView.currentItem().text())
@ -203,16 +167,23 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
""" """
Edits all slides. Edits all slides.
""" """
if self.slideListView.count() > 0: slide_list = u''
slide_list = u'' for row in range(0, self.slideListView.count()):
for row in range(0, self.slideListView.count()): item = self.slideListView.item(row)
item = self.slideListView.item(row) slide_list += item.text()
slide_list += item.text() if row != self.slideListView.count() - 1:
if row != self.slideListView.count() - 1: slide_list += u'\n[---]\n'
slide_list += u'\n[---]\n' self.editSlideForm.setText(slide_list)
self.editSlideForm.setText(slide_list) if self.editSlideForm.exec_():
if self.editSlideForm.exec_(): self.updateSlideList(self.editSlideForm.getText(), True)
self.updateSlideList(self.editSlideForm.getText(), True)
def onPreviewButtonPressed(self):
"""
Save the custom item and preview it.
"""
log.debug(u'onPreview')
if self.saveCustom():
Receiver.send_message(u'custom_preview')
def updateSlideList(self, slides, edit_all=False): def updateSlideList(self, slides, edit_all=False):
""" """
@ -243,14 +214,41 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.slideListView.addItem(slide) self.slideListView.addItem(slide)
self.slideListView.repaint() self.slideListView.repaint()
def onDeleteButtonPressed(self): def onDeleteButtonClicked(self):
"""
Removes the current row from the list.
"""
self.slideListView.takeItem(self.slideListView.currentRow()) self.slideListView.takeItem(self.slideListView.currentRow())
self.editButton.setEnabled(True) if self.slideListView.currentRow() == 0:
self.editAllButton.setEnabled(True) self.upButton.setEnabled(False)
if self.slideListView.count() == 0: if self.slideListView.currentRow() == self.slideListView.count():
self.downButton.setEnabled(False)
def onCurrentRowChanged(self, row):
"""
Called when the *slideListView*'s current row has been changed. This
enables or disables buttons which require an slide to act on.
``row``
The row (int). If there is no current row, the value is -1.
"""
if row == -1:
self.deleteButton.setEnabled(False) self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False) self.editButton.setEnabled(False)
self.editAllButton.setEnabled(False) self.upButton.setEnabled(False)
self.downButton.setEnabled(False)
else:
self.deleteButton.setEnabled(True)
self.editButton.setEnabled(True)
# Decide if the up/down buttons should be enabled or not.
if self.slideListView.count() - 1 == row:
self.downButton.setEnabled(False)
else:
self.downButton.setEnabled(True)
if row == 0:
self.upButton.setEnabled(False)
else:
self.upButton.setEnabled(True)
def _validate(self): def _validate(self):
""" """
@ -259,10 +257,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
# We must have a title. # We must have a title.
if len(self.titleEdit.displayText()) == 0: if len(self.titleEdit.displayText()) == 0:
self.titleEdit.setFocus() self.titleEdit.setFocus()
return False, translate('CustomPlugin.EditCustomForm', critical_error_message_box(
'You need to type in a title.') message=translate('CustomPlugin.EditCustomForm',
'You need to type in a title.'))
return False
# We must have at least one slide. # We must have at least one slide.
if self.slideListView.count() == 0: if self.slideListView.count() == 0:
return False, translate('CustomPlugin.EditCustomForm', critical_error_message_box(
'You need to add at least one slide') message=translate('CustomPlugin.EditCustomForm',
return True, u'' 'You need to add at least one slide'))
return False
return True

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, SpellTextEdit from openlp.core.lib import translate, SpellTextEdit
from openlp.core.lib.ui import create_save_cancel_button_box
class Ui_CustomSlideEditDialog(object): class Ui_CustomSlideEditDialog(object):
def setupUi(self, customSlideEditDialog): def setupUi(self, customSlideEditDialog):
@ -36,20 +37,13 @@ class Ui_CustomSlideEditDialog(object):
self.slideTextEdit = SpellTextEdit(self) self.slideTextEdit = SpellTextEdit(self)
self.slideTextEdit.setObjectName(u'slideTextEdit') self.slideTextEdit.setObjectName(u'slideTextEdit')
self.dialogLayout.addWidget(self.slideTextEdit) self.dialogLayout.addWidget(self.slideTextEdit)
self.buttonBox = QtGui.QDialogButtonBox(customSlideEditDialog) self.buttonBox = create_save_cancel_button_box(customSlideEditDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.splitButton = QtGui.QPushButton(customSlideEditDialog) self.splitButton = QtGui.QPushButton(customSlideEditDialog)
self.splitButton.setObjectName(u'splitButton') self.splitButton.setObjectName(u'splitButton')
self.buttonBox.addButton(self.splitButton, self.buttonBox.addButton(self.splitButton,
QtGui.QDialogButtonBox.ActionRole) QtGui.QDialogButtonBox.ActionRole)
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(customSlideEditDialog) 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) QtCore.QMetaObject.connectSlotsByName(customSlideEditDialog)
def retranslateUi(self, customSlideEditDialog): def retranslateUi(self, customSlideEditDialog):

View File

@ -69,7 +69,7 @@ class CustomMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick) QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
def initialise(self): def initialise(self):
self.loadCustomListView(self.manager.get_all_objects( self.loadList(self.manager.get_all_objects(
CustomSlide, order_by_ref=CustomSlide.title)) CustomSlide, order_by_ref=CustomSlide.title))
# Called to redisplay the custom list screen edith from a search # Called to redisplay the custom list screen edith from a search
# or from the exit of the Custom edit dialog. If remote editing is # or from the exit of the Custom edit dialog. If remote editing is
@ -80,7 +80,7 @@ class CustomMediaItem(MediaManagerItem):
self.onPreviewClick() self.onPreviewClick()
self.onRemoteEditClear() self.onRemoteEditClear()
def loadCustomListView(self, list): def loadList(self, list):
self.listView.clear() self.listView.clear()
for customSlide in list: for customSlide in list:
custom_name = QtGui.QListWidgetItem(customSlide.title) custom_name = QtGui.QListWidgetItem(customSlide.title)
@ -146,16 +146,7 @@ class CustomMediaItem(MediaManagerItem):
raw_footer = [] raw_footer = []
slide = None slide = None
theme = None theme = None
if item is None: item_id = self._getIdOfItemToGenerate(item, self.remoteCustom)
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]
service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)

View File

@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
ItemCapabilities, SettingsManager, translate, check_item_selected, \ ItemCapabilities, SettingsManager, translate, check_item_selected, \
check_directory_exists, Receiver 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 from openlp.core.utils import AppLocation, delete_file, get_images_filter
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -123,19 +123,19 @@ class ImageMediaItem(MediaManagerItem):
self.settingsSection, self.getFileList()) self.settingsSection, self.getFileList())
def loadList(self, list): def loadList(self, list):
for file in list: for imageFile in list:
filename = os.path.split(unicode(file))[1] filename = os.path.split(unicode(imageFile))[1]
thumb = os.path.join(self.servicePath, filename) thumb = os.path.join(self.servicePath, filename)
if os.path.exists(thumb): if os.path.exists(thumb):
if self.validate(file, thumb): if self.validate(imageFile, thumb):
icon = build_icon(thumb) icon = build_icon(thumb)
else: else:
icon = build_icon(u':/general/general_delete.png') icon = build_icon(u':/general/general_delete.png')
else: else:
icon = self.iconFromFile(file, thumb) icon = self.iconFromFile(imageFile, thumb)
item_name = QtGui.QListWidgetItem(filename) item_name = QtGui.QListWidgetItem(filename)
item_name.setIcon(icon) item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
self.listView.addItem(item_name) self.listView.addItem(item_name)
def generateSlideData(self, service_item, item=None, xmlVersion=False): def generateSlideData(self, service_item, item=None, xmlVersion=False):
@ -161,7 +161,7 @@ class ImageMediaItem(MediaManagerItem):
items.remove(item) items.remove(item)
# We cannot continue, as all images do not exist. # We cannot continue, as all images do not exist.
if not items: if not items:
criticalErrorMessageBox( critical_error_message_box(
translate('ImagePlugin.MediaItem', 'Missing Image(s)'), translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
unicode(translate('ImagePlugin.MediaItem', unicode(translate('ImagePlugin.MediaItem',
'The following image(s) no longer exist: %s')) % 'The following image(s) no longer exist: %s')) %
@ -214,7 +214,7 @@ class ImageMediaItem(MediaManagerItem):
self.parent.liveController.display.directImage(name, filename) self.parent.liveController.display.directImage(name, filename)
self.resetAction.setVisible(True) self.resetAction.setVisible(True)
else: else:
criticalErrorMessageBox( critical_error_message_box(
translate('ImagePlugin.MediaItem', 'Live Background Error'), translate('ImagePlugin.MediaItem', 'Live Background Error'),
unicode(translate('ImagePlugin.MediaItem', unicode(translate('ImagePlugin.MediaItem',
'There was a problem replacing your background, ' 'There was a problem replacing your background, '

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
ItemCapabilities, SettingsManager, translate, check_item_selected, Receiver 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__) log = logging.getLogger(__name__)
@ -57,7 +57,6 @@ class MediaMediaItem(MediaManagerItem):
u':/media/media_video.png').toImage() u':/media/media_video.png').toImage()
MediaManagerItem.__init__(self, parent, self, icon) MediaManagerItem.__init__(self, parent, self, icon)
self.singleServiceItem = False self.singleServiceItem = False
self.serviceItemIconName = u':/media/image_clapperboard.png'
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'video_background_replaced'), QtCore.SIGNAL(u'video_background_replaced'),
self.videobackgroundReplaced) self.videobackgroundReplaced)
@ -121,7 +120,7 @@ class MediaMediaItem(MediaManagerItem):
self.parent.liveController.display.video(filename, 0, True) self.parent.liveController.display.video(filename, 0, True)
self.resetAction.setVisible(True) self.resetAction.setVisible(True)
else: else:
criticalErrorMessageBox(translate('MediaPlugin.MediaItem', critical_error_message_box(translate('MediaPlugin.MediaItem',
'Live Background Error'), 'Live Background Error'),
unicode(translate('MediaPlugin.MediaItem', unicode(translate('MediaPlugin.MediaItem',
'There was a problem replacing your background, ' 'There was a problem replacing your background, '
@ -145,7 +144,7 @@ class MediaMediaItem(MediaManagerItem):
return True return True
else: else:
# File is no longer present # File is no longer present
criticalErrorMessageBox( critical_error_message_box(
translate('MediaPlugin.MediaItem', 'Missing Media File'), translate('MediaPlugin.MediaItem', 'Missing Media File'),
unicode(translate('MediaPlugin.MediaItem', unicode(translate('MediaPlugin.MediaItem',
'The file %s no longer exists.')) % filename) 'The file %s no longer exists.')) % filename)

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
SettingsManager, translate, check_item_selected, Receiver, ItemCapabilities 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 from openlp.plugins.presentations.lib import MessageListener
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -116,12 +116,8 @@ class PresentationMediaItem(MediaManagerItem):
self.displayLayout.setObjectName(u'displayLayout') self.displayLayout.setObjectName(u'displayLayout')
self.displayTypeLabel = QtGui.QLabel(self.presentationWidget) self.displayTypeLabel = QtGui.QLabel(self.presentationWidget)
self.displayTypeLabel.setObjectName(u'displayTypeLabel') self.displayTypeLabel.setObjectName(u'displayTypeLabel')
self.displayTypeComboBox = QtGui.QComboBox(self.presentationWidget) self.displayTypeComboBox = media_item_combo_box(
self.displayTypeComboBox.setSizeAdjustPolicy( self.presentationWidget, u'displayTypeComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.displayTypeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.displayTypeComboBox.setObjectName(u'displayTypeComboBox')
self.displayTypeLabel.setBuddy(self.displayTypeComboBox) self.displayTypeLabel.setBuddy(self.displayTypeComboBox)
self.displayLayout.addRow(self.displayTypeLabel, self.displayLayout.addRow(self.displayTypeLabel,
self.displayTypeComboBox) self.displayTypeComboBox)
@ -181,7 +177,7 @@ class PresentationMediaItem(MediaManagerItem):
filename = os.path.split(unicode(file))[1] filename = os.path.split(unicode(file))[1]
if titles.count(filename) > 0: if titles.count(filename) > 0:
if not initialLoad: if not initialLoad:
criticalErrorMessageBox( critical_error_message_box(
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'File Exists'), 'File Exists'),
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
@ -205,7 +201,7 @@ class PresentationMediaItem(MediaManagerItem):
if initialLoad: if initialLoad:
icon = build_icon(u':/general/general_delete.png') icon = build_icon(u':/general/general_delete.png')
else: else:
criticalErrorMessageBox( critical_error_message_box(
self, translate('PresentationPlugin.MediaItem', self, translate('PresentationPlugin.MediaItem',
'Unsupported File'), 'Unsupported File'),
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
@ -278,7 +274,7 @@ class PresentationMediaItem(MediaManagerItem):
return True return True
else: else:
# File is no longer present # File is no longer present
criticalErrorMessageBox( critical_error_message_box(
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'Missing Presentation'), 'Missing Presentation'),
unicode(translate('PresentationPlugin.MediaItem', unicode(translate('PresentationPlugin.MediaItem',
@ -287,7 +283,7 @@ class PresentationMediaItem(MediaManagerItem):
return False return False
else: else:
# File is no longer present # File is no longer present
criticalErrorMessageBox( critical_error_message_box(
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'Missing Presentation'), 'Missing Presentation'),
unicode(translate('PresentationPlugin.MediaItem', unicode(translate('PresentationPlugin.MediaItem',

View File

@ -116,7 +116,7 @@ class Controller(object):
def last(self): 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) log.debug(u'Live = %s, last' % self.is_live)
if not self.is_live: if not self.is_live:

View File

@ -74,7 +74,11 @@ class PresentationPlugin(Plugin):
self.insertToolboxItem() self.insertToolboxItem()
for controller in self.controllers: for controller in self.controllers:
if self.controllers[controller].enabled(): if self.controllers[controller].enabled():
self.controllers[controller].start_process() try:
self.controllers[controller].start_process()
except:
log.exception(u'Failed to start controller process')
self.controllers[controller].available = False
self.mediaItem.buildFileMaskString() self.mediaItem.buildFileMaskString()
def finalise(self): def finalise(self):

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.lib.ui import create_save_cancel_button_box
class Ui_AuthorsDialog(object): class Ui_AuthorsDialog(object):
def setupUi(self, authorsDialog): def setupUi(self, authorsDialog):
@ -55,17 +56,10 @@ class Ui_AuthorsDialog(object):
self.displayLabel.setBuddy(self.displayEdit) self.displayLabel.setBuddy(self.displayEdit)
self.authorLayout.addRow(self.displayLabel, self.displayEdit) self.authorLayout.addRow(self.displayLabel, self.displayEdit)
self.dialogLayout.addLayout(self.authorLayout) self.dialogLayout.addLayout(self.authorLayout)
self.buttonBox = QtGui.QDialogButtonBox(authorsDialog) self.dialogLayout.addWidget(
self.buttonBox.setStandardButtons( create_save_cancel_button_box(authorsDialog))
QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(authorsDialog) self.retranslateUi(authorsDialog)
authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height()) 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) QtCore.QMetaObject.connectSlotsByName(authorsDialog)
def retranslateUi(self, authorsDialog): def retranslateUi(self, authorsDialog):

View File

@ -27,7 +27,7 @@
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from openlp.core.lib import translate 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 from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog
class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog): class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
@ -80,17 +80,19 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
def accept(self): def accept(self):
if not self.firstNameEdit.text(): 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.')) 'You need to type in the first name of the author.'))
self.firstNameEdit.setFocus() self.firstNameEdit.setFocus()
return False return False
elif not self.lastNameEdit.text(): 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.')) 'You need to type in the last name of the author.'))
self.lastNameEdit.setFocus() self.lastNameEdit.setFocus()
return False return False
elif not self.displayEdit.text(): elif not self.displayEdit.text():
if criticalErrorMessageBox( if critical_error_message_box(
message=translate('SongsPlugin.AuthorsForm', message=translate('SongsPlugin.AuthorsForm',
'You have not set a display name for the ' 'You have not set a display name for the '
'author, combine the first and last names?'), 'author, combine the first and last names?'),

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate from openlp.core.lib import build_icon, translate
from openlp.core.lib.ui import create_save_cancel_button_box
class Ui_EditSongDialog(object): class Ui_EditSongDialog(object):
def setupUi(self, editSongDialog): def setupUi(self, editSongDialog):
@ -111,14 +112,8 @@ class Ui_EditSongDialog(object):
self.authorsLayout.setObjectName(u'authorsLayout') self.authorsLayout.setObjectName(u'authorsLayout')
self.authorAddLayout = QtGui.QHBoxLayout() self.authorAddLayout = QtGui.QHBoxLayout()
self.authorAddLayout.setObjectName(u'authorAddLayout') self.authorAddLayout.setObjectName(u'authorAddLayout')
self.authorsComboBox = QtGui.QComboBox(self.authorsGroupBox) self.authorsComboBox = editSongDialogComboBox(
self.authorsComboBox.setSizeAdjustPolicy( self.authorsGroupBox, u'authorsComboBox')
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.authorAddLayout.addWidget(self.authorsComboBox) self.authorAddLayout.addWidget(self.authorsComboBox)
self.authorAddButton = QtGui.QPushButton(self.authorsGroupBox) self.authorAddButton = QtGui.QPushButton(self.authorsGroupBox)
self.authorAddButton.setObjectName(u'authorAddButton') self.authorAddButton.setObjectName(u'authorAddButton')
@ -152,14 +147,8 @@ class Ui_EditSongDialog(object):
self.topicsLayout.setObjectName(u'topicsLayout') self.topicsLayout.setObjectName(u'topicsLayout')
self.topicAddLayout = QtGui.QHBoxLayout() self.topicAddLayout = QtGui.QHBoxLayout()
self.topicAddLayout.setObjectName(u'topicAddLayout') self.topicAddLayout.setObjectName(u'topicAddLayout')
self.topicsComboBox = QtGui.QComboBox(self.topicsGroupBox) self.topicsComboBox = editSongDialogComboBox(
self.topicsComboBox.setSizeAdjustPolicy( self.topicsGroupBox, u'topicsComboBox')
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.topicAddLayout.addWidget(self.topicsComboBox) self.topicAddLayout.addWidget(self.topicsComboBox)
self.topicAddButton = QtGui.QPushButton(self.topicsGroupBox) self.topicAddButton = QtGui.QPushButton(self.topicsGroupBox)
self.topicAddButton.setObjectName(u'topicAddButton') self.topicAddButton.setObjectName(u'topicAddButton')
@ -183,14 +172,8 @@ class Ui_EditSongDialog(object):
self.songBookLayout.setObjectName(u'songBookLayout') self.songBookLayout.setObjectName(u'songBookLayout')
self.songBookNameLabel = QtGui.QLabel(self.songBookGroupBox) self.songBookNameLabel = QtGui.QLabel(self.songBookGroupBox)
self.songBookNameLabel.setObjectName(u'songBookNameLabel') self.songBookNameLabel.setObjectName(u'songBookNameLabel')
self.songBookComboBox = QtGui.QComboBox(self.songBookGroupBox) self.songBookComboBox = editSongDialogComboBox(
self.songBookComboBox.setSizeAdjustPolicy( self.songBookGroupBox, u'songBookComboBox')
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.songBookNameLabel.setBuddy(self.songBookComboBox) self.songBookNameLabel.setBuddy(self.songBookComboBox)
self.songBookLayout.addRow(self.songBookNameLabel, self.songBookLayout.addRow(self.songBookNameLabel,
self.songBookComboBox) self.songBookComboBox)
@ -215,14 +198,8 @@ class Ui_EditSongDialog(object):
self.themeGroupBox.setObjectName(u'themeGroupBox') self.themeGroupBox.setObjectName(u'themeGroupBox')
self.themeLayout = QtGui.QHBoxLayout(self.themeGroupBox) self.themeLayout = QtGui.QHBoxLayout(self.themeGroupBox)
self.themeLayout.setObjectName(u'themeLayout') self.themeLayout.setObjectName(u'themeLayout')
self.themeComboBox = QtGui.QComboBox(self.themeGroupBox) self.themeComboBox = editSongDialogComboBox(
self.themeComboBox.setSizeAdjustPolicy( self.themeGroupBox, u'themeComboBox')
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.themeLayout.addWidget(self.themeComboBox) self.themeLayout.addWidget(self.themeComboBox)
self.themeAddButton = QtGui.QPushButton(self.themeGroupBox) self.themeAddButton = QtGui.QPushButton(self.themeGroupBox)
self.themeAddButton.setObjectName(u'themeAddButton') self.themeAddButton.setObjectName(u'themeAddButton')
@ -264,16 +241,9 @@ class Ui_EditSongDialog(object):
self.themeTabLayout.addWidget(self.commentsGroupBox) self.themeTabLayout.addWidget(self.commentsGroupBox)
self.songTabWidget.addTab(self.themeTab, u'') self.songTabWidget.addTab(self.themeTab, u'')
self.dialogLayout.addWidget(self.songTabWidget) self.dialogLayout.addWidget(self.songTabWidget)
self.buttonBox = QtGui.QDialogButtonBox(editSongDialog) self.buttonBox = create_save_cancel_button_box(editSongDialog)
self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(editSongDialog) 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) QtCore.QMetaObject.connectSlotsByName(editSongDialog)
def retranslateUi(self, editSongDialog): def retranslateUi(self, editSongDialog):
@ -338,3 +308,15 @@ class Ui_EditSongDialog(object):
self.songTabWidget.indexOf(self.themeTab), self.songTabWidget.indexOf(self.themeTab),
translate('SongsPlugin.EditSongForm', translate('SongsPlugin.EditSongForm',
'Theme, Copyright Info && Comments')) '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

View File

@ -30,7 +30,7 @@ import re
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import add_widget_completer, critical_error_message_box
from openlp.plugins.songs.forms import EditVerseForm from openlp.plugins.songs.forms import EditVerseForm
from openlp.plugins.songs.lib import SongXML, VerseType from openlp.plugins.songs.lib import SongXML, VerseType
from openlp.plugins.songs.lib.db import Book, Song, Author, Topic from openlp.plugins.songs.lib.db import Book, Song, Author, Topic
@ -129,37 +129,26 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.authorsComboBox.setItemData( self.authorsComboBox.setItemData(
row, QtCore.QVariant(author.id)) row, QtCore.QVariant(author.id))
self.authors.append(author.display_name) self.authors.append(author.display_name)
completer = QtGui.QCompleter(self.authors) add_widget_completer(self.authors, self.authorsComboBox)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.authorsComboBox.setCompleter(completer)
def loadTopics(self): def loadTopics(self):
topics = self.manager.get_all_objects(Topic, order_by_ref=Topic.name)
self.topicsComboBox.clear()
self.topicsComboBox.addItem(u'')
self.topics = [] self.topics = []
for topic in topics: self.__loadObjects(Topic, self.topicsComboBox, self.topics)
row = self.topicsComboBox.count()
self.topicsComboBox.addItem(topic.name)
self.topics.append(topic.name)
self.topicsComboBox.setItemData(row, QtCore.QVariant(topic.id))
completer = QtGui.QCompleter(self.topics)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.topicsComboBox.setCompleter(completer)
def loadBooks(self): def loadBooks(self):
books = self.manager.get_all_objects(Book, order_by_ref=Book.name)
self.songBookComboBox.clear()
self.songBookComboBox.addItem(u'')
self.books = [] self.books = []
for book in books: self.__loadObjects(Book, self.songBookComboBox, self.books)
row = self.songBookComboBox.count()
self.songBookComboBox.addItem(book.name) def __loadObjects(self, cls, combo, cache):
self.books.append(book.name) objects = self.manager.get_all_objects(cls, order_by_ref=cls.name)
self.songBookComboBox.setItemData(row, QtCore.QVariant(book.id)) combo.clear()
completer = QtGui.QCompleter(self.books) combo.addItem(u'')
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) for object in objects:
self.songBookComboBox.setCompleter(completer) row = combo.count()
combo.addItem(object.name)
cache.append(object.name)
combo.setItemData(row, QtCore.QVariant(object.id))
add_widget_completer(cache, combo)
def loadThemes(self, theme_list): def loadThemes(self, theme_list):
self.themeComboBox.clear() self.themeComboBox.clear()
@ -168,9 +157,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for theme in theme_list: for theme in theme_list:
self.themeComboBox.addItem(theme) self.themeComboBox.addItem(theme)
self.themes.append(theme) self.themes.append(theme)
completer = QtGui.QCompleter(self.themes) add_widget_completer(self.themes, self.themeComboBox)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.themeComboBox.setCompleter(completer)
def newSong(self): def newSong(self):
log.debug(u'New Song') log.debug(u'New Song')
@ -255,7 +242,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.songBookNumberEdit.setText(self.song.song_number) self.songBookNumberEdit.setText(self.song.song_number)
else: else:
self.songBookNumberEdit.setText(u'') self.songBookNumberEdit.setText(u'')
# lazy xml migration for now # lazy xml migration for now
self.verseListWidget.clear() self.verseListWidget.clear()
self.verseListWidget.setRowCount(0) self.verseListWidget.setRowCount(0)
@ -333,11 +319,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
author = Author.populate(first_name=text.rsplit(u' ', 1)[0], author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
last_name=text.rsplit(u' ', 1)[1], display_name=text) last_name=text.rsplit(u' ', 1)[1], display_name=text)
self.manager.save_object(author) self.manager.save_object(author)
author_item = QtGui.QListWidgetItem( self.__addAuthorToList(author)
unicode(author.display_name))
author_item.setData(QtCore.Qt.UserRole,
QtCore.QVariant(author.id))
self.authorsListView.addItem(author_item)
self.loadAuthors() self.loadAuthors()
self.authorsComboBox.setCurrentIndex(0) self.authorsComboBox.setCurrentIndex(0)
else: else:
@ -347,15 +329,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
author = self.manager.get_object(Author, item_id) author = self.manager.get_object(Author, item_id)
if self.authorsListView.findItems(unicode(author.display_name), if self.authorsListView.findItems(unicode(author.display_name),
QtCore.Qt.MatchExactly): QtCore.Qt.MatchExactly):
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=translate('SongsPlugin.EditSongForm',
'This author is already in the list.')) 'This author is already in the list.'))
else: else:
author_item = QtGui.QListWidgetItem(unicode( self.__addAuthorToList(author)
author.display_name))
author_item.setData(QtCore.Qt.UserRole,
QtCore.QVariant(author.id))
self.authorsListView.addItem(author_item)
self.authorsComboBox.setCurrentIndex(0) self.authorsComboBox.setCurrentIndex(0)
else: else:
QtGui.QMessageBox.warning(self, QtGui.QMessageBox.warning(self,
@ -365,6 +343,14 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
'or type in a new author and click the "Add Author to ' 'or type in a new author and click the "Add Author to '
'Song" button to add the new author.')) '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): def onAuthorsListViewPressed(self):
if self.authorsListView.count() > 1: if self.authorsListView.count() > 1:
self.authorRemoveButton.setEnabled(True) self.authorRemoveButton.setEnabled(True)
@ -400,7 +386,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
topic = self.manager.get_object(Topic, item_id) topic = self.manager.get_object(Topic, item_id)
if self.topicsListView.findItems(unicode(topic.name), if self.topicsListView.findItems(unicode(topic.name),
QtCore.Qt.MatchExactly): QtCore.Qt.MatchExactly):
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=translate('SongsPlugin.EditSongForm',
'This topic is already in the list.')) 'This topic is already in the list.'))
else: else:
@ -533,21 +519,21 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if not self.titleEdit.text(): if not self.titleEdit.text():
self.songTabWidget.setCurrentIndex(0) self.songTabWidget.setCurrentIndex(0)
self.titleEdit.setFocus() self.titleEdit.setFocus()
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=translate('SongsPlugin.EditSongForm',
'You need to type in a song title.')) 'You need to type in a song title.'))
return False return False
if self.verseListWidget.rowCount() == 0: if self.verseListWidget.rowCount() == 0:
self.songTabWidget.setCurrentIndex(0) self.songTabWidget.setCurrentIndex(0)
self.verseListWidget.setFocus() self.verseListWidget.setFocus()
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=translate('SongsPlugin.EditSongForm',
'You need to type in at least one verse.')) 'You need to type in at least one verse.'))
return False return False
if self.authorsListView.count() == 0: if self.authorsListView.count() == 0:
self.songTabWidget.setCurrentIndex(1) self.songTabWidget.setCurrentIndex(1)
self.authorsListView.setFocus() self.authorsListView.setFocus()
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=translate('SongsPlugin.EditSongForm',
'You need to have an author for this song.')) 'You need to have an author for this song.'))
return False return False
@ -575,7 +561,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
valid = verses.pop(0) valid = verses.pop(0)
for verse in verses: for verse in verses:
valid = valid + u', ' + verse valid = valid + u', ' + verse
criticalErrorMessageBox( critical_error_message_box(
message=unicode(translate('SongsPlugin.EditSongForm', message=unicode(translate('SongsPlugin.EditSongForm',
'The verse order is invalid. There is no verse ' 'The verse order is invalid. There is no verse '
'corresponding to %s. Valid entries are %s.')) % \ 'corresponding to %s. Valid entries are %s.')) % \
@ -648,29 +634,31 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
""" """
Free up autocompletion memory on dialog exit Free up autocompletion memory on dialog exit
""" """
log.debug (u'SongEditForm.clearCaches')
self.authors = [] self.authors = []
self.themes = [] self.themes = []
self.books = [] self.books = []
self.topics = [] self.topics = []
def closePressed(self): def reject(self):
""" """
Exit Dialog and do not save Exit Dialog and do not save
""" """
log.debug (u'SongEditForm.reject')
Receiver.send_message(u'songs_edit_clear') Receiver.send_message(u'songs_edit_clear')
self.clearCaches() self.clearCaches()
self.close() QtGui.QDialog.reject(self)
def accept(self): def accept(self):
""" """
Exit Dialog and save song if valid Exit Dialog and save song if valid
""" """
log.debug(u'accept') log.debug(u'SongEditForm.accept')
self.clearCaches() self.clearCaches()
if self._validate_song(): if self._validate_song():
self.saveSong() self.saveSong()
Receiver.send_message(u'songs_load_list') Receiver.send_message(u'songs_load_list')
self.close() QtGui.QDialog.accept(self)
def saveSong(self, preview=False): def saveSong(self, preview=False):
""" """

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate, SpellTextEdit from openlp.core.lib import build_icon, translate, SpellTextEdit
from openlp.core.lib.ui import create_save_cancel_button_box
from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib import VerseType
class Ui_EditVerseDialog(object): class Ui_EditVerseDialog(object):
@ -59,17 +60,9 @@ class Ui_EditVerseDialog(object):
self.verseTypeLayout.addWidget(self.insertButton) self.verseTypeLayout.addWidget(self.insertButton)
self.verseTypeLayout.addStretch() self.verseTypeLayout.addStretch()
self.dialogLayout.addLayout(self.verseTypeLayout) self.dialogLayout.addLayout(self.verseTypeLayout)
self.buttonBox = QtGui.QDialogButtonBox(editVerseDialog) self.dialogLayout.addWidget(
self.buttonBox.setOrientation(QtCore.Qt.Horizontal) create_save_cancel_button_box(editVerseDialog))
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(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) QtCore.QMetaObject.connectSlotsByName(editVerseDialog)
def retranslateUi(self, editVerseDialog): def retranslateUi(self, editVerseDialog):

View File

@ -29,7 +29,7 @@ import logging
from PyQt4 import QtCore, QtGui 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 openlp.plugins.songs.lib import VerseType, translate
from editversedialog import Ui_EditVerseDialog from editversedialog import Ui_EditVerseDialog
@ -168,7 +168,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
else: else:
value = self.getVerse()[0].split(u'\n')[1] value = self.getVerse()[0].split(u'\n')[1]
if len(value) == 0: if len(value) == 0:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.EditSongForm', message=translate('SongsPlugin.EditSongForm',
'You need to type some text in to the verse.')) 'You need to type some text in to the verse.'))
return False return False

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.lib.ui import create_save_cancel_button_box
class Ui_SongBookDialog(object): class Ui_SongBookDialog(object):
def setupUi(self, songBookDialog): def setupUi(self, songBookDialog):
@ -49,17 +50,10 @@ class Ui_SongBookDialog(object):
self.publisherLabel.setBuddy(self.publisherEdit) self.publisherLabel.setBuddy(self.publisherEdit)
self.bookLayout.addRow(self.publisherLabel, self.publisherEdit) self.bookLayout.addRow(self.publisherLabel, self.publisherEdit)
self.dialogLayout.addLayout(self.bookLayout) self.dialogLayout.addLayout(self.bookLayout)
self.buttonBox = QtGui.QDialogButtonBox(songBookDialog) self.dialogLayout.addWidget(
self.buttonBox.setStandardButtons( create_save_cancel_button_box(songBookDialog))
QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(songBookDialog) self.retranslateUi(songBookDialog)
songBookDialog.setMaximumHeight(songBookDialog.sizeHint().height()) 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) QtCore.QMetaObject.connectSlotsByName(songBookDialog)
def retranslateUi(self, songBookDialog): def retranslateUi(self, songBookDialog):

View File

@ -27,7 +27,7 @@
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.lib import translate 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 from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog
class SongBookForm(QtGui.QDialog, Ui_SongBookDialog): class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
@ -50,7 +50,7 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
def accept(self): def accept(self):
if not self.nameEdit.text(): if not self.nameEdit.text():
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongBookForm', message=translate('SongsPlugin.SongBookForm',
'You need to type in a name for the book.')) 'You need to type in a name for the book.'))
self.nameEdit.setFocus() self.nameEdit.setFocus()

View File

@ -32,7 +32,7 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsManager, translate 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.core.ui.wizard import OpenLPWizard
from openlp.plugins.songs.lib.importer import SongFormat from openlp.plugins.songs.lib.importer import SongFormat
@ -162,32 +162,34 @@ class SongImportForm(OpenLPWizard):
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.formatSpacer) self.formatSpacer)
self.sourceLayout.addLayout(self.formatLayout) self.sourceLayout.addLayout(self.formatLayout)
self.stackSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Expanding)
self.formatStack = QtGui.QStackedLayout() self.formatStack = QtGui.QStackedLayout()
self.formatStack.setObjectName(u'FormatStack') self.formatStack.setObjectName(u'FormatStack')
# OpenLP 2.0 # OpenLP 2.0
self.addSingleFileSelectItem(u'openLP2') self.addFileSelectItem(u'openLP2', single_select=True)
# openlp.org 1.x # openlp.org 1.x
self.addSingleFileSelectItem(u'openLP1', None, True) self.addFileSelectItem(u'openLP1', None, True, True)
# OpenLyrics # OpenLyrics
self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True) self.addFileSelectItem(u'openLyrics', u'OpenLyrics', True)
# Open Song # Open Song
self.addMultiFileSelectItem(u'openSong', u'OpenSong') self.addFileSelectItem(u'openSong', u'OpenSong')
# Words of Worship # Words of Worship
self.addMultiFileSelectItem(u'wordsOfWorship') self.addFileSelectItem(u'wordsOfWorship')
# CCLI File import # CCLI File import
self.addMultiFileSelectItem(u'ccli') self.addFileSelectItem(u'ccli')
# Songs of Fellowship # Songs of Fellowship
self.addMultiFileSelectItem(u'songsOfFellowship', None, True) self.addFileSelectItem(u'songsOfFellowship', None, True)
# Generic Document/Presentation import # Generic Document/Presentation import
self.addMultiFileSelectItem(u'generic', None, True) self.addFileSelectItem(u'generic', None, True)
# EasySlides # EasySlides
self.addSingleFileSelectItem(u'easiSlides') self.addFileSelectItem(u'easiSlides', single_select=True)
# EasyWorship # EasyWorship
self.addSingleFileSelectItem(u'ew') self.addFileSelectItem(u'ew', single_select=True)
# Words of Worship # Words of Worship
self.addMultiFileSelectItem(u'songBeamer') self.addFileSelectItem(u'songBeamer')
# Commented out for future use. # 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.sourceLayout.addLayout(self.formatStack)
self.addPage(self.sourcePage) self.addPage(self.sourcePage)
@ -318,16 +320,6 @@ class SongImportForm(OpenLPWizard):
self.openLP2FilenameLabel.minimumSizeHint().width()) self.openLP2FilenameLabel.minimumSizeHint().width())
self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
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): def validateCurrentPage(self):
""" """
@ -339,7 +331,7 @@ class SongImportForm(OpenLPWizard):
source_format = self.formatComboBox.currentIndex() source_format = self.formatComboBox.currentIndex()
if source_format == SongFormat.OpenLP2: if source_format == SongFormat.OpenLP2:
if self.openLP2FilenameEdit.text().isEmpty(): if self.openLP2FilenameEdit.text().isEmpty():
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No OpenLP 2.0 Song Database Selected'), 'No OpenLP 2.0 Song Database Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -349,7 +341,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.OpenLP1: elif source_format == SongFormat.OpenLP1:
if self.openLP1FilenameEdit.text().isEmpty(): if self.openLP1FilenameEdit.text().isEmpty():
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No openlp.org 1.x Song Database Selected'), 'No openlp.org 1.x Song Database Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -359,7 +351,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.OpenLyrics: elif source_format == SongFormat.OpenLyrics:
if self.openLyricsFileListWidget.count() == 0: if self.openLyricsFileListWidget.count() == 0:
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No OpenLyrics Files Selected'), 'No OpenLyrics Files Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -369,7 +361,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.OpenSong: elif source_format == SongFormat.OpenSong:
if self.openSongFileListWidget.count() == 0: if self.openSongFileListWidget.count() == 0:
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No OpenSong Files Selected'), 'No OpenSong Files Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -379,7 +371,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.WordsOfWorship: elif source_format == SongFormat.WordsOfWorship:
if self.wordsOfWorshipFileListWidget.count() == 0: if self.wordsOfWorshipFileListWidget.count() == 0:
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No Words of Worship Files Selected'), 'No Words of Worship Files Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -389,7 +381,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.CCLI: elif source_format == SongFormat.CCLI:
if self.ccliFileListWidget.count() == 0: if self.ccliFileListWidget.count() == 0:
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No CCLI Files Selected'), 'No CCLI Files Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -399,7 +391,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.SongsOfFellowship: elif source_format == SongFormat.SongsOfFellowship:
if self.songsOfFellowshipFileListWidget.count() == 0: if self.songsOfFellowshipFileListWidget.count() == 0:
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No Songs of Fellowship File Selected'), 'No Songs of Fellowship File Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -409,7 +401,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.Generic: elif source_format == SongFormat.Generic:
if self.genericFileListWidget.count() == 0: if self.genericFileListWidget.count() == 0:
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No Document/Presentation Selected'), 'No Document/Presentation Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -419,7 +411,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.EasiSlides: elif source_format == SongFormat.EasiSlides:
if self.easiSlidesFilenameEdit.text().isEmpty(): if self.easiSlidesFilenameEdit.text().isEmpty():
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No Easislides Songs file selected'), 'No Easislides Songs file selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -429,7 +421,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.EasyWorship: elif source_format == SongFormat.EasyWorship:
if self.ewFilenameEdit.text().isEmpty(): if self.ewFilenameEdit.text().isEmpty():
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No EasyWorship Song Database Selected'), 'No EasyWorship Song Database Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -439,7 +431,7 @@ class SongImportForm(OpenLPWizard):
return False return False
elif source_format == SongFormat.SongBeamer: elif source_format == SongFormat.SongBeamer:
if self.songBeamerFileListWidget.count() == 0: if self.songBeamerFileListWidget.count() == 0:
criticalErrorMessageBox( critical_error_message_box(
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'No SongBeamer File Selected'), 'No SongBeamer File Selected'),
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
@ -791,52 +783,8 @@ class SongImportForm(OpenLPWizard):
translate('SongsPlugin.SongImportForm', translate('SongsPlugin.SongImportForm',
'Your song import failed.')) 'Your song import failed.'))
def addSingleFileSelectItem(self, prefix, obj_prefix=None, def addFileSelectItem(self, prefix, obj_prefix=None, can_disable=False,
can_disable=False): single_select=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):
if not obj_prefix: if not obj_prefix:
obj_prefix = prefix obj_prefix = prefix
page = QtGui.QWidget() page = QtGui.QWidget()
@ -847,37 +795,53 @@ class SongImportForm(OpenLPWizard):
importWidget = page importWidget = page
importLayout = QtGui.QVBoxLayout(importWidget) importLayout = QtGui.QVBoxLayout(importWidget)
importLayout.setMargin(0) 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)
importLayout.addLayout(fileLayout)
importLayout.addSpacerItem(self.stackSpacer)
else: else:
importLayout.setObjectName(obj_prefix + u'Layout') fileListWidget = QtGui.QListWidget(importWidget)
fileListWidget = QtGui.QListWidget(importWidget) fileListWidget.setSelectionMode(
fileListWidget.setSelectionMode( QtGui.QAbstractItemView.ExtendedSelection)
QtGui.QAbstractItemView.ExtendedSelection) fileListWidget.setObjectName(obj_prefix + u'FileListWidget')
fileListWidget.setObjectName(obj_prefix + u'FileListWidget') importLayout.addWidget(fileListWidget)
importLayout.addWidget(fileListWidget) buttonLayout = QtGui.QHBoxLayout()
buttonLayout = QtGui.QHBoxLayout() buttonLayout.setObjectName(obj_prefix + u'ButtonLayout')
buttonLayout.setObjectName(obj_prefix + u'ButtonLayout') addButton = QtGui.QPushButton(importWidget)
addButton = QtGui.QPushButton(importWidget) addButton.setIcon(self.openIcon)
addButton.setIcon(self.openIcon) addButton.setObjectName(obj_prefix + u'AddButton')
addButton.setObjectName(obj_prefix + u'AddButton') buttonLayout.addWidget(addButton)
buttonLayout.addWidget(addButton) buttonLayout.addStretch()
buttonLayout.addStretch() removeButton = QtGui.QPushButton(importWidget)
removeButton = QtGui.QPushButton(importWidget) removeButton.setIcon(self.deleteIcon)
removeButton.setIcon(self.deleteIcon) removeButton.setObjectName(obj_prefix + u'RemoveButton')
removeButton.setObjectName(obj_prefix + u'RemoveButton') buttonLayout.addWidget(removeButton)
buttonLayout.addWidget(removeButton) importLayout.addLayout(buttonLayout)
importLayout.addLayout(buttonLayout)
self.formatStack.addWidget(page) self.formatStack.addWidget(page)
setattr(self, prefix + u'Page', page) setattr(self, prefix + u'Page', page)
setattr(self, prefix + u'FileListWidget', fileListWidget) if single_select:
setattr(self, prefix + u'ButtonLayout', buttonLayout) setattr(self, prefix + u'FilenameLabel', filenameLabel)
setattr(self, prefix + u'AddButton', addButton) setattr(self, prefix + u'FileLayout', fileLayout)
setattr(self, prefix + u'RemoveButton', removeButton) setattr(self, prefix + u'FilenameEdit', filenameEdit)
if can_disable: setattr(self, prefix + u'BrowseButton', browseButton)
setattr(self, prefix + u'ImportLayout', importLayout)
else: 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'') self.formatComboBox.addItem(u'')
def disablableWidget(self, page, prefix, obj_prefix): def disablableWidget(self, page, prefix, obj_prefix):
@ -895,6 +859,7 @@ class SongImportForm(OpenLPWizard):
disabledLabel.setWordWrap(True) disabledLabel.setWordWrap(True)
disabledLabel.setObjectName(obj_prefix + u'DisabledLabel') disabledLabel.setObjectName(obj_prefix + u'DisabledLabel')
disabledLayout.addWidget(disabledLabel) disabledLayout.addWidget(disabledLabel)
disabledLayout.addSpacerItem(self.stackSpacer)
layout.addWidget(disabledWidget) layout.addWidget(disabledWidget)
importWidget = QtGui.QWidget(page) importWidget = QtGui.QWidget(page)
importWidget.setObjectName(obj_prefix + u'ImportWidget') importWidget.setObjectName(obj_prefix + u'ImportWidget')

View File

@ -29,7 +29,7 @@ from PyQt4 import QtGui, QtCore
from sqlalchemy.sql import and_ from sqlalchemy.sql import and_
from openlp.core.lib import Receiver, translate 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.forms import AuthorsForm, TopicsForm, SongBookForm
from openlp.plugins.songs.lib.db import Author, Book, Topic, Song from openlp.plugins.songs.lib.db import Author, Book, Topic, Song
from songmaintenancedialog import Ui_SongMaintenanceDialog from songmaintenancedialog import Ui_SongMaintenanceDialog
@ -94,8 +94,8 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.typeListWidget.setFocus() self.typeListWidget.setFocus()
return QtGui.QDialog.exec_(self) return QtGui.QDialog.exec_(self)
def _getCurrentItemId(self, ListWidget): def _getCurrentItemId(self, listWidget):
item = ListWidget.currentItem() item = listWidget.currentItem()
if item: if item:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
return item_id return item_id
@ -108,14 +108,14 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
if item_id != -1: if item_id != -1:
item = self.manager.get_object(item_class, item_id) item = self.manager.get_object(item_class, item_id)
if item and len(item.songs) == 0: 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: parent=self, question=True) == QtGui.QMessageBox.Yes:
self.manager.delete_object(item_class, item.id) self.manager.delete_object(item_class, item.id)
reset_func() reset_func()
else: else:
criticalErrorMessageBox(dlg_title, err_text) critical_error_message_box(dlg_title, err_text)
else: else:
criticalErrorMessageBox(dlg_title, sel_text) critical_error_message_box(dlg_title, sel_text)
def resetAuthors(self): def resetAuthors(self):
""" """
@ -159,66 +159,43 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def checkAuthor(self, new_author, edit=False): def checkAuthor(self, new_author, edit=False):
""" """
Returns *False* if the given Author already exists, otherwise *True*. 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, authors = self.manager.get_all_objects(Author,
and_(Author.first_name == new_author.first_name, and_(Author.first_name == new_author.first_name,
Author.last_name == new_author.last_name, Author.last_name == new_author.last_name,
Author.display_name == new_author.display_name)) Author.display_name == new_author.display_name))
# Check if this author already exists. return self.__checkObject(authors, new_author, edit)
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
def checkTopic(self, new_topic, edit=False): def checkTopic(self, new_topic, edit=False):
""" """
Returns *False* if the given Topic already exists, otherwise *True*. 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, topics = self.manager.get_all_objects(Topic,
Topic.name == new_topic.name) Topic.name == new_topic.name)
if len(topics) > 0: return self.__checkObject(topics, new_topic, edit)
# 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
def checkBook(self, new_book, edit=False): def checkBook(self, new_book, edit=False):
""" """
Returns *False* if the given Topic already exists, otherwise *True*. 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, books = self.manager.get_all_objects(Book,
and_(Book.name == new_book.name, and_(Book.name == new_book.name,
Book.publisher == new_book.publisher)) Book.publisher == new_book.publisher))
if len(books) > 0: return self.__checkObject(books, new_book, edit)
# If we edit an existing Book, we need to make sure that we do
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. # not return False when nothing has changed.
if edit: if edit:
for book in books: for object in objects:
if book.id != new_book.id: if object.id != new_object.id:
return False return False
return True return True
else: else:
@ -237,11 +214,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
if self.manager.save_object(author): if self.manager.save_object(author):
self.resetAuthors() self.resetAuthors()
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not add your author.')) 'Could not add your author.'))
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'This author already exists.')) 'This author already exists.'))
@ -252,11 +229,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
if self.manager.save_object(topic): if self.manager.save_object(topic):
self.resetTopics() self.resetTopics()
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not add your topic.')) 'Could not add your topic.'))
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'This topic already exists.')) 'This topic already exists.'))
@ -268,11 +245,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
if self.manager.save_object(book): if self.manager.save_object(book):
self.resetBooks() self.resetBooks()
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not add your book.')) 'Could not add your book.'))
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'This book already exists.')) 'This book already exists.'))
@ -301,28 +278,24 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
self.resetAuthors() self.resetAuthors()
Receiver.send_message(u'songs_load_list') Receiver.send_message(u'songs_load_list')
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your changes.')) 'Could not save your changes.'))
elif criticalErrorMessageBox(message=unicode(translate( elif critical_error_message_box(message=unicode(translate(
'SongsPlugin.SongMaintenanceForm', 'The author %s already ' 'SongsPlugin.SongMaintenanceForm', 'The author %s already '
'exists. Would you like to make songs with author %s use ' 'exists. Would you like to make songs with author %s use '
'the existing author %s?')) % (author.display_name, 'the existing author %s?')) % (author.display_name,
temp_display_name, author.display_name), temp_display_name, author.display_name),
parent=self, question=True) == QtGui.QMessageBox.Yes: parent=self, question=True) == QtGui.QMessageBox.Yes:
Receiver.send_message(u'cursor_busy') self.__mergeObjects(author, self.mergeAuthors,
Receiver.send_message(u'openlp_process_events') self.resetAuthors)
self.mergeAuthors(author)
self.resetAuthors()
Receiver.send_message(u'songs_load_list')
Receiver.send_message(u'cursor_normal')
else: else:
# We restore the author's old first and last name as well as # We restore the author's old first and last name as well as
# his display name. # his display name.
author.first_name = temp_first_name author.first_name = temp_first_name
author.last_name = temp_last_name author.last_name = temp_last_name
author.display_name = temp_display_name author.display_name = temp_display_name
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your modified author, because the ' 'Could not save your modified author, because the '
'author already exists.')) 'author already exists.'))
@ -341,24 +314,20 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
if self.manager.save_object(topic): if self.manager.save_object(topic):
self.resetTopics() self.resetTopics()
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your changes.')) 'Could not save your changes.'))
elif criticalErrorMessageBox( elif critical_error_message_box(
message=unicode(translate('SongsPlugin.SongMaintenanceForm', message=unicode(translate('SongsPlugin.SongMaintenanceForm',
'The topic %s already exists. Would you like to make songs ' 'The topic %s already exists. Would you like to make songs '
'with topic %s use the existing topic %s?')) % (topic.name, 'with topic %s use the existing topic %s?')) % (topic.name,
temp_name, topic.name), temp_name, topic.name),
parent=self, question=True) == QtGui.QMessageBox.Yes: parent=self, question=True) == QtGui.QMessageBox.Yes:
Receiver.send_message(u'cursor_busy') self.__mergeObjects(topic, self.mergeTopics, self.resetTopics)
Receiver.send_message(u'openlp_process_events')
self.mergeTopics(topic)
self.resetTopics()
Receiver.send_message(u'cursor_normal')
else: else:
# We restore the topics's old name. # We restore the topics's old name.
topic.name = temp_name topic.name = temp_name
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your modified topic, because it ' 'Could not save your modified topic, because it '
'already exists.')) 'already exists.'))
@ -383,25 +352,31 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
if self.manager.save_object(book): if self.manager.save_object(book):
self.resetBooks() self.resetBooks()
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your changes.')) 'Could not save your changes.'))
elif criticalErrorMessageBox( elif critical_error_message_box(
message=unicode(translate('SongsPlugin.SongMaintenanceForm', message=unicode(translate('SongsPlugin.SongMaintenanceForm',
'The book %s already exists. Would you like to make songs ' 'The book %s already exists. Would you like to make songs '
'with book %s use the existing book %s?')) % (book.name, 'with book %s use the existing book %s?')) % (book.name,
temp_name, book.name), temp_name, book.name),
parent=self, question=True) == QtGui.QMessageBox.Yes: parent=self, question=True) == QtGui.QMessageBox.Yes:
Receiver.send_message(u'cursor_busy') self.__mergeObjects(book, self.mergeBooks, self.resetBooks)
Receiver.send_message(u'openlp_process_events')
self.mergeBooks(book)
self.resetBooks()
Receiver.send_message(u'cursor_normal')
else: else:
# We restore the book's old name and publisher. # We restore the book's old name and publisher.
book.name = temp_name book.name = temp_name
book.publisher = temp_publisher 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')
merge(dbObject)
reset()
Receiver.send_message(u'songs_load_list')
Receiver.send_message(u'cursor_normal')
def mergeAuthors(self, old_author): def mergeAuthors(self, old_author):
""" """
Merges two authors into one author. Merges two authors into one author.
@ -508,42 +483,32 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onAuthorsListRowChanged(self, row): def onAuthorsListRowChanged(self, row):
""" """
Called when the *authorsListWidget* current's row has changed. Called when the *authorsListWidget*'s current row has changed.
``row``
The current row. If there is no current row, the value is -1
""" """
if row == -1: self.__rowChange(row, self.authorsEditButton, self.authorsDeleteButton)
self.authorsDeleteButton.setEnabled(False)
self.authorsEditButton.setEnabled(False)
else:
self.authorsDeleteButton.setEnabled(True)
self.authorsEditButton.setEnabled(True)
def onTopicsListRowChanged(self, row): def onTopicsListRowChanged(self, row):
""" """
Called when the *booksListWidget* current's row has changed. Called when the *topicsListWidget*'s current row has changed.
``row``
The current row. If there is no current row, the value is -1.
""" """
if row == -1: self.__rowChange(row, self.topicsEditButton, self.topicsDeleteButton)
self.topicsDeleteButton.setEnabled(False)
self.topicsEditButton.setEnabled(False)
else:
self.topicsDeleteButton.setEnabled(True)
self.topicsEditButton.setEnabled(True)
def onBooksListRowChanged(self, row): 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`` ``row``
The current row. If there is no current row, the value is -1. The current row. If there is no current row, the value is -1.
""" """
if row == -1: if row == -1:
self.booksDeleteButton.setEnabled(False) deleteButton.setEnabled(False)
self.booksEditButton.setEnabled(False) editButton.setEnabled(False)
else: else:
self.booksDeleteButton.setEnabled(True) deleteButton.setEnabled(True)
self.booksEditButton.setEnabled(True) editButton.setEnabled(True)

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.lib.ui import create_save_cancel_button_box
class Ui_TopicsDialog(object): class Ui_TopicsDialog(object):
def setupUi(self, topicsDialog): def setupUi(self, topicsDialog):
@ -43,17 +44,10 @@ class Ui_TopicsDialog(object):
self.nameLabel.setBuddy(self.nameEdit) self.nameLabel.setBuddy(self.nameEdit)
self.nameLayout.addRow(self.nameLabel, self.nameEdit) self.nameLayout.addRow(self.nameLabel, self.nameEdit)
self.dialogLayout.addLayout(self.nameLayout) self.dialogLayout.addLayout(self.nameLayout)
self.buttonBox = QtGui.QDialogButtonBox(topicsDialog) self.dialogLayout.addWidget(
self.buttonBox.setStandardButtons( create_save_cancel_button_box(topicsDialog))
QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(topicsDialog) self.retranslateUi(topicsDialog)
topicsDialog.setMaximumHeight(topicsDialog.sizeHint().height()) 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) QtCore.QMetaObject.connectSlotsByName(topicsDialog)
def retranslateUi(self, topicsDialog): def retranslateUi(self, topicsDialog):

View File

@ -27,7 +27,7 @@
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.lib import translate 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 from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog): class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
@ -49,7 +49,8 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
def accept(self): def accept(self):
if not self.nameEdit.text(): 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.')) 'You need to type in a topic name.'))
self.nameEdit.setFocus() self.nameEdit.setFocus()
return False return False

View File

@ -39,6 +39,7 @@ class Author(BaseModel):
""" """
pass pass
class Book(BaseModel): class Book(BaseModel):
""" """
Book model Book model
@ -47,30 +48,115 @@ class Book(BaseModel):
return u'<Book id="%s" name="%s" publisher="%s" />' % ( return u'<Book id="%s" name="%s" publisher="%s" />' % (
str(self.id), self.name, self.publisher) str(self.id), self.name, self.publisher)
class MediaFile(BaseModel): class MediaFile(BaseModel):
""" """
MediaFile model MediaFile model
""" """
pass pass
class Song(BaseModel): class Song(BaseModel):
""" """
Song model Song model
""" """
pass pass
class Topic(BaseModel): class Topic(BaseModel):
""" """
Topic model Topic model
""" """
pass pass
def init_schema(url): 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`` ``url``
The database to setup 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) session, metadata = init_db(url)

View File

@ -133,29 +133,37 @@ class EasiSlidesImport(SongImport):
pass pass
def _add_copyright(self, song): 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: try:
copyright.append(unicode(song.Copyright).strip()) copyright_list.append(unicode(element).strip())
except UnicodeDecodeError: except UnicodeDecodeError:
log.exception(u'Unicode decode error while decoding Copyright') log.exception(u'Unicode error decoding %s' % element)
self._success = False self._success = False
except AttributeError: except AttributeError:
pass 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): def _parse_and_add_lyrics(self, song):
try: try:

View File

@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui
from sqlalchemy.sql import or_ from sqlalchemy.sql import or_
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \
ItemCapabilities, translate, check_item_selected ItemCapabilities, translate, check_item_selected, PluginStatus
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm SongImportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML from openlp.plugins.songs.lib import OpenLyrics, SongXML
@ -95,8 +95,6 @@ class SongMediaItem(MediaManagerItem):
self.searchLayout.addLayout(self.searchButtonLayout) self.searchLayout.addLayout(self.searchButtonLayout)
self.pageLayout.addWidget(self.searchWidget) self.pageLayout.addWidget(self.searchWidget)
# Signals and slots # Signals and slots
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'plugin_list_refresh'), self.onSearchTextButtonClick)
QtCore.QObject.connect(self.searchTextEdit, QtCore.QObject.connect(self.searchTextEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick) QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick)
QtCore.QObject.connect(self.searchTextButton, QtCore.QObject.connect(self.searchTextButton,
@ -337,16 +335,7 @@ class SongMediaItem(MediaManagerItem):
author_list = u'' author_list = u''
author_audit = [] author_audit = []
ccli = u'' ccli = u''
if item is None: item_id = self._getIdOfItemToGenerate(item, self.remoteSong)
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]
service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)
@ -407,45 +396,46 @@ class SongMediaItem(MediaManagerItem):
Triggered by a song being loaded by the service item Triggered by a song being loaded by the service item
""" """
log.debug(u'serviceLoad') log.debug(u'serviceLoad')
if item.data_string: if self.plugin.status != PluginStatus.Active or not item.data_string:
search_results = self.parent.manager.get_all_objects(Song, return
Song.search_title == re.compile(r'\W+', re.UNICODE).sub(u' ', search_results = self.parent.manager.get_all_objects(Song,
item.data_string[u'title'].split(u'@')[0].lower()).strip(), Song.search_title == re.compile(r'\W+', re.UNICODE).sub(u' ',
Song.search_title.asc()) item.data_string[u'title'].split(u'@')[0].lower()).strip(),
author_list = item.data_string[u'authors'].split(u', ') Song.search_title.asc())
# The service item always has an author (at least it has u'' as author_list = item.data_string[u'authors'].split(u', ')
# author). However, songs saved in the database do not have to have # The service item always has an author (at least it has u'' as
# an author. # author). However, songs saved in the database do not have to have
if u'' in author_list: # an author.
author_list.remove(u'') if u'' in author_list:
editId = 0 author_list.remove(u'')
add_song = True editId = 0
if search_results: add_song = True
for song in search_results: if search_results:
same_authors = True for song in search_results:
# If the author counts are different, we do not have to do same_authors = True
# any further checking. This is also important when a song # If the author counts are different, we do not have to do any
# does not have any author (because we can not loop over an # further checking. This is also important when a song does not
# empty list). # have any author (because we can not loop over an empty list).
if len(song.authors) == len(author_list): if len(song.authors) == len(author_list):
for author in song.authors: for author in song.authors:
if author.display_name not in author_list: if author.display_name not in author_list:
same_authors = False same_authors = False
else: else:
same_authors = False same_authors = False
# All authors are the same, so we can stop here and the song # All authors are the same, so we can stop here and the song
# does not have to be saved. # does not have to be saved.
if same_authors: if same_authors:
add_song = False add_song = False
editId = song.id editId = song.id
break break
if add_song: if add_song:
if self.addSongFromService: if self.addSongFromService:
editId = self.openLyrics.xml_to_song(item.xml_version) editId = self.openLyrics.xml_to_song(item.xml_version)
# Update service with correct song id. self.onSearchTextButtonClick()
if editId: # Update service with correct song id.
Receiver.send_message(u'service_item_update', if editId:
u'%s:%s' % (editId, item._uuid)) Receiver.send_message(u'service_item_update',
u'%s:%s' % (editId, item._uuid))
def collateSongTitles(self, song_1, song_2): def collateSongTitles(self, song_1, song_2):
""" """

View File

@ -13,82 +13,128 @@
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Dialog</string>
</property> </property>
<layout class="QVBoxLayout" name="exceptionLayout"> <widget class="QPlainTextEdit" name="exceptionTextEdit">
<property name="spacing"> <property name="geometry">
<number>8</number> <rect>
<x>8</x>
<y>194</y>
<width>564</width>
<height>171</height>
</rect>
</property> </property>
<property name="margin"> <property name="readOnly">
<number>8</number> <bool>true</bool>
</property> </property>
<item> <property name="backgroundVisible">
<layout class="QHBoxLayout" name="messageLayout"> <bool>false</bool>
<property name="spacing"> </property>
<number>0</number> </widget>
</property> <widget class="QDialogButtonBox" name="exceptionButtonBox">
<property name="leftMargin"> <property name="geometry">
<number>0</number> <rect>
</property> <x>8</x>
<property name="rightMargin"> <y>373</y>
<number>0</number> <width>83</width>
</property> <height>26</height>
<item> </rect>
<widget class="QLabel" name="bugLabel"> </property>
<property name="minimumSize"> <property name="orientation">
<size> <enum>Qt::Horizontal</enum>
<width>64</width> </property>
<height>64</height> <property name="standardButtons">
</size> <set>QDialogButtonBox::Close</set>
</property> </property>
<property name="maximumSize"> </widget>
<size> <widget class="QPlainTextEdit" name="discriptionplainTextEdit">
<width>64</width> <property name="geometry">
<height>64</height> <rect>
</size> <x>8</x>
</property> <y>103</y>
<property name="text"> <width>561</width>
<string/> <height>71</height>
</property> </rect>
<property name="pixmap"> </property>
<pixmap resource="../images/openlp-2.qrc">:/graphics/exception.png</pixmap> <property name="sizePolicy">
</property> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<property name="alignment"> <horstretch>0</horstretch>
<set>Qt::AlignCenter</set> <verstretch>0</verstretch>
</property> </sizepolicy>
</widget> </property>
</item> </widget>
<item> <widget class="QLabel" name="characterCount">
<widget class="QLabel" name="messageLabel"> <property name="geometry">
<property name="text"> <rect>
<string>Oops! OpenLP hit a problem, and couldn't recover. The text in the box below contains information that might be helpful to the OpenLP developers, so please e-mail it to bugs@openlp.org, along with a detailed description of what you were doing when the problem occurred.</string> <x>10</x>
</property> <y>170</y>
<property name="wordWrap"> <width>301</width>
<bool>true</bool> <height>17</height>
</property> </rect>
</widget> </property>
</item> <property name="text">
</layout> <string>TextLabel</string>
</item> </property>
<item> </widget>
<widget class="QPlainTextEdit" name="exceptionTextEdit"> <widget class="QLabel" name="whatyouweredoinglabel">
<property name="readOnly"> <property name="geometry">
<bool>true</bool> <rect>
</property> <x>10</x>
<property name="backgroundVisible"> <y>80</y>
<bool>false</bool> <width>59</width>
</property> <height>17</height>
</widget> </rect>
</item> </property>
<item> <property name="text">
<widget class="QDialogButtonBox" name="exceptionButtonBox"> <string>TextLabel</string>
<property name="orientation"> </property>
<enum>Qt::Horizontal</enum> </widget>
</property> <widget class="QWidget" name="">
<property name="standardButtons"> <layout class="QHBoxLayout" name="messageLayout">
<set>QDialogButtonBox::Close</set> <property name="spacing">
</property> <number>0</number>
</widget> </property>
</item> <property name="leftMargin">
</layout> <number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="bugLabel">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images/openlp-2.qrc">:/graphics/exception.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="messageLabel">
<property name="text">
<string>Oops! OpenLP hit a problem, and couldn't recover. The text in the box below contains information that might be helpful to the OpenLP developers, so please e-mail it to bugs@openlp.org, along with a detailed description of what you were doing when the problem occurred.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
<resources> <resources>
<include location="../images/openlp-2.qrc"/> <include location="../images/openlp-2.qrc"/>

View File

@ -83,6 +83,58 @@ Root: HKCU; SubKey: Software\OpenLP\OpenLP\custom; ValueType: dword; ValueName:
Root: HKCU; SubKey: Software\OpenLP\OpenLP\images; ValueType: dword; ValueName: status; ValueData: $00000001 Root: HKCU; SubKey: Software\OpenLP\OpenLP\images; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\media; ValueType: dword; ValueName: status; ValueData: $00000001 Root: HKCU; SubKey: Software\OpenLP\OpenLP\media; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\presentations; ValueType: dword; ValueName: status; ValueData: $00000001 Root: HKCU; SubKey: Software\OpenLP\OpenLP\presentations; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\remotes; ValueType: dword; ValueName: status; ValueData: $00000001 Root: HKCU; SubKey: Software\OpenLP\OpenLP\remotes; ValueType: dword; ValueName: status; ValueData: $00000000
Root: HKCU; SubKey: Software\OpenLP\OpenLP\songs; ValueType: dword; ValueName: status; ValueData: $00000001 Root: HKCU; SubKey: Software\OpenLP\OpenLP\songs; ValueType: dword; ValueName: status; ValueData: $00000001
Root: HKCU; SubKey: Software\OpenLP\OpenLP\songusage; ValueType: dword; ValueName: status; ValueData: $00000001 Root: HKCU; SubKey: Software\OpenLP\OpenLP\songusage; ValueType: dword; ValueName: status; ValueData: $00000001
[Code]
function GetUninstallString(): String;
var
sUnInstPath: String;
sUnInstallString: String;
begin
sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
sUnInstallString := '';
if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
Result := sUnInstallString;
end;
function IsUpgrade(): Boolean;
begin
Result := (GetUninstallString() <> '');
end;
// Return Values:
// 1 - uninstall string is empty
// 2 - error executing the UnInstallString
// 3 - successfully executed the UnInstallString
function UnInstallOldVersion(): Integer;
var
sUnInstallString: String;
iResultCode: Integer;
begin
Result := 0;
sUnInstallString := GetUninstallString();
if sUnInstallString <> '' then
begin
sUnInstallString := RemoveQuotes(sUnInstallString);
if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
Result := 3
else
Result := 2;
end
else
Result := 1;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if (CurStep=ssInstall) then
begin
if (IsUpgrade()) then
begin
UnInstallOldVersion();
end;
end;
end;

Binary file not shown.

View File

@ -1,308 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 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 #
###############################################################################
import sys
import os
import sqlite
import sqlite3
from optparse import OptionParser
from traceback import format_tb as get_traceback
# Some global options to be used throughout the import process
verbose = False
debug = False
old_cursor = None
new_cursor = None
# SQL create statments
create_statements = [
(u'table "book"', u"""CREATE TABLE book (
id INTEGER NOT NULL,
testament_id INTEGER,
name VARCHAR(30),
abbreviation VARCHAR(5),
PRIMARY KEY (id),
FOREIGN KEY(testament_id) REFERENCES testament (id)
)"""),
(u'table "metadata"', u"""CREATE TABLE metadata (
"key" VARCHAR(255) NOT NULL,
value VARCHAR(255),
PRIMARY KEY ("key")
)"""),
(u'table "testament"', u"""CREATE TABLE testament (
id INTEGER NOT NULL,
name VARCHAR(30),
PRIMARY KEY (id)
)"""),
(u'table "verse"', u"""CREATE TABLE verse (
id INTEGER NOT NULL,
book_id INTEGER,
chapter INTEGER,
verse INTEGER,
text TEXT,
PRIMARY KEY (id),
FOREIGN KEY(book_id) REFERENCES book (id)
)"""),
(u'index "idx_abbrev"',
u"""CREATE INDEX idx_abbrev ON book (abbreviation, id)"""),
(u'index "idx_chapter_verse_book',
u"""CREATE INDEX idx_chapter_verse_book ON verse (chapter, verse, book_id, id)"""),
(u'index "idx_chapter_verse_text"',
u"""CREATE INDEX idx_chapter_verse_text ON verse (text, verse, book_id, id)"""),
(u'index "idx_name"',
u"""CREATE INDEX idx_name ON book (name, id)""")
]
def display_sql(sql, params):
prepared_params = []
for param in params:
if isinstance(param, basestring):
prepared_params.append(u'"%s"' % param)
elif isinstance(param, (int, long)):
prepared_params.append(u'%d' % param)
elif isinstance(param, (float, complex)):
prepared_params.append(u'%f' % param)
else:
prepared_params.append(u'"%s"' % str(param))
for prepared_param in prepared_params:
sql = sql.replace(u'?', prepared_param, 1)
return sql
def create_database():
global new_cursor, create_statements
if debug or verbose:
print 'Creating new database:'
else:
print 'Creating new database...',
for statement_type, sql_create in create_statements:
if debug:
print '... ', sql_create.replace('\n', ' ').replace(' ', ' ')
elif verbose:
print '... creating %s...' % statement_type,
new_cursor.execute(sql_create)
if verbose and not debug:
print 'done.'
if not verbose and not debug:
print 'done.'
def import_bible():
global old_cursor, new_cursor, debug, verbose
if debug or verbose:
print 'Importing metadata:'
else:
print 'Importing metadata...',
if debug:
print '... SELECT "key", "value" FROM metadata'
elif verbose:
print '... fetching metadata from old database...',
old_cursor.execute(u'SELECT "key", "value" FROM metadata')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
for row in rows:
key = unicode(row[0], u'cp1252')
value = unicode(row[1], u'cp1252')
if key == u'Permission':
key = u'Permissions'
sql_insert = u'INSERT INTO metadata '\
'("key", "value") '\
'VALUES (?, ?)'
sql_params = (key, value)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % key
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing testaments:'
else:
print 'Importing testaments...',
if debug:
print '... SELECT id, name FROM testament'
elif verbose:
print '... fetching testaments from old database...',
old_cursor.execute(u'SELECT id, name FROM testament')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
for row in rows:
id = int(row[0])
name = unicode(row[1], u'cp1252')
sql_insert = u'INSERT INTO testament '\
'(id, name) '\
'VALUES (?, ?)'
sql_params = (id, name)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % name
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing books:'
else:
print 'Importing books...',
if debug:
print '... SELECT id, testament_id, name, abbreviation FROM book'
elif verbose:
print '... fetching books from old database...',
old_cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
book_map = {}
for row in rows:
testament_id = int(row[1])
name = unicode(row[2], u'cp1252')
abbreviation = unicode(row[3], u'cp1252')
sql_insert = u'INSERT INTO book '\
'(id, testament_id, name, abbreviation) '\
'VALUES (NULL, ?, ?, ?)'
sql_params = (testament_id, name, abbreviation)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % name
new_cursor.execute(sql_insert, sql_params)
book_map[row[0]] = new_cursor.lastrowid
if debug:
print ' >>> (old) books.id =', row[0], ' (new) books.id =', book_map[row[0]]
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing verses:'
else:
print 'Importing verses...',
if debug:
print '... SELECT id, book_id, chapter, verse, text || \'\' AS text FROM verse...',
elif verbose:
print '... fetching verses from old database...',
old_cursor.execute(u'SELECT id, book_id, chapter, verse, text || \'\' AS text FROM verse')
rows = old_cursor.fetchall()
if debug or verbose:
print 'done.'
for row in rows:
book_id = int(row[1])
chapter = int(row[2])
verse = int(row[3])
text = unicode(row[4], u'cp1252')
sql_insert = u'INSERT INTO verse '\
'(id, book_id, chapter, verse, text) '\
'VALUES (NULL, ?, ?, ?, ?)'
sql_params = (book_map[book_id], chapter, verse, text)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s..."' % text[:17]
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
def main(old_db, new_db):
global old_cursor, new_cursor, debug
old_connection = None
new_connection = None
try:
old_connection = sqlite.connect(old_db)
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem connecting to the old database:', errormsg
return 1
try:
new_connection = sqlite3.connect(new_db)
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem creating the new database:', errormsg
return 1
old_cursor = old_connection.cursor()
new_cursor = new_connection.cursor()
try:
create_database()
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem creating the database:', errormsg
return 1
try:
import_bible()
new_connection.commit()
except:
new_connection.rollback()
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem importing songs:', errormsg
return 1
print 'Import complete.'
if __name__ == u'__main__':
option_parser = OptionParser(usage='Usage: %prog [options] OLDDATABASE NEWDATABASE')
option_parser.add_option('-o', '--overwrite', dest='overwrite', default=False,
action=u'store_true', help='Overwrite database file if it already exists.')
option_parser.add_option('-v', '--verbose', dest='verbose', default=False,
action=u'store_true', help='Outputs additional progress data.')
option_parser.add_option('-d', '--debug', dest='debug', default=False,
action=u'store_true', help='Outputs raw SQL statements (overrides verbose).')
options, arguments = option_parser.parse_args()
if len(arguments) < 2:
if len(arguments) == 0:
option_parser.error('Please specify an old database and a new database.')
else:
option_parser.error('Please specify a new database.')
old_db = os.path.abspath(arguments[0])
new_db = os.path.abspath(arguments[1])
if not os.path.isfile(old_db):
option_parser.error('Old database file ("%s") is not a file.' % old_db)
if not os.path.exists(old_db):
option_parser.error('Old database file ("%s") does not exist.' % old_db)
if os.path.exists(new_db):
if not options.overwrite:
option_parser.error('New database file ("%s") exists. If you want to overwrite it, specify the --overwrite option.' % new_db)
else:
if not os.path.isfile(new_db):
option_parser.error('New database file ("%s") is not a file.' % new_db)
os.unlink(new_db)
verbose = options.verbose
debug = options.debug
main(old_db, new_db)

View File

@ -1,323 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 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 #
###############################################################################
import sys
import os
import sqlite
import sqlite3
import re
from optparse import OptionParser
from traceback import format_tb as get_traceback
# Some global options to be used throughout the import process
dirty_chars = re.compile(r'\W ', re.UNICODE)
verbose = False
debug = False
old_cursor = None
new_cursor = None
# SQL create statments
create_statements = [
(u'table "authors"', u"""CREATE TABLE authors (
id INTEGER NOT NULL,
first_name VARCHAR(128),
last_name VARCHAR(128),
display_name VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
)"""),
(u'table "song_books"', u"""CREATE TABLE song_books (
id INTEGER NOT NULL,
name VARCHAR(128) NOT NULL,
publisher VARCHAR(128),
PRIMARY KEY (id)
)"""),
(u'table "songs"', u"""CREATE TABLE songs (
id INTEGER NOT NULL,
song_book_id INTEGER,
title VARCHAR(255) NOT NULL,
alternate_title VARCHAR(255),
lyrics TEXT NOT NULL,
verse_order VARCHAR(128),
copyright VARCHAR(255),
comments TEXT,
ccli_number VARCHAR(64),
song_number VARCHAR(64),
theme_name VARCHAR(128),
search_title VARCHAR(255) NOT NULL,
search_lyrics TEXT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(song_book_id) REFERENCES song_books (id)
)"""),
(u'table "topics"', u"""CREATE TABLE topics (
id INTEGER NOT NULL,
name VARCHAR(128) NOT NULL,
PRIMARY KEY (id)
)"""),
(u'index "ix_songs_search_lyrics"',
u"""CREATE INDEX ix_songs_search_lyrics ON songs (search_lyrics)"""),
(u'index "ix_songs_search_title',
u"""CREATE INDEX ix_songs_search_title ON songs (search_title)"""),
(u'table "authors_songs"', u"""CREATE TABLE authors_songs (
author_id INTEGER NOT NULL,
song_id INTEGER NOT NULL,
PRIMARY KEY (author_id, song_id),
FOREIGN KEY(author_id) REFERENCES authors (id),
FOREIGN KEY(song_id) REFERENCES songs (id)
)"""),
(u'table "songs_topics"', u"""CREATE TABLE songs_topics (
song_id INTEGER NOT NULL,
topic_id INTEGER NOT NULL,
PRIMARY KEY (song_id, topic_id),
FOREIGN KEY(song_id) REFERENCES songs (id),
FOREIGN KEY(topic_id) REFERENCES topics (id)
)""")
]
def prepare_string(dirty):
return dirty_chars.sub(u'', dirty.replace(u'\r\n', u' ').replace(u'\n', u' '))
def display_sql(sql, params):
prepared_params = []
for param in params:
if isinstance(param, basestring):
prepared_params.append(u'"%s"' % param)
elif isinstance(param, (int, long)):
prepared_params.append(u'%d' % param)
elif isinstance(param, (float, complex)):
prepared_params.append(u'%f' % param)
else:
prepared_params.append(u'"%s"' % str(param))
for prepared_param in prepared_params:
sql = sql.replace(u'?', prepared_param, 1)
return sql
def create_database():
global new_cursor, create_statements
if debug or verbose:
print 'Creating new database:'
else:
print 'Creating new database...',
for statement_type, sql_create in create_statements:
if debug:
print '... ', sql_create.replace('\n', ' ').replace(' ', ' ')
elif verbose:
print '... creating %s...' % statement_type,
new_cursor.execute(sql_create)
if verbose and not debug:
print 'done.'
if not verbose and not debug:
print 'done.'
def import_songs():
global old_cursor, new_cursor, debug, verbose
if debug or verbose:
print 'Importing authors:'
else:
print 'Importing authors...',
if debug:
print '... SELECT authorid AS id, authorname AS displayname FROM authors'
elif verbose:
print '... fetching authors from old database...',
old_cursor.execute(u'SELECT authorid AS id, authorname AS displayname FROM authors')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
author_map = {}
for row in rows:
display_name = unicode(row[1], u'cp1252')
names = display_name.split(u' ')
first_name = names[0]
last_name = u' '.join(names[1:])
if last_name is None:
last_name = u''
sql_insert = u'INSERT INTO authors '\
'(id, first_name, last_name, display_name) '\
'VALUES (NULL, ?, ?, ?)'
sql_params = (first_name, last_name, display_name)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % display_name
new_cursor.execute(sql_insert, sql_params)
author_map[row[0]] = new_cursor.lastrowid
if debug:
print ' >>> authors.authorid =', row[0], 'authors.id =', author_map[row[0]]
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing songs:'
else:
print 'Importing songs...',
if debug:
print '... SELECT songid AS id, songtitle AS title, lyrics || \'\' AS lyrics, copyrightinfo AS copyright FROM songs...',
elif verbose:
print '... fetching songs from old database...',
old_cursor.execute(u'SELECT songid AS id, songtitle AS title, lyrics || \'\' AS lyrics, copyrightinfo AS copyright FROM songs')
rows = old_cursor.fetchall()
if debug or verbose:
print 'done.'
song_map = {}
xml_lyrics_template = u'<?xml version="1.0" encoding="utf-8"?><song version="1.0"><lyrics language="en">%s</lyrics></song>'
xml_verse_template = u'<verse label="%d" type="Verse"><![CDATA[%s]]></verse>'
for row in rows:
clean_title = unicode(row[1], u'cp1252')
clean_lyrics = unicode(row[2], u'cp1252').replace(u'\r\n', u'\n')
clean_copyright = unicode(row[3], u'cp1252')
verse_order = u''
text_lyrics = clean_lyrics.split(u'\n\n')
xml_verse = u''
verses = []
for line, verse in enumerate(text_lyrics):
if not verse:
continue
xml_verse += (xml_verse_template % (line + 1, verse))
verses.append(u'V%d' % (line + 1))
verse_order = u' '.join(verses)
xml_lyrics = xml_lyrics_template % xml_verse
search_title = prepare_string(clean_title)
search_lyrics = prepare_string(clean_lyrics)
sql_insert = u'INSERT INTO songs '\
'(id, song_book_id, title, lyrics, verse_order, copyright, search_title, search_lyrics) '\
'VALUES (NULL, 0, ?, ?, ?, ?, ?, ?)'
sql_params = (clean_title, xml_lyrics, verse_order, clean_copyright, search_title, search_lyrics)
if debug:
print '...', display_sql(sql_insert, (sql_params[0], u'%s...' % clean_lyrics[:7], sql_params[2], sql_params[3], sql_params[4], u'%s...' % search_lyrics[:7]))
elif verbose:
print '... importing "%s"' % clean_title
new_cursor.execute(sql_insert, sql_params)
song_map[row[0]] = new_cursor.lastrowid
if debug:
print ' >>> songs.songid =', row[0], 'songs.id =', song_map[row[0]]
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing song-to-author mapping:'
else:
print 'Importing song-to-author mapping...',
if debug:
print '... SELECT authorid AS author_id, songid AS song_id FROM songauthors'
elif verbose:
print '... fetching song-to-author mapping from old database...',
old_cursor.execute(u'SELECT authorid AS author_id, songid AS song_id FROM songauthors')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
for row in rows:
sql_insert = u'INSERT INTO authors_songs '\
'(author_id, song_id) '\
'VALUES (?, ?)'
sql_params = (author_map[row[0]], song_map[row[1]])
if debug:
print '... ', display_sql(sql_insert, sql_params)
elif verbose:
print '... Author %d (was %d) => Song %d (was %d)'\
% (int(row[0]), author_map[row[0]],
int(row[1]), song_map[row[1]])
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
def main(old_db, new_db):
global old_cursor, new_cursor, debug
old_connection = None
new_connection = None
try:
old_connection = sqlite.connect(old_db)
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem connecting to the old database:', errormsg
return 1
try:
new_connection = sqlite3.connect(new_db)
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem creating the new database:', errormsg
return 1
old_cursor = old_connection.cursor()
new_cursor = new_connection.cursor()
try:
create_database()
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem creating the database:', errormsg
return 1
try:
import_songs()
new_connection.commit()
except:
new_connection.rollback()
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem importing songs:', errormsg
return 1
print 'Import complete.'
if __name__ == u'__main__':
option_parser = OptionParser(usage='Usage: %prog [options] OLDDATABASE NEWDATABASE')
option_parser.add_option('-o', '--overwrite', dest='overwrite', default=False,
action=u'store_true', help='Overwrite database file if it already exists.')
option_parser.add_option('-v', '--verbose', dest='verbose', default=False,
action=u'store_true', help='Outputs additional progress data.')
option_parser.add_option('-d', '--debug', dest='debug', default=False,
action=u'store_true', help='Outputs raw SQL statements (overrides verbose).')
options, arguments = option_parser.parse_args()
if len(arguments) < 2:
if len(arguments) == 0:
option_parser.error('Please specify an old database and a new database.')
else:
option_parser.error('Please specify a new database.')
old_db = os.path.abspath(arguments[0])
new_db = os.path.abspath(arguments[1])
if not os.path.isfile(old_db):
option_parser.error('Old database file ("%s") is not a file.' % old_db)
if not os.path.exists(old_db):
option_parser.error('Old database file ("%s") does not exist.' % old_db)
if os.path.exists(new_db):
if not options.overwrite:
option_parser.error('New database file ("%s") exists. If you want to overwrite it, specify the --overwrite option.' % new_db)
else:
if not os.path.isfile(new_db):
option_parser.error('New database file ("%s") is not a file.' % new_db)
os.unlink(new_db)
verbose = options.verbose
debug = options.debug
main(old_db, new_db)

View File

@ -69,8 +69,7 @@ OpenLP (previously openlp.org) is free church presentation software, or lyrics p
url='http://openlp.org/', url='http://openlp.org/',
license='GNU General Public License', license='GNU General Public License',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
scripts=['openlp.pyw', 'scripts/openlp-1to2-converter.py', scripts=['openlp.pyw', 'scripts/openlp-remoteclient.py'],
'scripts/bible-1to2-converter.py','scripts/openlp-remoteclient.py'],
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
install_requires=[ install_requires=[