This commit is contained in:
rimach 2011-02-09 18:43:02 +01:00
commit 06073d2b5e
90 changed files with 2551 additions and 2618 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
"""
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
try:
# If bzrlib is availble, use it
@ -216,6 +216,7 @@ class OpenLP(QtGui.QApplication):
Sets the Busy Cursor for the Application
"""
self.setOverrideCursor(QtCore.Qt.BusyCursor)
self.processEvents()
def setNormalCursor(self):
"""

View File

@ -86,10 +86,10 @@ class BaseModel(object):
"""
Creates an instance of a class and populates it, returning the instance
"""
me = cls()
instance = cls()
for key in kwargs:
me.__setattr__(key, kwargs[key])
return me
instance.__setattr__(key, kwargs[key])
return instance
class Manager(object):
"""

View File

@ -60,8 +60,8 @@ class DisplayTags(object):
DisplayTags.html_expands.append(tag)
@staticmethod
def remove_html_tag(id):
def remove_html_tag(tag_id):
"""
Removes amd individual html_expands list.
Removes an individual html_expands tag.
"""
DisplayTags.html_expands.pop(id)
DisplayTags.html_expands.pop(tag_id)

View File

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

View File

@ -61,10 +61,10 @@ class Image(object):
image = None
image_bytes = None
class ImageManager(QtCore.QObject):
"""
Image Manager handles the conversion and sizing of images.
"""
log.info(u'Image Manager loaded')

View File

@ -103,7 +103,6 @@ class MediaManagerItem(QtGui.QWidget):
self.icon = build_icon(icon)
self.toolbar = None
self.remoteTriggered = None
self.serviceItemIconName = None
self.singleServiceItem = True
self.pageLayout = QtGui.QVBoxLayout(self)
self.pageLayout.setSpacing(0)
@ -159,7 +158,7 @@ class MediaManagerItem(QtGui.QWidget):
``icon``
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 ':/'.
``slot``
@ -246,7 +245,7 @@ class MediaManagerItem(QtGui.QWidget):
preview_string[u'title'],
preview_string[u'tooltip'],
u':/general/general_preview.png', self.onPreviewClick)
## Live Button ##
## Live Button ##
live_string = self.plugin.getString(StringContent.Live)
self.addToolbarButton(
live_string[u'title'],
@ -367,33 +366,34 @@ class MediaManagerItem(QtGui.QWidget):
count += 1
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
if os.path.exists(thumb):
filedate = os.stat(file).st_mtime
thumbdate = os.stat(thumb).st_mtime
# if file updated rebuild icon
if filedate > thumbdate:
self.iconFromFile(file, thumb)
imageDate = os.stat(image).st_mtime
thumbDate = os.stat(thumb).st_mtime
# If image has been updated rebuild icon
if imageDate > thumbDate:
self.iconFromFile(image, thumb)
else:
self.iconFromFile(file, thumb)
self.iconFromFile(image, thumb)
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``
The file to create the icon from
``image``
The image file to create the icon from.
``thumb``
The filename to save the thumbnail to
"""
icon = build_icon(unicode(file))
icon = build_icon(unicode(image))
pixmap = icon.pixmap(QtCore.QSize(88, 50))
ext = os.path.splitext(thumb)[1].lower()
pixmap.save(thumb, ext[1:])
@ -404,12 +404,16 @@ class MediaManagerItem(QtGui.QWidget):
u'defined by the plugin')
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):
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):
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to '
@ -508,7 +512,7 @@ class MediaManagerItem(QtGui.QWidget):
'No Service Item Selected'),
translate('OpenLP.MediaManagerItem',
'You must select an existing service item to add to.'))
elif self.title.lower() == serviceItem.name.lower():
elif self.plugin.name.lower() == serviceItem.name.lower():
self.generateSlideData(serviceItem)
self.parent.serviceManager.addServiceItem(serviceItem,
replace=True)
@ -525,10 +529,7 @@ class MediaManagerItem(QtGui.QWidget):
Common method for generating a service item
"""
serviceItem = ServiceItem(self.parent)
if self.serviceItemIconName:
serviceItem.add_icon(self.serviceItemIconName)
else:
serviceItem.add_icon(self.parent.icon_path)
serviceItem.add_icon(self.parent.icon_path)
if self.generateSlideData(serviceItem, item, xmlVersion):
return serviceItem
else:
@ -540,3 +541,25 @@ class MediaManagerItem(QtGui.QWidget):
individual service items need to be processed by the plugins
"""
pass
def _getIdOfItemToGenerate(self, item, remoteItem):
"""
Utility method to check items being submitted for slide generation.
``item``
The item to check.
``remoteItem``
The id to assign if the slide generation was remotely triggered.
"""
if item is None:
if self.remoteTriggered is None:
item = self.listView.currentItem()
if item is None:
return False
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
else:
item_id = remoteItem
else:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
return item_id

View File

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

View File

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

View File

@ -91,21 +91,30 @@ class ThemeLevel(object):
Song = 3
class BackgroundType(object):
"""
Type enumeration for backgrounds.
"""
Solid = 0
Gradient = 1
Image = 2
@staticmethod
def to_string(type):
if type == BackgroundType.Solid:
def to_string(background_type):
"""
Return a string representation of a background type.
"""
if background_type == BackgroundType.Solid:
return u'solid'
elif type == BackgroundType.Gradient:
elif background_type == BackgroundType.Gradient:
return u'gradient'
elif type == BackgroundType.Image:
elif background_type == BackgroundType.Image:
return u'image'
@staticmethod
def from_string(type_string):
"""
Return a background type for the given string.
"""
if type_string == u'solid':
return BackgroundType.Solid
elif type_string == u'gradient':
@ -114,6 +123,9 @@ class BackgroundType(object):
return BackgroundType.Image
class BackgroundGradientType(object):
"""
Type enumeration for background gradients.
"""
Horizontal = 0
Vertical = 1
Circular = 2
@ -121,20 +133,26 @@ class BackgroundGradientType(object):
LeftBottom = 4
@staticmethod
def to_string(type):
if type == BackgroundGradientType.Horizontal:
def to_string(gradient_type):
"""
Return a string representation of a background gradient type.
"""
if gradient_type == BackgroundGradientType.Horizontal:
return u'horizontal'
elif type == BackgroundGradientType.Vertical:
elif gradient_type == BackgroundGradientType.Vertical:
return u'vertical'
elif type == BackgroundGradientType.Circular:
elif gradient_type == BackgroundGradientType.Circular:
return u'circular'
elif type == BackgroundGradientType.LeftTop:
elif gradient_type == BackgroundGradientType.LeftTop:
return u'leftTop'
elif type == BackgroundGradientType.LeftBottom:
elif gradient_type == BackgroundGradientType.LeftBottom:
return u'leftBottom'
@staticmethod
def from_string(type_string):
"""
Return a background gradient type for the given string.
"""
if type_string == u'horizontal':
return BackgroundGradientType.Horizontal
elif type_string == u'vertical':
@ -147,19 +165,25 @@ class BackgroundGradientType(object):
return BackgroundGradientType.LeftBottom
class HorizontalType(object):
"""
Type enumeration for horizontal alignment.
"""
Left = 0
Center = 1
Right = 2
class VerticalType(object):
"""
Type enumeration for vertical alignment.
"""
Top = 0
Middle = 1
Bottom = 2
boolean_list = [u'italics', u'override', u'outline', u'shadow',
BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow',
u'slide_transition']
integer_list = [u'size', u'line_adjustment', u'x', u'height', u'y',
INTEGER_LIST = [u'size', u'line_adjustment', u'x', u'height', u'y',
u'width', u'shadow_size', u'outline_size', u'horizontal_align',
u'vertical_align', u'wrap_style']
@ -514,9 +538,9 @@ class ThemeXML(object):
return
field = self._de_hump(element)
tag = master + u'_' + field
if field in boolean_list:
if field in BOOLEAN_LIST:
setattr(self, tag, str_to_bool(value))
elif field in integer_list:
elif field in INTEGER_LIST:
setattr(self, tag, int(value))
else:
# make string value unicode
@ -559,8 +583,7 @@ class ThemeXML(object):
self.background_end_color,
self.background_direction)
else:
filename = \
os.path.split(self.background_filename)[1]
filename = os.path.split(self.background_filename)[1]
self.add_background_image(filename)
self.add_font(self.font_main_name,
self.font_main_color,

View File

@ -61,7 +61,7 @@ class OpenLPToolbar(QtGui.QToolBar):
``icon``
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 ':/'.
``tooltip``
@ -73,13 +73,13 @@ class OpenLPToolbar(QtGui.QToolBar):
``checkable``
If *True* the button has two, *off* and *on*, states. Default is
*False*, which means the buttons has only one state.
``shortcut``
The primary shortcut for this action
``alternate``
The alternate shortcut for this action
``context``
Specify the context in which this shortcut is valid
"""

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

@ -0,0 +1,268 @@
# -*- 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__)
class UiStrings(object):
"""
Provide standard strings for objects to use.
"""
# These strings should need a good reason to be retranslated elsewhere.
# Should some/more/less of these have an &amp; attached?
Add = translate('OpenLP.Ui', '&Add')
AllFiles = translate('OpenLP.Ui', 'All Files')
Authors = translate('OpenLP.Ui', 'Authors')
Delete = translate('OpenLP.Ui', '&Delete')
Edit = translate('OpenLP.Ui', '&Edit')
Error = translate('OpenLP.Ui', 'Error')
Import = translate('OpenLP.Ui', 'Import')
Live = translate('OpenLP.Ui', 'Live')
Load = translate('OpenLP.Ui', 'Load')
New = translate('OpenLP.Ui', 'New')
OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0')
Preview = translate('OpenLP.Ui', 'Preview')
Service = translate('OpenLP.Ui', 'Service')
Theme = translate('OpenLP.Ui', 'Theme')
Themes = translate('OpenLP.Ui', 'Themes')
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.
"""
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 UiStrings.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(UiStrings.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)
def create_valign_combo(form, parent, layout):
"""
Creates a standard label and combo box for asking users to select a
vertical alignment.
``form``
The UI screen that the label and combo will appear on.
``parent``
The parent object. This should be a ``QWidget`` descendant.
``layout``
A layout object to add the label and combo widgets to.
"""
verticalLabel = QtGui.QLabel(parent)
verticalLabel.setObjectName(u'VerticalLabel')
verticalLabel.setText(translate('OpenLP.Ui', '&Vertical Align:'))
form.verticalComboBox = QtGui.QComboBox(parent)
form.verticalComboBox.setObjectName(u'VerticalComboBox')
form.verticalComboBox.addItem(translate('OpenLP.Ui', 'Top'))
form.verticalComboBox.addItem(translate('OpenLP.Ui', 'Middle'))
form.verticalComboBox.addItem(translate('OpenLP.Ui', 'Bottom'))
verticalLabel.setBuddy(form.verticalComboBox)
layout.addRow(verticalLabel, form.verticalComboBox)

View File

@ -33,11 +33,14 @@ processing version 1 themes in OpenLP version 2.
from xml.etree.ElementTree import ElementTree, XML
from PyQt4 import QtGui
DELPHI_COLORS = {u'clRed': 0xFF0000,
u'clBlue': 0x0000FF,
u'clYellow': 0xFFFF00,
u'clBlack': 0x000000,
u'clWhite': 0xFFFFFF}
DELPHI_COLORS = {
u'clAqua': 0x00FFFF, u'clBlack': 0x000000, u'clBlue': 0x0000FF,
u'clFuchsia': 0xFF00FF, u'clGray': 0x808080, u'clGreen': 0x008000,
u'clLime': 0x00FF00, u'clMaroon': 0x800000, u'clNavy': 0x000080,
u'clOlive': 0x808000, u'clPurple': 0x800080, u'clRed': 0xFF0000,
u'clSilver': 0xC0C0C0, u'clTeal': 0x008080, u'clWhite': 0xFFFFFF,
u'clYellow': 0xFFFF00
}
BLANK_STYLE_XML = \
'''<?xml version="1.0" encoding="iso-8859-1"?>
@ -184,7 +187,6 @@ class Theme(object):
if element.tag != u'Theme':
element_text = element.text
val = 0
# easy!
if element_text is None:
val = element_text
# strings need special handling to sort the colours out

View File

@ -51,34 +51,6 @@ class HideMode(object):
Theme = 2
Screen = 3
def criticalErrorMessageBox(title=None, message=None, parent=None,
question=False):
"""
Provides a standard critical message box for errors that OpenLP displays
to users.
``title``
The title for the message box.
``message``
The message to display to the user.
``parent``
The parent UI element to attach the dialog to.
``question``
Should this message box question the user.
"""
error = translate('OpenLP.Ui', 'Error')
if question:
return QtGui.QMessageBox.critical(parent, error, message,
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
data = {u'message': message}
data[u'title'] = title if title else error
return Receiver.send_message(u'openlp_error_message', data)
from themeform import ThemeForm
from filerenameform import FileRenameForm
from maindisplay import MainDisplay
@ -99,6 +71,6 @@ from mediadockmanager import MediaDockManager
from servicemanager import ServiceManager
from thememanager import ThemeManager
__all__ = ['criticalErrorMessageBox', 'SplashScreen', 'AboutForm',
'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager',
'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm']
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay',
'SlideController', 'ServiceManager', 'ThemeManager', 'MediaDockManager',
'ServiceItemEditForm']

View File

@ -23,27 +23,27 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
'''
"""
The :mod:`DisplayTagTab` provides an Tag Edit facility. The Base set are
protected and included each time loaded. Custom tags can be defined and saved.
The Custom Tag arrays are saved in a pickle so QSettings works on them. Base
Tags cannot be changed.
'''
"""
import cPickle
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate, DisplayTags
from openlp.core.ui import criticalErrorMessageBox
from openlp.core.lib.ui import UiStrings, critical_error_message_box
class DisplayTagTab(SettingsTab):
'''
"""
The :class:`DisplayTagTab` manages the settings tab .
'''
"""
def __init__(self):
'''
"""
Initialise the settings tab
'''
"""
SettingsTab.__init__(self, u'Display Tags')
def resizeEvent(self, event=None):
@ -67,9 +67,9 @@ class DisplayTagTab(SettingsTab):
self.selected = -1
def setupUi(self):
'''
"""
Configure the UI elements for the tab.
'''
"""
self.setObjectName(u'DisplayTagTab')
self.tabTitleVisible = \
translate(u'OpenLP.DisplayTagTab', 'Display Tags')
@ -164,8 +164,7 @@ class DisplayTagTab(SettingsTab):
self.startTagLabel.setText(
translate('OpenLP.DisplayTagTab', 'Start tag'))
self.endTagLabel.setText(translate('OpenLP.DisplayTagTab', 'End tag'))
self.deletePushButton.setText(
translate('OpenLP.DisplayTagTab', 'Delete'))
self.deletePushButton.setText(UiStrings.Delete)
self.defaultPushButton.setText(
translate('OpenLP.DisplayTagTab', 'Default'))
self.newPushButton.setText(translate('OpenLP.DisplayTagTab', 'New'))
@ -276,7 +275,7 @@ class DisplayTagTab(SettingsTab):
"""
for html in DisplayTags.get_html_tags():
if self._strip(html[u'start tag']) == u'n':
criticalErrorMessageBox(
critical_error_message_box(
translate('OpenLP.DisplayTagTab', 'Update Error'),
translate('OpenLP.DisplayTagTab',
'Tag "n" already defined.'))
@ -317,7 +316,7 @@ class DisplayTagTab(SettingsTab):
for linenumber, html1 in enumerate(html_expands):
if self._strip(html1[u'start tag']) == tag and \
linenumber != self.selected:
criticalErrorMessageBox(
critical_error_message_box(
translate('OpenLP.DisplayTagTab', 'Update Error'),
unicode(translate('OpenLP.DisplayTagTab',
'Tag %s already defined.')) % tag)

View File

@ -46,6 +46,15 @@ class Ui_ExceptionDialog(object):
self.messageLabel.setObjectName(u'messageLabel')
self.messageLayout.addWidget(self.messageLabel)
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.setReadOnly(True)
self.exceptionTextEdit.setObjectName(u'exceptionTextEdit')
@ -65,19 +74,31 @@ class Ui_ExceptionDialog(object):
self.saveReportButton.setObjectName(u'saveReportButton')
self.exceptionButtonBox.addButton(self.saveReportButton,
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)
QtCore.QObject.connect(self.descriptionTextEdit,
QtCore.SIGNAL(u'textChanged()'), self.onDescriptionUpdated)
QtCore.QObject.connect(self.exceptionButtonBox,
QtCore.SIGNAL(u'rejected()'), exceptionDialog.reject)
QtCore.QObject.connect(self.sendReportButton,
QtCore.SIGNAL(u'pressed()'), self.onSendReportButtonPressed)
QtCore.QObject.connect(self.saveReportButton,
QtCore.SIGNAL(u'pressed()'), self.onSaveReportButtonPressed)
QtCore.QObject.connect(self.attachFileButton,
QtCore.SIGNAL(u'pressed()'), self.onAttachFileButtonPressed)
QtCore.QMetaObject.connectSlotsByName(exceptionDialog)
def retranslateUi(self, exceptionDialog):
exceptionDialog.setWindowTitle(
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! '
'OpenLP hit a problem, and couldn\'t recover. The text in the box '
'below contains information that might be helpful to the OpenLP '
@ -88,3 +109,5 @@ class Ui_ExceptionDialog(object):
'Send E-Mail'))
self.saveReportButton.setText(translate('OpenLP.ExceptionDialog',
'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.settingsSection = u'crashreport'
def exec_(self):
self.descriptionTextEdit.setPlainText(u'')
self.onDescriptionUpdated()
self.fileAttachment = None
return QtGui.QDialog.exec_(self)
def _createReport(self):
openlp_version = self.parent().applicationVersion[u'full']
description = unicode(self.descriptionTextEdit.toPlainText())
traceback = unicode(self.exceptionTextEdit.toPlainText())
system = unicode(translate('OpenLP.ExceptionForm',
'Platform: %s\n')) % platform.platform()
@ -90,7 +97,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
system = system + u'Desktop: KDE SC\n'
elif os.environ.get(u'GNOME_DESKTOP_SESSION_ID'):
system = system + u'Desktop: GNOME\n'
return (openlp_version, traceback, system, libraries)
return (openlp_version, description, traceback, system, libraries)
def onSaveReportButtonPressed(self):
"""
@ -99,6 +106,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
report = unicode(translate('OpenLP.ExceptionForm',
'**OpenLP Bug Report**\n'
'Version: %s\n\n'
'--- Details of the Exception. ---\n\n%s\n\n '
'--- Exception Traceback ---\n%s\n'
'--- System information ---\n%s\n'
'--- Library Versions ---\n%s\n'))
@ -132,18 +140,48 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
body = unicode(translate('OpenLP.ExceptionForm',
'*OpenLP Bug Report*\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'
'--- System information ---\n%s\n'
'--- Library Versions ---\n%s\n',
'Please add the information that bug reports are favoured written '
'in English.'))
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):
source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line)
if u':' in line:
exception = line.split(u'\n')[-1].split(u':')[0]
subject = u'Bug report: %s in %s' % (exception, source)
mailto(address=u'bugs@openlp.org', subject=subject,
body=body % content)
if self.fileAttachment:
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:
return self.text()
class GeneralTab(SettingsTab):
"""
GeneralTab is the general settings tab in the settings dialog.

View File

@ -72,7 +72,7 @@ class MainDisplay(DisplayWidget):
self.setWindowIcon(mainIcon)
self.retranslateUi()
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
self.setWindowFlags(QtCore.Qt.FramelessWindowHint |
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
QtCore.Qt.WindowStaysOnTopHint)
if self.isLive:
QtCore.QObject.connect(Receiver.get_receiver(),
@ -326,8 +326,7 @@ class MainDisplay(DisplayWidget):
vol = float(volume)/float(10)
if isBackground or not self.usePhonon:
js = u'show_video("init", "%s", %s, true); show_video("play");' % \
(videoPath.replace(u'\\', u'\\\\'), \
str(vol))
(videoPath.replace(u'\\', u'\\\\'), str(vol))
self.frame.evaluateJavaScript(js)
else:
self.phononActive = True
@ -398,8 +397,7 @@ class MainDisplay(DisplayWidget):
if u'video' in self.override:
Receiver.send_message(u'video_background_replaced')
self.override = {}
elif self.override[u'theme'] != \
serviceItem.themedata.theme_name:
elif self.override[u'theme'] != serviceItem.themedata.theme_name:
Receiver.send_message(u'live_theme_changed')
self.override = {}
else:

View File

@ -28,11 +28,13 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
icon_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ThemeManager, SlideController, PluginForm, MediaDockManager, \
ShortcutListForm
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate
from openlp.core.utils import AppLocation, add_actions, LanguageManager, \
ActionList
@ -76,10 +78,10 @@ class Ui_MainWindow(object):
self.MainContentLayout.setMargin(0)
self.MainContentLayout.setObjectName(u'MainContentLayout')
mainWindow.setCentralWidget(self.MainContent)
self.ControlSplitter = QtGui.QSplitter(self.MainContent)
self.ControlSplitter.setOrientation(QtCore.Qt.Horizontal)
self.ControlSplitter.setObjectName(u'ControlSplitter')
self.MainContentLayout.addWidget(self.ControlSplitter)
self.controlSplitter = QtGui.QSplitter(self.MainContent)
self.controlSplitter.setOrientation(QtCore.Qt.Horizontal)
self.controlSplitter.setObjectName(u'controlSplitter')
self.MainContentLayout.addWidget(self.controlSplitter)
# Create slide controllers
self.previewController = SlideController(self, self.settingsmanager,
self.screens)
@ -87,10 +89,10 @@ class Ui_MainWindow(object):
self.screens, True)
previewVisible = QtCore.QSettings().value(
u'user interface/preview panel', QtCore.QVariant(True)).toBool()
self.previewController.Panel.setVisible(previewVisible)
self.previewController.panel.setVisible(previewVisible)
liveVisible = QtCore.QSettings().value(u'user interface/live panel',
QtCore.QVariant(True)).toBool()
self.liveController.Panel.setVisible(liveVisible)
self.liveController.panel.setVisible(liveVisible)
# Create menu
self.MenuBar = QtGui.QMenuBar(mainWindow)
self.MenuBar.setObjectName(u'MenuBar')
@ -101,9 +103,9 @@ class Ui_MainWindow(object):
self.FileExportMenu = QtGui.QMenu(self.FileMenu)
self.FileExportMenu.setObjectName(u'FileExportMenu')
# View Menu
self.ViewMenu = QtGui.QMenu(self.MenuBar)
self.ViewMenu.setObjectName(u'ViewMenu')
self.ViewModeMenu = QtGui.QMenu(self.ViewMenu)
self.viewMenu = QtGui.QMenu(self.MenuBar)
self.viewMenu.setObjectName(u'viewMenu')
self.ViewModeMenu = QtGui.QMenu(self.viewMenu)
self.ViewModeMenu.setObjectName(u'ViewModeMenu')
# Tools Menu
self.ToolsMenu = QtGui.QMenu(self.MenuBar)
@ -124,135 +126,103 @@ class Ui_MainWindow(object):
self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel')
self.StatusBar.addPermanentWidget(self.DefaultThemeLabel)
# Create the MediaManager
self.MediaManagerDock = OpenLPDockWidget(
mainWindow, u'MediaManagerDock',
build_icon(u':/system/system_mediamanager.png'))
self.MediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE)
self.MediaManagerDock.setMinimumWidth(
self.mediaManagerDock = OpenLPDockWidget(mainWindow,
u'mediaManagerDock', u':/system/system_mediamanager.png')
self.mediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE)
self.mediaManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_left)
# Create the media toolbox
self.MediaToolBox = QtGui.QToolBox(self.MediaManagerDock)
self.MediaToolBox = QtGui.QToolBox(self.mediaManagerDock)
self.MediaToolBox.setObjectName(u'MediaToolBox')
self.MediaManagerDock.setWidget(self.MediaToolBox)
self.mediaManagerDock.setWidget(self.MediaToolBox)
mainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea,
self.MediaManagerDock)
self.mediaManagerDock)
# Create the service manager
self.ServiceManagerDock = OpenLPDockWidget(
mainWindow, u'ServiceManagerDock',
build_icon(u':/system/system_servicemanager.png'))
self.ServiceManagerDock.setMinimumWidth(
self.serviceManagerDock = OpenLPDockWidget(mainWindow,
u'serviceManagerDock', u':/system/system_servicemanager.png')
self.serviceManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right)
self.ServiceManagerContents = ServiceManager(mainWindow,
self.ServiceManagerDock)
self.ServiceManagerDock.setWidget(self.ServiceManagerContents)
self.serviceManagerDock)
self.serviceManagerDock.setWidget(self.ServiceManagerContents)
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self.ServiceManagerDock)
self.serviceManagerDock)
# Create the theme manager
self.ThemeManagerDock = OpenLPDockWidget(
mainWindow, u'ThemeManagerDock',
build_icon(u':/system/system_thememanager.png'))
self.ThemeManagerDock.setMinimumWidth(
self.themeManagerDock = OpenLPDockWidget(mainWindow,
u'themeManagerDock', u':/system/system_thememanager.png')
self.themeManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right)
self.ThemeManagerContents = ThemeManager(mainWindow,
self.ThemeManagerDock)
self.themeManagerDock)
self.ThemeManagerContents.setObjectName(u'ThemeManagerContents')
self.ThemeManagerDock.setWidget(self.ThemeManagerContents)
self.themeManagerDock.setWidget(self.ThemeManagerContents)
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self.ThemeManagerDock)
self.themeManagerDock)
# Create the menu items
self.FileNewItem = QtGui.QAction(mainWindow)
self.FileNewItem.setIcon(build_icon(u':/general/general_new.png'))
self.FileNewItem.setObjectName(u'FileNewItem')
self.FileNewItem = icon_action(mainWindow, u'FileNewItem',
u':/general/general_new.png')
mainWindow.actionList.add_action(self.FileNewItem, u'File')
self.FileOpenItem = QtGui.QAction(mainWindow)
self.FileOpenItem.setIcon(build_icon(u':/general/general_open.png'))
self.FileOpenItem.setObjectName(u'FileOpenItem')
self.FileOpenItem = icon_action(mainWindow, u'FileOpenItem',
u':/general/general_open.png')
mainWindow.actionList.add_action(self.FileOpenItem, u'File')
self.FileSaveItem = QtGui.QAction(mainWindow)
self.FileSaveItem.setIcon(build_icon(u':/general/general_save.png'))
self.FileSaveItem.setObjectName(u'FileSaveItem')
self.FileSaveItem = icon_action(mainWindow, u'FileSaveItem',
u':/general/general_save.png')
mainWindow.actionList.add_action(self.FileSaveItem, u'File')
self.FileSaveAsItem = QtGui.QAction(mainWindow)
self.FileSaveAsItem.setObjectName(u'FileSaveAsItem')
self.FileSaveAsItem = base_action(mainWindow, u'FileSaveAsItem')
mainWindow.actionList.add_action(self.FileSaveAsItem, u'File')
self.FileExitItem = QtGui.QAction(mainWindow)
self.FileExitItem.setIcon(build_icon(u':/system/system_exit.png'))
self.FileExitItem.setObjectName(u'FileExitItem')
self.printServiceOrderItem = base_action(
mainWindow, u'printServiceItem')
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')
self.ImportThemeItem = QtGui.QAction(mainWindow)
self.ImportThemeItem.setObjectName(u'ImportThemeItem')
self.ImportThemeItem = base_action(mainWindow, u'ImportThemeItem')
mainWindow.actionList.add_action(self.ImportThemeItem, u'Import')
self.ImportLanguageItem = QtGui.QAction(mainWindow)
self.ImportLanguageItem.setObjectName(u'ImportLanguageItem')
self.ImportLanguageItem = base_action(mainWindow, u'ImportLanguageItem')
mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import')
self.ExportThemeItem = QtGui.QAction(mainWindow)
self.ExportThemeItem.setObjectName(u'ExportThemeItem')
self.ExportThemeItem = base_action(mainWindow, u'ExportThemeItem')
mainWindow.actionList.add_action(self.ExportThemeItem, u'Export')
self.ExportLanguageItem = QtGui.QAction(mainWindow)
self.ExportLanguageItem.setObjectName(u'ExportLanguageItem')
self.ExportLanguageItem = base_action(mainWindow, u'ExportLanguageItem')
mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export')
self.ViewMediaManagerItem = QtGui.QAction(mainWindow)
self.ViewMediaManagerItem.setCheckable(True)
self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible())
self.ViewMediaManagerItem.setIcon(
build_icon(u':/system/system_mediamanager.png'))
self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem')
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')
self.ViewMediaManagerItem = icon_action(mainWindow,
u'ViewMediaManagerItem', u':/system/system_mediamanager.png',
self.mediaManagerDock.isVisible())
self.ViewThemeManagerItem = icon_action(mainWindow,
u'ViewThemeManagerItem', u':/system/system_thememanager.png',
self.themeManagerDock.isVisible())
mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View')
self.ViewServiceManagerItem = QtGui.QAction(mainWindow)
self.ViewServiceManagerItem.setCheckable(True)
self.ViewServiceManagerItem.setChecked(
self.ServiceManagerDock.isVisible())
self.ViewServiceManagerItem.setIcon(
build_icon(u':/system/system_servicemanager.png'))
self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem')
self.ViewServiceManagerItem = icon_action(mainWindow,
u'ViewServiceManagerItem', u':/system/system_servicemanager.png',
self.serviceManagerDock.isVisible())
mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View')
self.ViewPreviewPanel = QtGui.QAction(mainWindow)
self.ViewPreviewPanel.setCheckable(True)
self.ViewPreviewPanel.setChecked(previewVisible)
self.ViewPreviewPanel.setObjectName(u'ViewPreviewPanel')
self.ViewPreviewPanel = checkable_action(mainWindow,
u'ViewPreviewPanel', previewVisible)
mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View')
self.ViewLivePanel = QtGui.QAction(mainWindow)
self.ViewLivePanel.setCheckable(True)
self.ViewLivePanel.setChecked(liveVisible)
self.ViewLivePanel.setObjectName(u'ViewLivePanel')
self.ViewLivePanel = checkable_action(mainWindow, u'ViewLivePanel',
liveVisible)
mainWindow.actionList.add_action(self.ViewLivePanel, u'View')
self.ModeDefaultItem = QtGui.QAction(mainWindow)
self.ModeDefaultItem.setCheckable(True)
self.ModeDefaultItem.setObjectName(u'ModeDefaultItem')
self.ModeDefaultItem = checkable_action(mainWindow, u'ModeDefaultItem')
mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode')
self.ModeSetupItem = QtGui.QAction(mainWindow)
self.ModeSetupItem.setCheckable(True)
self.ModeSetupItem.setObjectName(u'ModeLiveItem')
self.ModeSetupItem = checkable_action(mainWindow, u'ModeLiveItem')
mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode')
self.ModeLiveItem = QtGui.QAction(mainWindow)
self.ModeLiveItem.setCheckable(True)
self.ModeLiveItem.setObjectName(u'ModeLiveItem')
self.ModeLiveItem = checkable_action(mainWindow, u'ModeLiveItem')
mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode')
self.ModeGroup = QtGui.QActionGroup(mainWindow)
self.ModeGroup.addAction(self.ModeDefaultItem)
self.ModeGroup.addAction(self.ModeSetupItem)
self.ModeGroup.addAction(self.ModeLiveItem)
self.ModeDefaultItem.setChecked(True)
self.ToolsAddToolItem = QtGui.QAction(mainWindow)
self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png'))
self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem')
self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
u':/tools/tools_add.png')
mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools')
self.SettingsPluginListItem = QtGui.QAction(mainWindow)
self.SettingsPluginListItem.setIcon(
build_icon(u':/system/settings_plugin_list.png'))
self.SettingsPluginListItem.setObjectName(u'SettingsPluginListItem')
mainWindow.actionList.add_action(self.SettingsPluginListItem,
self.settingsPluginListItem = icon_action(mainWindow,
u'settingsPluginListItem', u':/system/settings_plugin_list.png')
mainWindow.actionList.add_action(self.settingsPluginListItem,
u'Settings')
# i18n Language Items
self.AutoLanguageItem = QtGui.QAction(mainWindow)
self.AutoLanguageItem.setObjectName(u'AutoLanguageItem')
self.AutoLanguageItem.setCheckable(True)
self.AutoLanguageItem = checkable_action(mainWindow,
u'AutoLanguageItem')
mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings')
self.LanguageGroup = QtGui.QActionGroup(mainWindow)
self.LanguageGroup.setExclusive(True)
@ -262,39 +232,28 @@ class Ui_MainWindow(object):
qmList = LanguageManager.get_qm_list()
savedLanguage = LanguageManager.get_language()
for key in sorted(qmList.keys()):
languageItem = QtGui.QAction(mainWindow)
languageItem.setObjectName(key)
languageItem.setCheckable(True)
languageItem = checkable_action(mainWindow, key)
if qmList[key] == savedLanguage:
languageItem.setChecked(True)
add_actions(self.LanguageGroup, [languageItem])
self.SettingsShortcutsItem = QtGui.QAction(mainWindow)
self.SettingsShortcutsItem.setIcon(
build_icon(u':/system/system_configure_shortcuts.png'))
self.SettingsShortcutsItem.setObjectName(u'SettingsShortcutsItem')
self.SettingsConfigureItem = QtGui.QAction(mainWindow)
self.SettingsConfigureItem.setIcon(
build_icon(u':/system/system_settings.png'))
self.SettingsConfigureItem.setObjectName(u'SettingsConfigureItem')
self.SettingsShortcutsItem = icon_action(mainWindow,
u'SettingsShortcutsItem',
u':/system/system_configure_shortcuts.png')
self.SettingsConfigureItem = icon_action(mainWindow,
u'SettingsConfigureItem', u':/system/system_settings.png')
mainWindow.actionList.add_action(self.SettingsShortcutsItem,
u'Settings')
self.HelpDocumentationItem = QtGui.QAction(mainWindow)
self.HelpDocumentationItem.setIcon(
build_icon(u':/system/system_help_contents.png'))
self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem')
self.HelpDocumentationItem = icon_action(mainWindow,
u'HelpDocumentationItem', u':/system/system_help_contents.png')
self.HelpDocumentationItem.setEnabled(False)
mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help')
self.HelpAboutItem = QtGui.QAction(mainWindow)
self.HelpAboutItem.setIcon(
build_icon(u':/system/system_about.png'))
self.HelpAboutItem.setObjectName(u'HelpAboutItem')
self.HelpAboutItem = icon_action(mainWindow, u'HelpAboutItem',
u':/system/system_about.png')
mainWindow.actionList.add_action(self.HelpAboutItem, u'Help')
self.HelpOnlineHelpItem = QtGui.QAction(mainWindow)
self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem')
self.HelpOnlineHelpItem = base_action(mainWindow, u'HelpOnlineHelpItem')
self.HelpOnlineHelpItem.setEnabled(False)
mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help')
self.HelpWebSiteItem = QtGui.QAction(mainWindow)
self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem')
self.HelpWebSiteItem = base_action(mainWindow, u'HelpWebSiteItem')
mainWindow.actionList.add_action(self.HelpWebSiteItem, u'Help')
add_actions(self.FileImportMenu,
(self.ImportThemeItem, self.ImportLanguageItem))
@ -302,18 +261,18 @@ class Ui_MainWindow(object):
(self.ExportThemeItem, self.ExportLanguageItem))
self.FileMenuActions = (self.FileNewItem, self.FileOpenItem,
self.FileSaveItem, self.FileSaveAsItem, None,
self.FileImportMenu.menuAction(), self.FileExportMenu.menuAction(),
self.FileExitItem)
self.printServiceOrderItem, None, self.FileImportMenu.menuAction(),
self.FileExportMenu.menuAction(), self.FileExitItem)
add_actions(self.ViewModeMenu, (self.ModeDefaultItem,
self.ModeSetupItem, self.ModeLiveItem))
add_actions(self.ViewMenu, (self.ViewModeMenu.menuAction(),
add_actions(self.viewMenu, (self.ViewModeMenu.menuAction(),
None, self.ViewMediaManagerItem, self.ViewServiceManagerItem,
self.ViewThemeManagerItem, None, self.ViewPreviewPanel,
self.ViewLivePanel))
# i18n add Language Actions
add_actions(self.SettingsLanguageMenu, (self.AutoLanguageItem, None))
add_actions(self.SettingsLanguageMenu, self.LanguageGroup.actions())
add_actions(self.SettingsMenu, (self.SettingsPluginListItem,
add_actions(self.SettingsMenu, (self.settingsPluginListItem,
self.SettingsLanguageMenu.menuAction(), None,
self.SettingsShortcutsItem, self.SettingsConfigureItem))
add_actions(self.ToolsMenu, (self.ToolsAddToolItem, None))
@ -321,7 +280,7 @@ class Ui_MainWindow(object):
self.HelpOnlineHelpItem, None, self.HelpWebSiteItem,
self.HelpAboutItem))
add_actions(self.MenuBar, (self.FileMenu.menuAction(),
self.ViewMenu.menuAction(), self.ToolsMenu.menuAction(),
self.viewMenu.menuAction(), self.ToolsMenu.menuAction(),
self.SettingsMenu.menuAction(), self.HelpMenu.menuAction()))
# Initialise the translation
self.retranslateUi(mainWindow)
@ -337,23 +296,23 @@ class Ui_MainWindow(object):
"""
Set up the translation system
"""
mainWindow.mainTitle = translate('OpenLP.MainWindow', 'OpenLP 2.0')
mainWindow.mainTitle = UiStrings.OLPV2
mainWindow.setWindowTitle(mainWindow.mainTitle)
self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
self.FileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export'))
self.ViewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
self.viewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
self.ViewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
self.ToolsMenu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
self.SettingsMenu.setTitle(translate('OpenLP.MainWindow', '&Settings'))
self.SettingsLanguageMenu.setTitle(translate('OpenLP.MainWindow',
'&Language'))
self.HelpMenu.setTitle(translate('OpenLP.MainWindow', '&Help'))
self.MediaManagerDock.setWindowTitle(
self.mediaManagerDock.setWindowTitle(
translate('OpenLP.MainWindow', 'Media Manager'))
self.ServiceManagerDock.setWindowTitle(
self.serviceManagerDock.setWindowTitle(
translate('OpenLP.MainWindow', 'Service Manager'))
self.ThemeManagerDock.setWindowTitle(
self.themeManagerDock.setWindowTitle(
translate('OpenLP.MainWindow', 'Theme Manager'))
self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New'))
self.FileNewItem.setToolTip(
@ -381,6 +340,12 @@ class Ui_MainWindow(object):
'Save the current service under a new name.'))
self.FileSaveAsItem.setShortcut(
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(
translate('OpenLP.MainWindow', 'E&xit'))
self.FileExitItem.setStatusTip(
@ -439,11 +404,11 @@ class Ui_MainWindow(object):
'Toggle the visibility of the live panel.'))
self.ViewLivePanel.setShortcut(
translate('OpenLP.MainWindow', 'F12'))
self.SettingsPluginListItem.setText(translate('OpenLP.MainWindow',
self.settingsPluginListItem.setText(translate('OpenLP.MainWindow',
'&Plugin List'))
self.SettingsPluginListItem.setStatusTip(
self.settingsPluginListItem.setStatusTip(
translate('OpenLP.MainWindow', 'List the Plugins'))
self.SettingsPluginListItem.setShortcut(
self.settingsPluginListItem.setShortcut(
translate('OpenLP.MainWindow', 'Alt+F7'))
self.HelpDocumentationItem.setText(
translate('OpenLP.MainWindow', '&User Guide'))
@ -537,20 +502,20 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'toggled(bool)'), self.setPreviewPanelVisibility)
QtCore.QObject.connect(self.ViewLivePanel,
QtCore.SIGNAL(u'toggled(bool)'), self.setLivePanelVisibility)
QtCore.QObject.connect(self.MediaManagerDock,
QtCore.QObject.connect(self.mediaManagerDock,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.ViewMediaManagerItem.setChecked)
QtCore.QObject.connect(self.ServiceManagerDock,
QtCore.QObject.connect(self.serviceManagerDock,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.ViewServiceManagerItem.setChecked)
QtCore.QObject.connect(self.ThemeManagerDock,
QtCore.QObject.connect(self.themeManagerDock,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.ViewThemeManagerItem.setChecked)
QtCore.QObject.connect(self.HelpWebSiteItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
QtCore.QObject.connect(self.HelpAboutItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked)
QtCore.QObject.connect(self.SettingsPluginListItem,
QtCore.QObject.connect(self.settingsPluginListItem,
QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked)
QtCore.QObject.connect(self.SettingsConfigureItem,
QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
@ -567,6 +532,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.FileSaveAsItem,
QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.saveFileAs)
QtCore.QObject.connect(self.printServiceOrderItem,
QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.printServiceOrder)
# i18n set signals for languages
QtCore.QObject.connect(self.AutoLanguageItem,
QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage)
@ -758,37 +726,32 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
Put OpenLP into "Default" view mode.
"""
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'default')
self.setViewMode(True, True, True, True, True)
self.setViewMode(True, True, True, True, True, u'default')
def onModeSetupItemClicked(self):
"""
Put OpenLP into "Setup" view mode.
"""
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'setup')
self.setViewMode(True, True, False, True, False)
self.setViewMode(True, True, False, True, False, u'setup')
def onModeLiveItemClicked(self):
"""
Put OpenLP into "Live" view mode.
"""
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'live')
self.setViewMode(False, True, False, False, True)
self.setViewMode(False, True, False, False, True, u'live')
def setViewMode(self, media=True, service=True, theme=True, preview=True,
live=True):
live=True, mode=u''):
"""
Set OpenLP to a different view mode.
"""
self.MediaManagerDock.setVisible(media)
self.ServiceManagerDock.setVisible(service)
self.ThemeManagerDock.setVisible(theme)
if mode:
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
mode)
self.mediaManagerDock.setVisible(media)
self.serviceManagerDock.setVisible(service)
self.themeManagerDock.setVisible(theme)
self.setPreviewPanelVisibility(preview)
self.setLivePanelVisibility(live)
@ -905,16 +868,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
theme)
def toggleMediaManager(self, visible):
if self.MediaManagerDock.isVisible() != visible:
self.MediaManagerDock.setVisible(visible)
if self.mediaManagerDock.isVisible() != visible:
self.mediaManagerDock.setVisible(visible)
def toggleServiceManager(self, visible):
if self.ServiceManagerDock.isVisible() != visible:
self.ServiceManagerDock.setVisible(visible)
if self.serviceManagerDock.isVisible() != visible:
self.serviceManagerDock.setVisible(visible)
def toggleThemeManager(self, visible):
if self.ThemeManagerDock.isVisible() != visible:
self.ThemeManagerDock.setVisible(visible)
if self.themeManagerDock.isVisible() != visible:
self.themeManagerDock.setVisible(visible)
def setPreviewPanelVisibility(self, visible):
"""
@ -926,7 +889,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
True - Visible
False - Hidden
"""
self.previewController.Panel.setVisible(visible)
self.previewController.panel.setVisible(visible)
QtCore.QSettings().setValue(u'user interface/preview panel',
QtCore.QVariant(visible))
self.ViewPreviewPanel.setChecked(visible)
@ -941,7 +904,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
True - Visible
False - Hidden
"""
self.liveController.Panel.setVisible(visible)
self.liveController.panel.setVisible(visible)
QtCore.QSettings().setValue(u'user interface/live panel',
QtCore.QVariant(visible))
self.ViewLivePanel.setChecked(visible)
@ -991,8 +954,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
self.FileMenu.clear()
add_actions(self.FileMenu, self.FileMenuActions[:-1])
existingRecentFiles = [file for file in self.recentFiles
if QtCore.QFile.exists(file)]
existingRecentFiles = [recentFile for recentFile in self.recentFiles
if QtCore.QFile.exists(recentFile)]
recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
if recentFilesToDisplay:
self.FileMenu.addSeparator()

View File

@ -28,13 +28,15 @@ import logging
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
log = logging.getLogger(__name__)
class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
"""
The plugin form provides user control over the plugins OpenLP uses.
"""
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.parent = parent
@ -129,7 +131,9 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
if self.programaticChange:
return
if status == 0:
Receiver.send_message(u'cursor_busy')
self.activePlugin.toggleStatus(PluginStatus.Active)
Receiver.send_message(u'cursor_normal')
else:
self.activePlugin.toggleStatus(PluginStatus.Inactive)
status_text = unicode(

View File

@ -0,0 +1,137 @@
# -*- 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 build_icon, translate, SpellTextEdit
class Ui_PrintServiceOrderDialog(object):
def setupUi(self, printServiceOrderDialog):
printServiceOrderDialog.setObjectName(u'printServiceOrderDialog')
self.dialogLayout = QtGui.QGridLayout(printServiceOrderDialog)
self.dialogLayout.setObjectName(u'dialogLayout')
self.perviewLayout = QtGui.QVBoxLayout()
self.perviewLayout.setObjectName(u'perviewLayout')
self.previewLabel = QtGui.QLabel(printServiceOrderDialog)
self.previewLabel.setSizePolicy(
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
self.previewLabel.setObjectName(u'previewLabel')
self.perviewLayout.addWidget(self.previewLabel)
self.previewWidget = QtGui.QPrintPreviewWidget(
self.printer, self, QtCore.Qt.Widget)
self.previewWidget.setEnabled(True)
self.previewWidget.setSizePolicy(
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding)
self.previewWidget.setObjectName(u'previewWidget')
# Give the previewWidget a fixed size, to prevent resizing when clicking
# the zoom buttons.
self.previewWidget.setFixedWidth(350)
self.perviewLayout.addWidget(self.previewWidget)
self.dialogLayout.addLayout(self.perviewLayout, 0, 0, 1, 1)
self.settingsLayout = QtGui.QVBoxLayout()
self.settingsLayout.setObjectName(u'settingsLayout')
self.serviceTitleLayout = QtGui.QGridLayout()
self.serviceTitleLayout.setObjectName(u'serviceTitleLayout')
self.serviceTitleLineEdit = QtGui.QLineEdit(printServiceOrderDialog)
self.serviceTitleLineEdit.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
self.serviceTitleLineEdit.setObjectName(u'serviceTitleLineEdit')
self.serviceTitleLayout.addWidget(self.serviceTitleLineEdit, 1, 1, 1, 1)
self.serviceTitleLabel = QtGui.QLabel(printServiceOrderDialog)
self.serviceTitleLabel.setSizePolicy(
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
self.serviceTitleLabel.setObjectName(u'serviceTitleLabel')
self.serviceTitleLayout.addWidget(self.serviceTitleLabel, 1, 0, 1, 1)
self.settingsLayout.addLayout(self.serviceTitleLayout)
self.printSlideTextCheckBox = QtGui.QCheckBox(printServiceOrderDialog)
self.printSlideTextCheckBox.setObjectName(u'printSlideTextCheckBox')
self.settingsLayout.addWidget(self.printSlideTextCheckBox)
self.printNotesCheckBox = QtGui.QCheckBox(printServiceOrderDialog)
self.printNotesCheckBox.setObjectName(u'printNotesCheckBox')
self.settingsLayout.addWidget(self.printNotesCheckBox)
self.printMetaDataCheckBox = QtGui.QCheckBox(printServiceOrderDialog)
self.printMetaDataCheckBox.setObjectName(u'printMetaDataCheckBox')
self.settingsLayout.addWidget(self.printMetaDataCheckBox)
spacerItem = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.settingsLayout.addItem(spacerItem)
self.customNotesLabel = QtGui.QLabel(self)
self.customNotesLabel.setObjectName(u'customNotesLabel')
self.settingsLayout.addWidget(self.customNotesLabel)
self.customNoteEdit = SpellTextEdit(self)
self.customNoteEdit.setObjectName(u'customNoteEdit')
self.settingsLayout.addWidget(self.customNoteEdit)
self.dialogLayout.addLayout(self.settingsLayout, 0, 3, 1, 1)
self.buttonLayout = QtGui.QHBoxLayout()
self.buttonLayout.setObjectName(u'buttonLayout')
spacerItem = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.buttonLayout.addItem(spacerItem)
self.cancelButton = QtGui.QPushButton(printServiceOrderDialog)
self.cancelButton.setObjectName(u'cancelButton')
self.buttonLayout.addWidget(self.cancelButton)
self.printButton = QtGui.QPushButton(printServiceOrderDialog)
self.printButton.setObjectName(u'printButton')
self.buttonLayout.addWidget(self.printButton)
self.dialogLayout.addLayout(self.buttonLayout, 1, 3, 1, 1)
self.zoomButtonLayout = QtGui.QHBoxLayout()
self.zoomButtonLayout.setObjectName(u'zoomButtonLayout')
spacerItem = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.zoomButtonLayout.addItem(spacerItem)
self.zoomOutButton = QtGui.QToolButton(printServiceOrderDialog)
self.zoomOutButton.setIcon(
build_icon(u':/general/general_zoom_out.png'))
self.zoomOutButton.setObjectName(u'zoomOutButton')
self.zoomButtonLayout.addWidget(self.zoomOutButton)
self.zoomInButton = QtGui.QToolButton(printServiceOrderDialog)
self.zoomInButton.setIcon(build_icon(u':/general/general_zoom_in.png'))
self.zoomInButton.setObjectName(u'zoomInButton')
self.zoomButtonLayout.addWidget(self.zoomInButton)
self.dialogLayout.addLayout(self.zoomButtonLayout, 1, 0, 1, 1)
self.retranslateUi(printServiceOrderDialog)
QtCore.QMetaObject.connectSlotsByName(printServiceOrderDialog)
def retranslateUi(self, printServiceOrderDialog):
printServiceOrderDialog.setWindowTitle(
translate('OpenLP.PrintServiceOrderForm', 'Print Service Order'))
self.previewLabel.setText(
translate('OpenLP.ServiceManager', '<b>Preview:</b>'))
self.printSlideTextCheckBox.setText(translate(
'OpenLP.PrintServiceOrderForm', 'Include slide text if available'))
self.printNotesCheckBox.setText(translate(
'OpenLP.PrintServiceOrderForm', 'Include service item notes'))
self.printMetaDataCheckBox.setText(
translate('OpenLP.PrintServiceOrderForm',
'Include play length of media items'))
self.serviceTitleLabel.setText(translate(
'OpenLP.PrintServiceOrderForm', 'Title:'))
self.serviceTitleLineEdit.setText(translate('OpenLP.ServiceManager',
'Service Order Sheet'))
self.printButton.setText(translate('OpenLP.ServiceManager', 'Print'))
self.cancelButton.setText(translate('OpenLP.ServiceManager', 'Cancel'))
self.customNotesLabel.setText(
translate('OpenLP.ServiceManager', '<b>Custom Service Notes:</b>'))

View File

@ -0,0 +1,184 @@
# -*- 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 #
###############################################################################
import datetime
import mutagen
import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
from openlp.core.ui.printserviceorderdialog import Ui_PrintServiceOrderDialog
class PrintServiceOrderForm(QtGui.QDialog, Ui_PrintServiceOrderDialog):
def __init__(self, parent, serviceManager):
"""
Constructor
"""
QtGui.QDialog.__init__(self, parent)
self.serviceManager = serviceManager
self.printer = QtGui.QPrinter()
self.printDialog = QtGui.QPrintDialog(self.printer, self)
self.document = QtGui.QTextDocument()
self.setupUi(self)
# Load the settings for the dialog.
settings = QtCore.QSettings()
settings.beginGroup(u'advanced')
self.printSlideTextCheckBox.setChecked(settings.value(
u'print slide text', QtCore.QVariant(False)).toBool())
self.printMetaDataCheckBox.setChecked(settings.value(
u'print file meta data', QtCore.QVariant(False)).toBool())
self.printNotesCheckBox.setChecked(settings.value(
u'print notes', QtCore.QVariant(False)).toBool())
settings.endGroup()
# Signals
QtCore.QObject.connect(self.printButton,
QtCore.SIGNAL(u'clicked()'), self.printServiceOrder)
QtCore.QObject.connect(self.zoomOutButton,
QtCore.SIGNAL(u'clicked()'), self.zoomOut)
QtCore.QObject.connect(self.zoomInButton,
QtCore.SIGNAL(u'clicked()'), self.zoomIn)
QtCore.QObject.connect(self.previewWidget,
QtCore.SIGNAL(u'paintRequested(QPrinter *)'), self.paintRequested)
QtCore.QObject.connect(self.serviceTitleLineEdit,
QtCore.SIGNAL(u'textChanged(const QString)'),
self.updatePreviewText)
QtCore.QObject.connect(self.printSlideTextCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.updatePreviewText)
QtCore.QObject.connect(self.printNotesCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.updatePreviewText)
QtCore.QObject.connect(self.printMetaDataCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.updatePreviewText)
QtCore.QObject.connect(self.customNoteEdit,
QtCore.SIGNAL(u'textChanged()'), self.updatePreviewText)
QtCore.QObject.connect(self.cancelButton,
QtCore.SIGNAL(u'clicked()'), self.reject)
self.updatePreviewText()
def updatePreviewText(self):
"""
Creates the html text and updates the html of *self.document*.
"""
text = u''
if self.serviceTitleLineEdit.text():
text += u'<h2>%s</h2>' % unicode(self.serviceTitleLineEdit.text())
for item in self.serviceManager.serviceItems:
item = item[u'service_item']
# Add the title of the service item.
text += u'<h4><img src="%s" /> %s</h4>' % (item.icon,
item.get_display_title())
# Add slide text of the service item.
if self.printSlideTextCheckBox.isChecked():
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
# Add service items' notes.
if self.printNotesCheckBox.isChecked():
if item.notes:
text += u'<p><b>%s</b></p>%s' % (translate(
'OpenLP.ServiceManager', 'Notes:'),
item.notes.replace(u'\n', u'<br />'))
# Add play length of media files.
if item.is_media() and self.printMetaDataCheckBox.isChecked():
path = os.path.join(item.get_frames()[0][u'path'],
item.get_frames()[0][u'title'])
if not os.path.isfile(path):
continue
file = mutagen.File(path)
if file is not None:
length = int(file.info.length)
text += u'<p><b>%s</b> %s</p>' % (translate(
'OpenLP.ServiceManager', u'Playing time:'),
unicode(datetime.timedelta(seconds=length)))
if self.customNoteEdit.toPlainText():
text += u'<h4>%s</h4>%s' % (translate('OpenLP.ServiceManager',
u'Custom Service Notes:'), self.customNoteEdit.toPlainText())
self.document.setHtml(text)
self.previewWidget.updatePreview()
def paintRequested(self, printer):
"""
Paint the preview of the *self.document*.
``printer``
A *QPrinter* object.
"""
self.document.print_(printer)
def printServiceOrder(self):
"""
Called, when the *printButton* is clicked. Opens the *printDialog*.
"""
if not self.printDialog.exec_():
return
# Print the document.
self.document.print_(self.printer)
self.accept()
def zoomIn(self):
"""
Called when *zoomInButton* is clicked.
"""
self.previewWidget.zoomIn()
def zoomOut(self):
"""
Called when *zoomOutButton* is clicked.
"""
self.previewWidget.zoomOut()
def accept(self):
"""
Save the settings and close the dialog.
"""
# Save the settings for this dialog.
settings = QtCore.QSettings()
settings.beginGroup(u'advanced')
settings.setValue(u'print slide text',
QtCore.QVariant(self.printSlideTextCheckBox.isChecked()))
settings.setValue(u'print file meta data',
QtCore.QVariant(self.printMetaDataCheckBox.isChecked()))
settings.setValue(u'print notes',
QtCore.QVariant(self.printNotesCheckBox.isChecked()))
settings.endGroup()
# Close the dialog.
return QtGui.QDialog.accept(self)
def reject(self):
"""
Close the dialog, do not print the service and do not save the settings.
"""
return QtGui.QDialog.reject(self)

View File

@ -26,7 +26,9 @@
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):
def setupUi(self, serviceItemEditDialog):
@ -39,30 +41,19 @@ class Ui_ServiceItemEditDialog(object):
self.dialogLayout.addWidget(self.listWidget, 0, 0)
self.buttonLayout = QtGui.QVBoxLayout()
self.buttonLayout.setObjectName(u'buttonLayout')
self.deleteButton = QtGui.QPushButton(serviceItemEditDialog)
self.deleteButton.setObjectName(u'deleteButton')
self.deleteButton = create_delete_push_button(serviceItemEditDialog)
self.buttonLayout.addWidget(self.deleteButton)
self.buttonLayout.addStretch()
self.upButton = QtGui.QPushButton(serviceItemEditDialog)
self.upButton.setIcon(build_icon(u':/services/service_up.png'))
self.upButton.setObjectName(u'upButton')
self.upButton, self.downButton = create_up_down_push_button_set(
serviceItemEditDialog)
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.dialogLayout.addLayout(self.buttonLayout, 0, 1)
self.buttonBox = QtGui.QDialogButtonBox(serviceItemEditDialog)
self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2)
self.dialogLayout.addWidget(
create_save_cancel_button_box(serviceItemEditDialog), 1, 0, 1, 2)
self.retranslateUi(serviceItemEditDialog)
QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog)
def retranslateUi(self, serviceItemEditDialog):
serviceItemEditDialog.setWindowTitle(
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)
self.setupUi(self)
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.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
@ -81,7 +70,7 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
item_name = QtGui.QListWidgetItem(frame[u'title'])
self.listWidget.addItem(item_name)
def onItemDelete(self):
def onDeleteButtonClicked(self):
"""
Delete the current row.
"""
@ -96,31 +85,34 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
else:
self.listWidget.setCurrentRow(row)
def onItemUp(self):
def onUpButtonClicked(self):
"""
Move the current row up in the list.
"""
item = self.listWidget.currentItem()
if not item:
return
row = self.listWidget.row(item)
temp = self.itemList[row]
self.itemList.remove(self.itemList[row])
self.itemList.insert(row - 1, temp)
self.loadData()
self.listWidget.setCurrentRow(row - 1)
self.__moveItem(u'up')
def onItemDown(self):
def onDownButtonClicked(self):
"""
Move the current row down in the list
"""
self.__moveItem(u'down')
def __moveItem(self, direction=u''):
"""
Move the current item.
"""
if not direction:
return
item = self.listWidget.currentItem()
if not item:
return
row = self.listWidget.row(item)
temp = self.itemList[row]
self.itemList.remove(self.itemList[row])
self.itemList.insert(row + 1, temp)
if direction == u'up':
self.itemList.insert(row - 1, temp)
else:
self.itemList.insert(row + 1, temp)
self.loadData()
self.listWidget.setCurrentRow(row + 1)

View File

@ -23,10 +23,9 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import os
import logging
import cPickle
import logging
import os
import zipfile
log = logging.getLogger(__name__)
@ -36,8 +35,9 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \
ThemeLevel
from openlp.core.ui import criticalErrorMessageBox, ServiceNoteForm, \
ServiceItemEditForm
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm
from openlp.core.ui.printserviceorderform import PrintServiceOrderForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
split_filename
@ -67,8 +67,8 @@ class ServiceManagerList(QtGui.QTreeWidget):
class ServiceManager(QtGui.QWidget):
"""
Manages the services. This involves taking text strings from plugins and
adding them to the service. This service can then be zipped up with all
Manages the services. This involves taking text strings from plugins and
adding them to the service. This service can then be zipped up with all
the resources used into one OSZ file for use on any OpenLP v2 installation.
Also handles the UI tasks of moving things up and down etc.
"""
@ -391,7 +391,7 @@ class ServiceManager(QtGui.QWidget):
return QtGui.QMessageBox.question(self.mainwindow,
translate('OpenLP.ServiceManager', 'Modified Service'),
translate('OpenLP.ServiceManager', 'The current service has '
'been modified. Would you like to save this service?'),
'been modified. Would you like to save this service?'),
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
@ -491,7 +491,7 @@ class ServiceManager(QtGui.QWidget):
for file in zip.namelist():
ucsfile = file_is_unicode(file)
if not ucsfile:
criticalErrorMessageBox(
critical_error_message_box(
message=translate('OpenLP.ServiceManager',
'File is not a valid service.\n'
'The content encoding is not UTF-8.'))
@ -506,6 +506,7 @@ class ServiceManager(QtGui.QWidget):
if filePath.endswith(u'osd'):
p_file = filePath
if 'p_file' in locals():
Receiver.send_message(u'cursor_busy')
fileTo = open(p_file, u'r')
items = cPickle.load(fileTo)
fileTo.close()
@ -520,13 +521,14 @@ class ServiceManager(QtGui.QWidget):
Receiver.send_message(u'%s_service_load' %
serviceItem.name.lower(), serviceItem)
delete_file(p_file)
Receiver.send_message(u'cursor_normal')
else:
criticalErrorMessageBox(
critical_error_message_box(
message=translate('OpenLP.ServiceManager',
'File is not a valid service.'))
log.exception(u'File contains no service data')
except (IOError, NameError):
log.exception(u'Problem loading a service file')
log.exception(u'Problem loading service file %s' % fileName)
finally:
if fileTo:
fileTo.close()
@ -536,9 +538,7 @@ class ServiceManager(QtGui.QWidget):
self.mainwindow.addRecentFile(fileName)
self.setModified(False)
QtCore.QSettings(). \
setValue(u'service/last file',QtCore.QVariant(fileName))
# Refresh Plugin lists
Receiver.send_message(u'plugin_list_refresh')
setValue(u'service/last file', QtCore.QVariant(fileName))
def loadLastFile(self):
"""
@ -856,7 +856,7 @@ class ServiceManager(QtGui.QWidget):
one it allows the item to be displayed.
"""
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:
serviceItem.is_valid = False
@ -993,7 +993,7 @@ class ServiceManager(QtGui.QWidget):
self.mainwindow.previewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], child)
else:
criticalErrorMessageBox(
critical_error_message_box(
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', 'Your item cannot be '
'displayed as there is no handler to display it'))
@ -1027,7 +1027,7 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems[item][u'service_item'], 0)
self.mainwindow.liveController.previewListWidget.setFocus()
else:
criticalErrorMessageBox(
critical_error_message_box(
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', 'Your item cannot be '
'displayed as the plugin required to display it is missing '
@ -1182,3 +1182,10 @@ class ServiceManager(QtGui.QWidget):
data_item[u'selected'] = (item == curitem)
data.append(data_item)
Receiver.send_message(u'servicemanager_list_response', data)
def printServiceOrder(self):
"""
Print a Service Order Sheet.
"""
settingDialog = PrintServiceOrderForm(self.mainwindow, self)
settingDialog.exec_()

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 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.
"""
@ -37,8 +38,19 @@ class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit):
Constructor
"""
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
self.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
self.reject)
self.setupUi()
self.retranslateUi()
def setupUi(self):
self.setObjectName(u'serviceNoteEdit')
self.dialogLayout = QtGui.QVBoxLayout(self)
self.dialogLayout.setObjectName(u'verticalLayout')
self.textEdit = QtGui.QTextEdit(self)
self.textEdit.setObjectName(u'textEdit')
self.dialogLayout.addWidget(self.textEdit)
self.dialogLayout.addWidget(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.phonon import Phonon
from openlp.core.ui import HideMode, MainDisplay
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
ItemCapabilities, translate
from openlp.core.lib.ui import UiStrings, shortcut_action
from openlp.core.ui import HideMode, MainDisplay
log = logging.getLogger(__name__)
@ -77,28 +78,27 @@ class SlideController(QtGui.QWidget):
self.selectedRow = 0
self.serviceItem = None
self.alertTab = None
self.Panel = QtGui.QWidget(parent.ControlSplitter)
self.panel = QtGui.QWidget(parent.controlSplitter)
self.slideList = {}
# Layout for holding panel
self.panelLayout = QtGui.QVBoxLayout(self.Panel)
self.panelLayout = QtGui.QVBoxLayout(self.panel)
self.panelLayout.setSpacing(0)
self.panelLayout.setMargin(0)
# Type label for the top of the slide controller
self.typeLabel = QtGui.QLabel(self.Panel)
self.typeLabel = QtGui.QLabel(self.panel)
if self.isLive:
self.typeLabel.setText(translate('OpenLP.SlideController', 'Live'))
self.typeLabel.setText(UiStrings.Live)
self.split = 1
self.typePrefix = u'live'
else:
self.typeLabel.setText(translate('OpenLP.SlideController',
'Preview'))
self.typeLabel.setText(UiStrings.Preview)
self.split = 0
self.typePrefix = u'preview'
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
self.panelLayout.addWidget(self.typeLabel)
# Splitter
self.splitter = QtGui.QSplitter(self.Panel)
self.splitter = QtGui.QSplitter(self.panel)
self.splitter.setOrientation(QtCore.Qt.Vertical)
self.panelLayout.addWidget(self.splitter)
# Actual controller section
@ -185,13 +185,13 @@ class SlideController(QtGui.QWidget):
u'Stop Loop', u':/media/media_stop.png',
translate('OpenLP.SlideController', 'Stop continuous loop'),
self.onStopLoop)
self.DelaySpinBox = QtGui.QSpinBox()
self.DelaySpinBox.setMinimum(1)
self.DelaySpinBox.setMaximum(180)
self.toolbar.addToolbarWidget(u'Image SpinBox', self.DelaySpinBox)
self.DelaySpinBox.setSuffix(translate('OpenLP.SlideController',
self.delaySpinBox = QtGui.QSpinBox()
self.delaySpinBox.setMinimum(1)
self.delaySpinBox.setMaximum(180)
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
self.delaySpinBox.setSuffix(translate('OpenLP.SlideController',
's'))
self.DelaySpinBox.setToolTip(translate('OpenLP.SlideController',
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
'Delay between slides in seconds'))
else:
self.toolbar.addToolbarSeparator(u'Close Separator')
@ -317,18 +317,8 @@ class SlideController(QtGui.QWidget):
self.mediabar.setVisible(False)
if self.isLive:
self.setLiveHotkeys(self)
self.previewListWidget.addActions(
[self.previousItem,
self.nextItem,
self.previousService,
self.nextService,
self.escapeItem])
self.display.addActions(
[self.previousItem,
self.nextItem,
self.previousService,
self.nextService,
self.escapeItem])
self.__addActionsToWidget(self.previewListWidget)
self.__addActionsToWidget(self.display)
else:
self.setPreviewHotkeys()
self.previewListWidget.addActions(
@ -390,28 +380,17 @@ class SlideController(QtGui.QWidget):
self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown])
self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
actionList.add_action(self.nextItem, u'Live')
self.previousService = QtGui.QAction(translate(
'OpenLP.SlideController', 'Previous Service'), parent)
self.previousService.setShortcuts([QtCore.Qt.Key_Left, 0])
self.previousService.setShortcutContext(
QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(self.previousService,
QtCore.SIGNAL(u'triggered()'), self.servicePrevious)
self.previousService = shortcut_action(parent,
translate('OpenLP.SlideController', 'Previous Service'),
[QtCore.Qt.Key_Left, 0], self.servicePrevious)
actionList.add_action(self.previousService, u'Live')
self.nextService = QtGui.QAction(translate(
'OpenLP.SlideController', 'Next Service'), parent)
self.nextService.setShortcuts([QtCore.Qt.Key_Right, 0])
self.nextService.setShortcutContext(
QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(self.nextService,
QtCore.SIGNAL(u'triggered()'), self.serviceNext)
self.nextService = shortcut_action(parent,
translate('OpenLP.SlideController', 'Next Service'),
[QtCore.Qt.Key_Right, 0], self.serviceNext)
actionList.add_action(self.nextService, u'Live')
self.escapeItem = QtGui.QAction(translate(
'OpenLP.SlideController', 'Escape Item'), parent)
self.escapeItem.setShortcuts([QtCore.Qt.Key_Escape, 0])
self.escapeItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(self.escapeItem,
QtCore.SIGNAL(u'triggered()'), self.liveEscape)
self.escapeItem = shortcut_action(parent,
translate('OpenLP.SlideController', 'Escape Item'),
[QtCore.Qt.Key_Escape, 0], self.liveEscape)
actionList.add_action(self.escapeItem, u'Live')
def liveEscape(self):
@ -435,12 +414,7 @@ class SlideController(QtGui.QWidget):
self.display.alertTab = self.alertTab
self.display.setup()
if self.isLive:
self.display.addActions(
[self.previousItem,
self.nextItem,
self.previousService,
self.nextService,
self.escapeItem])
self.__addActionsToWidget(self.display)
# The SlidePreview's ratio.
self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height())
@ -448,6 +422,12 @@ class SlideController(QtGui.QWidget):
if self.serviceItem:
self.refreshServiceItem()
def __addActionsToWidget(self, widget):
widget.addActions([
self.previousItem, self.nextItem,
self.previousService, self.nextService,
self.escapeItem])
def previewSizeChanged(self):
"""
Takes care of the SlidePreview's size. Is called when one of the the
@ -474,7 +454,7 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.resizeRowsToContents()
else:
# Sort out image heights.
width = self.parent.ControlSplitter.sizes()[self.split]
width = self.parent.controlSplitter.sizes()[self.split]
for framenumber in range(len(self.serviceItem.get_frames())):
self.previewListWidget.setRowHeight(
framenumber, width / self.ratio)
@ -482,18 +462,11 @@ class SlideController(QtGui.QWidget):
def onSongBarHandler(self):
request = unicode(self.sender().text())
slideno = self.slideList[request]
if slideno > self.previewListWidget.rowCount():
self.previewListWidget.selectRow(
self.previewListWidget.rowCount() - 1)
else:
if slideno + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(slideno + 1, 0))
self.previewListWidget.selectRow(slideno)
self.__updatePreviewSelection(slideno)
self.onSlideSelected()
def receiveSpinDelay(self, value):
self.DelaySpinBox.setValue(int(value))
self.delaySpinBox.setValue(int(value))
def enableToolBar(self, item):
"""
@ -582,10 +555,7 @@ class SlideController(QtGui.QWidget):
slideno = 0
# If service item is the same as the current on only change slide
if item.__eq__(self.serviceItem):
if slideno + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(slideno + 1, 0))
self.previewListWidget.selectRow(slideno)
self.__checkUpdateSelectedSlide(slideno)
self.onSlideSelected()
return
self._processItem(item, slideno)
@ -613,7 +583,7 @@ class SlideController(QtGui.QWidget):
Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
[serviceItem, self.isLive, blanked, slideno])
self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split]
width = self.parent.controlSplitter.sizes()[self.split]
self.serviceItem = serviceItem
self.previewListWidget.clear()
self.previewListWidget.setRowCount(0)
@ -665,14 +635,7 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.resizeRowsToContents()
self.previewListWidget.setColumnWidth(0,
self.previewListWidget.viewport().size().width())
if slideno > self.previewListWidget.rowCount():
self.previewListWidget.selectRow(
self.previewListWidget.rowCount() - 1)
else:
if slideno + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(slideno + 1, 0))
self.previewListWidget.selectRow(slideno)
self.__updatePreviewSelection(slideno)
self.enableToolBar(serviceItem)
# Pass to display for viewing
self.display.buildHtml(self.serviceItem)
@ -683,6 +646,16 @@ class SlideController(QtGui.QWidget):
Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix,
[serviceItem])
def __updatePreviewSelection(self, slideno):
"""
Utility method to update the selected slide in the list.
"""
if slideno > self.previewListWidget.rowCount():
self.previewListWidget.selectRow(
self.previewListWidget.rowCount() - 1)
else:
self.__checkUpdateSelectedSlide(slideno)
def onTextRequest(self):
"""
Return the text for the current item in controller
@ -730,10 +703,7 @@ class SlideController(QtGui.QWidget):
[self.serviceItem, self.isLive, index])
self.updatePreview()
else:
if index + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(index + 1, 0))
self.previewListWidget.selectRow(index)
self.__checkUpdateSelectedSlide(index)
self.onSlideSelected()
def mainDisplaySetBackground(self):
@ -892,10 +862,7 @@ class SlideController(QtGui.QWidget):
"""
The slide has been changed. Update the slidecontroller accordingly
"""
if row + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
self.__checkUpdateSelectedSlide(row)
self.updatePreview()
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row)
@ -906,7 +873,8 @@ class SlideController(QtGui.QWidget):
using *Blank to Theme*.
"""
log.debug(u'updatePreview %s ' % self.screens.current[u'primary'])
if not self.screens.current[u'primary']:
if not self.screens.current[u'primary'] and \
self.serviceItem.is_capable(ItemCapabilities.ProvidesOwnDisplay):
# Grab now, but try again in a couple of seconds if slide change
# is slow
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
@ -946,10 +914,7 @@ class SlideController(QtGui.QWidget):
else:
Receiver.send_message('servicemanager_next_item')
return
if row + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
self.__checkUpdateSelectedSlide(row)
self.onSlideSelected()
def onSlideSelectedPreviousNoloop(self):
@ -972,12 +937,15 @@ class SlideController(QtGui.QWidget):
row = self.previewListWidget.rowCount() - 1
else:
row = 0
if row + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
self.__checkUpdateSelectedSlide(row)
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):
"""
Go to the last slide.
@ -999,7 +967,7 @@ class SlideController(QtGui.QWidget):
"""
if self.previewListWidget.rowCount() > 1:
self.timer_id = self.startTimer(
int(self.DelaySpinBox.value()) * 1000)
int(self.delaySpinBox.value()) * 1000)
self.toolbar.actions[u'Stop Loop'].setVisible(True)
self.toolbar.actions[u'Start Loop'].setVisible(False)

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \
Receiver
from openlp.core.ui import criticalErrorMessageBox
from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.utils import get_images_filter
from themewizard import Ui_ThemeWizard
@ -272,14 +272,18 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
def onMainPositionCheckBoxStateChanged(self, value):
"""
Change state as Main Area Position check box changed
NOTE the font_main_override is the inverse of the check box value
"""
self.theme.font_main_override = (value == QtCore.Qt.Checked)
if self.updateThemeAllowed:
self.theme.font_main_override = not (value == QtCore.Qt.Checked)
def onFooterPositionCheckBoxStateChanged(self, value):
"""
Change state as Footer Area Position check box changed
NOTE the font_footer_override is the inverse of the check box value
"""
self.theme.font_footer_override = (value == QtCore.Qt.Checked)
if self.updateThemeAllowed:
self.theme.font_footer_override = not (value == QtCore.Qt.Checked)
def exec_(self, edit=False):
"""
@ -479,8 +483,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
Background Image button pushed.
"""
images_filter = get_images_filter()
images_filter = '%s;;%s (*.*) (*)' % (images_filter,
translate('OpenLP.ThemeForm', 'All Files'))
images_filter = '%s;;%s (*.*) (*)' % (images_filter, UiStrings.AllFiles)
filename = QtGui.QFileDialog.getOpenFileName(self,
translate('OpenLP.ThemeForm', 'Select Image'), u'',
images_filter)
@ -563,13 +566,13 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
# Save the theme name
self.theme.theme_name = unicode(self.field(u'name').toString())
if not self.theme.theme_name:
criticalErrorMessageBox(
critical_error_message_box(
translate('OpenLP.ThemeForm', 'Theme Name Missing'),
translate('OpenLP.ThemeForm',
'There is no name for this theme. Please enter one.'))
return
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None':
criticalErrorMessageBox(
critical_error_message_box(
translate('OpenLP.ThemeForm', 'Theme Name Invalid'),
translate('OpenLP.ThemeForm',
'Invalid theme name. Please enter one.'))

View File

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

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, Receiver, ThemeLevel, translate
from openlp.core.lib.ui import UiStrings
class ThemesTab(SettingsTab):
"""
@ -98,7 +99,7 @@ class ThemesTab(SettingsTab):
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
def retranslateUi(self):
self.tabTitleVisible = translate('OpenLP.ThemesTab', 'Themes')
self.tabTitleVisible = UiStrings.Themes
self.GlobalGroupBox.setTitle(
translate('OpenLP.ThemesTab', 'Global Theme'))
self.LevelGroupBox.setTitle(
@ -165,13 +166,7 @@ class ThemesTab(SettingsTab):
self.global_theme = unicode(self.DefaultComboBox.currentText())
self.parent.renderManager.set_global_theme(
self.global_theme, self.theme_level)
image = self.parent.ThemeManagerContents.getPreviewImage(
self.global_theme)
preview = QtGui.QPixmap(unicode(image))
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(preview)
self.__previewGlobalTheme()
def updateThemeList(self, theme_list):
"""
@ -198,10 +193,16 @@ class ThemesTab(SettingsTab):
self.parent.renderManager.set_global_theme(
self.global_theme, self.theme_level)
if self.global_theme is not u'':
image = self.parent.ThemeManagerContents.getPreviewImage(
self.global_theme)
preview = QtGui.QPixmap(unicode(image))
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(preview)
self.__previewGlobalTheme()
def __previewGlobalTheme(self):
"""
Utility method to update the global theme preview image.
"""
image = self.parent.ThemeManagerContents.getPreviewImage(
self.global_theme)
preview = QtGui.QPixmap(unicode(image))
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(preview)

View File

@ -27,32 +27,19 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, build_icon
from openlp.core.lib.ui import add_welcome_page, create_valign_combo
class Ui_ThemeWizard(object):
def setupUi(self, ThemeWizard):
ThemeWizard.setObjectName(u'OpenLP.ThemeWizard')
ThemeWizard.setModal(True)
ThemeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
ThemeWizard.setOptions(
QtGui.QWizard.IndependentPages |
def setupUi(self, themeWizard):
themeWizard.setObjectName(u'OpenLP.ThemeWizard')
themeWizard.setModal(True)
themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
themeWizard.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage)
self.spacer = QtGui.QSpacerItem(10, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
# Welcome Page
self.welcomePage = QtGui.QWizardPage()
self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
QtGui.QPixmap(u':/wizards/wizard_createtheme.bmp'))
self.welcomePage.setObjectName(u'WelcomePage')
self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
self.welcomeLayout.setObjectName(u'WelcomeLayout')
self.titleLabel = QtGui.QLabel(self.welcomePage)
self.titleLabel.setObjectName(u'TitleLabel')
self.welcomeLayout.addWidget(self.titleLabel)
self.welcomeLayout.addSpacing(40)
self.informationLabel = QtGui.QLabel(self.welcomePage)
self.informationLabel.setWordWrap(True)
self.informationLabel.setObjectName(u'InformationLabel')
self.welcomeLayout.addWidget(self.informationLabel)
self.welcomeLayout.addStretch()
ThemeWizard.addPage(self.welcomePage)
add_welcome_page(themeWizard, u':/wizards/wizard_createtheme.bmp')
# Background Page
self.backgroundPage = QtGui.QWizardPage()
self.backgroundPage.setObjectName(u'BackgroundPage')
@ -67,10 +54,8 @@ class Ui_ThemeWizard(object):
self.backgroundComboBox.setObjectName(u'BackgroundComboBox')
self.backgroundTypeLayout.addRow(self.backgroundLabel,
self.backgroundComboBox)
self.backgroundTypeSpacer = QtGui.QSpacerItem(10, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
self.backgroundTypeLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.backgroundTypeSpacer)
self.spacer)
self.backgroundLayout.addLayout(self.backgroundTypeLayout)
self.backgroundStack = QtGui.QStackedLayout()
self.backgroundStack.setObjectName(u'BackgroundStack')
@ -84,10 +69,7 @@ class Ui_ThemeWizard(object):
self.colorButton = QtGui.QPushButton(self.colorWidget)
self.colorButton.setObjectName(u'ColorButton')
self.colorLayout.addRow(self.colorLabel, self.colorButton)
self.colorSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.colorLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.colorSpacer)
self.colorLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
self.backgroundStack.addWidget(self.colorWidget)
self.gradientWidget = QtGui.QWidget(self.backgroundPage)
self.gradientWidget.setObjectName(u'GradientWidget')
@ -113,10 +95,7 @@ class Ui_ThemeWizard(object):
self.gradientComboBox.addItems([u'', u'', u'', u'', u''])
self.gradientLayout.addRow(self.gradientTypeLabel,
self.gradientComboBox)
self.gradientSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.gradientLayout.setItem(3, QtGui.QFormLayout.LabelRole,
self.gradientSpacer)
self.gradientLayout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer)
self.backgroundStack.addWidget(self.gradientWidget)
self.imageWidget = QtGui.QWidget(self.backgroundPage)
self.imageWidget.setObjectName(u'ImageWidget')
@ -136,13 +115,10 @@ class Ui_ThemeWizard(object):
build_icon(u':/general/general_open.png'))
self.imageFileLayout.addWidget(self.imageBrowseButton)
self.imageLayout.addRow(self.imageLabel, self.imageFileLayout)
self.imageSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.imageSpacer)
self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
self.backgroundStack.addWidget(self.imageWidget)
self.backgroundLayout.addLayout(self.backgroundStack)
ThemeWizard.addPage(self.backgroundPage)
themeWizard.addPage(self.backgroundPage)
# Main Area Page
self.mainAreaPage = QtGui.QWizardPage()
self.mainAreaPage.setObjectName(u'MainAreaPage')
@ -225,7 +201,7 @@ class Ui_ThemeWizard(object):
self.shadowSizeSpinBox.setObjectName(u'ShadowSizeSpinBox')
self.shadowLayout.addWidget(self.shadowSizeSpinBox)
self.mainAreaLayout.addRow(self.shadowCheckBox, self.shadowLayout)
ThemeWizard.addPage(self.mainAreaPage)
themeWizard.addPage(self.mainAreaPage)
# Footer Area Page
self.footerAreaPage = QtGui.QWizardPage()
self.footerAreaPage.setObjectName(u'FooterAreaPage')
@ -251,7 +227,9 @@ class Ui_ThemeWizard(object):
self.footerSizeSpinBox.setObjectName(u'FooterSizeSpinBox')
self.footerAreaLayout.addRow(self.footerSizeLabel,
self.footerSizeSpinBox)
ThemeWizard.addPage(self.footerAreaPage)
self.footerAreaLayout.setItem(3, QtGui.QFormLayout.LabelRole,
self.spacer)
themeWizard.addPage(self.footerAreaPage)
# Alignment Page
self.alignmentPage = QtGui.QWizardPage()
self.alignmentPage.setObjectName(u'AlignmentPage')
@ -264,19 +242,17 @@ class Ui_ThemeWizard(object):
self.horizontalComboBox.setObjectName(u'HorizontalComboBox')
self.alignmentLayout.addRow(self.horizontalLabel,
self.horizontalComboBox)
self.verticalLabel = QtGui.QLabel(self.alignmentPage)
self.verticalLabel.setObjectName(u'VerticalLabel')
self.verticalComboBox = QtGui.QComboBox(self.alignmentPage)
self.verticalComboBox.addItems([u'', u'', u''])
self.verticalComboBox.setObjectName(u'VerticalComboBox')
self.alignmentLayout.addRow(self.verticalLabel, self.verticalComboBox)
create_valign_combo(themeWizard, self.alignmentPage,
self.alignmentLayout)
self.transitionsLabel = QtGui.QLabel(self.alignmentPage)
self.transitionsLabel.setObjectName(u'TransitionsLabel')
self.transitionsCheckBox = QtGui.QCheckBox(self.alignmentPage)
self.transitionsCheckBox.setObjectName(u'TransitionsCheckBox')
self.alignmentLayout.addRow(self.transitionsLabel,
self.transitionsCheckBox)
ThemeWizard.addPage(self.alignmentPage)
self.alignmentLayout.setItem(3, QtGui.QFormLayout.LabelRole,
self.spacer)
themeWizard.addPage(self.alignmentPage)
# Area Position Page
self.areaPositionPage = QtGui.QWizardPage()
self.areaPositionPage.setObjectName(u'AreaPositionPage')
@ -352,7 +328,7 @@ class Ui_ThemeWizard(object):
self.footerPositionLayout.addRow(self.footerHeightLabel,
self.footerHeightSpinBox)
self.areaPositionLayout.addWidget(self.footerPositionGroupBox)
ThemeWizard.addPage(self.areaPositionPage)
themeWizard.addPage(self.areaPositionPage)
# Preview Page
self.previewPage = QtGui.QWizardPage()
self.previewPage.setObjectName(u'PreviewPage')
@ -381,9 +357,8 @@ class Ui_ThemeWizard(object):
self.previewBoxLabel.setObjectName(u'PreviewBoxLabel')
self.previewAreaLayout.addWidget(self.previewBoxLabel)
self.previewLayout.addWidget(self.previewArea)
ThemeWizard.addPage(self.previewPage)
self.retranslateUi(ThemeWizard)
themeWizard.addPage(self.previewPage)
self.retranslateUi(themeWizard)
QtCore.QObject.connect(self.backgroundComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'), self.backgroundStack,
QtCore.SLOT(u'setCurrentIndex(int)'))
@ -423,10 +398,10 @@ class Ui_ThemeWizard(object):
QtCore.QObject.connect(self.footerPositionCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.footerHeightSpinBox,
QtCore.SLOT(u'setDisabled(bool)'))
QtCore.QMetaObject.connectSlotsByName(ThemeWizard)
QtCore.QMetaObject.connectSlotsByName(themeWizard)
def retranslateUi(self, ThemeWizard):
ThemeWizard.setWindowTitle(
def retranslateUi(self, themeWizard):
themeWizard.setWindowTitle(
translate('OpenLP.ThemeWizard', 'Theme Wizard'))
self.titleLabel.setText(
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
@ -471,8 +446,7 @@ class Ui_ThemeWizard(object):
self.mainAreaPage.setSubTitle(
translate('OpenLP.ThemeWizard', 'Define the font and display '
'characteristics for the Display text'))
self.mainFontLabel.setText(
translate('OpenLP.ThemeWizard', 'Font:'))
self.mainFontLabel.setText(translate('OpenLP.ThemeWizard', 'Font:'))
self.mainColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
self.mainSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.mainSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
@ -486,8 +460,7 @@ class Ui_ThemeWizard(object):
self.shadowCheckBox.setText(translate('OpenLP.ThemeWizard', '&Shadow:'))
self.shadowSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.shadowSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
self.mainBoldCheckBox.setText(
translate('OpenLP.ThemeWizard', 'Bold'))
self.mainBoldCheckBox.setText(translate('OpenLP.ThemeWizard', 'Bold'))
self.mainItalicsCheckBox.setText(
translate('OpenLP.ThemeWizard', 'Italic'))
self.footerAreaPage.setTitle(
@ -512,14 +485,6 @@ class Ui_ThemeWizard(object):
translate('OpenLP.ThemeWizard', 'Right'))
self.horizontalComboBox.setItemText(2,
translate('OpenLP.ThemeWizard', 'Center'))
self.verticalLabel.setText(
translate('OpenLP.ThemeWizard', 'Vertical Align:'))
self.verticalComboBox.setItemText(0,
translate('OpenLP.ThemeWizard', 'Top'))
self.verticalComboBox.setItemText(1,
translate('OpenLP.ThemeWizard', 'Middle'))
self.verticalComboBox.setItemText(2,
translate('OpenLP.ThemeWizard', 'Bottom'))
self.transitionsLabel.setText(
translate('OpenLP.ThemeWizard', 'Transitions:'))
self.areaPositionPage.setTitle(
@ -568,16 +533,6 @@ class Ui_ThemeWizard(object):
translate('OpenLP.ThemeWizard', 'Theme name:'))
# Align all QFormLayouts towards each other.
labelWidth = max(self.backgroundLabel.minimumSizeHint().width(),
self.colorLabel.minimumSizeHint().width(),
self.gradientStartLabel.minimumSizeHint().width(),
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,
self.horizontalLabel.minimumSizeHint().width())
self.spacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)

View File

@ -31,6 +31,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, Receiver
from openlp.core.lib.ui import add_welcome_page
log = logging.getLogger(__name__)
@ -63,36 +64,12 @@ class OpenLPWizard(QtGui.QWizard):
self.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.NoBackButtonOnLastPage)
self.addWelcomePage(image)
add_welcome_page(self, image)
self.addCustomPages()
self.addProgressPage()
self.retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self)
def addWelcomePage(self, image):
"""
Add the opening welcome page to the wizard.
``image``
A splash image for the wizard
"""
self.welcomePage = QtGui.QWizardPage()
self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
QtGui.QPixmap(image))
self.welcomePage.setObjectName(u'WelcomePage')
self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
self.welcomeLayout.setObjectName(u'WelcomeLayout')
self.titleLabel = QtGui.QLabel(self.welcomePage)
self.titleLabel.setObjectName(u'TitleLabel')
self.welcomeLayout.addWidget(self.titleLabel)
self.welcomeLayout.addSpacing(40)
self.informationLabel = QtGui.QLabel(self.welcomePage)
self.informationLabel.setWordWrap(True)
self.informationLabel.setObjectName(u'InformationLabel')
self.welcomeLayout.addWidget(self.informationLabel)
self.welcomeLayout.addStretch()
self.addPage(self.welcomePage)
def addProgressPage(self):
"""
Add the progress page for the wizard. This page informs the user how

View File

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

View File

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

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate
from openlp.core.lib.ui import UiStrings, create_valign_combo
class AlertsTab(SettingsTab):
"""
@ -40,48 +41,43 @@ class AlertsTab(SettingsTab):
def setupUi(self):
self.setObjectName(u'AlertsTab')
SettingsTab.setupUi(self)
self.FontGroupBox = QtGui.QGroupBox(self.leftColumn)
self.FontGroupBox.setObjectName(u'FontGroupBox')
self.FontLayout = QtGui.QFormLayout(self.FontGroupBox)
self.FontLayout.setObjectName(u'FontLayout')
self.FontLabel = QtGui.QLabel(self.FontGroupBox)
self.fontGroupBox = QtGui.QGroupBox(self.leftColumn)
self.fontGroupBox.setObjectName(u'fontGroupBox')
self.fontLayout = QtGui.QFormLayout(self.fontGroupBox)
self.fontLayout.setObjectName(u'fontLayout')
self.FontLabel = QtGui.QLabel(self.fontGroupBox)
self.FontLabel.setObjectName(u'FontLabel')
self.FontComboBox = QtGui.QFontComboBox(self.FontGroupBox)
self.FontComboBox = QtGui.QFontComboBox(self.fontGroupBox)
self.FontComboBox.setObjectName(u'FontComboBox')
self.FontLayout.addRow(self.FontLabel, self.FontComboBox)
self.FontColorLabel = QtGui.QLabel(self.FontGroupBox)
self.fontLayout.addRow(self.FontLabel, self.FontComboBox)
self.FontColorLabel = QtGui.QLabel(self.fontGroupBox)
self.FontColorLabel.setObjectName(u'FontColorLabel')
self.ColorLayout = QtGui.QHBoxLayout()
self.ColorLayout.setObjectName(u'ColorLayout')
self.FontColorButton = QtGui.QPushButton(self.FontGroupBox)
self.FontColorButton = QtGui.QPushButton(self.fontGroupBox)
self.FontColorButton.setObjectName(u'FontColorButton')
self.ColorLayout.addWidget(self.FontColorButton)
self.ColorLayout.addSpacing(20)
self.BackgroundColorLabel = QtGui.QLabel(self.FontGroupBox)
self.BackgroundColorLabel = QtGui.QLabel(self.fontGroupBox)
self.BackgroundColorLabel.setObjectName(u'BackgroundColorLabel')
self.ColorLayout.addWidget(self.BackgroundColorLabel)
self.BackgroundColorButton = QtGui.QPushButton(self.FontGroupBox)
self.BackgroundColorButton = QtGui.QPushButton(self.fontGroupBox)
self.BackgroundColorButton.setObjectName(u'BackgroundColorButton')
self.ColorLayout.addWidget(self.BackgroundColorButton)
self.FontLayout.addRow(self.FontColorLabel, self.ColorLayout)
self.FontSizeLabel = QtGui.QLabel(self.FontGroupBox)
self.fontLayout.addRow(self.FontColorLabel, self.ColorLayout)
self.FontSizeLabel = QtGui.QLabel(self.fontGroupBox)
self.FontSizeLabel.setObjectName(u'FontSizeLabel')
self.FontSizeSpinBox = QtGui.QSpinBox(self.FontGroupBox)
self.FontSizeSpinBox = QtGui.QSpinBox(self.fontGroupBox)
self.FontSizeSpinBox.setObjectName(u'FontSizeSpinBox')
self.FontLayout.addRow(self.FontSizeLabel, self.FontSizeSpinBox)
self.TimeoutLabel = QtGui.QLabel(self.FontGroupBox)
self.fontLayout.addRow(self.FontSizeLabel, self.FontSizeSpinBox)
self.TimeoutLabel = QtGui.QLabel(self.fontGroupBox)
self.TimeoutLabel.setObjectName(u'TimeoutLabel')
self.TimeoutSpinBox = QtGui.QSpinBox(self.FontGroupBox)
self.TimeoutSpinBox = QtGui.QSpinBox(self.fontGroupBox)
self.TimeoutSpinBox.setMaximum(180)
self.TimeoutSpinBox.setObjectName(u'TimeoutSpinBox')
self.FontLayout.addRow(self.TimeoutLabel, self.TimeoutSpinBox)
self.LocationLabel = QtGui.QLabel(self.FontGroupBox)
self.LocationLabel.setObjectName(u'LocationLabel')
self.LocationComboBox = QtGui.QComboBox(self.FontGroupBox)
self.LocationComboBox.addItems([u'', u'', u''])
self.LocationComboBox.setObjectName(u'LocationComboBox')
self.FontLayout.addRow(self.LocationLabel, self.LocationComboBox)
self.leftLayout.addWidget(self.FontGroupBox)
self.fontLayout.addRow(self.TimeoutLabel, self.TimeoutSpinBox)
create_valign_combo(self, self.fontGroupBox, self.fontLayout)
self.leftLayout.addWidget(self.fontGroupBox)
self.leftLayout.addStretch()
self.PreviewGroupBox = QtGui.QGroupBox(self.rightColumn)
self.PreviewGroupBox.setObjectName(u'PreviewGroupBox')
@ -99,15 +95,13 @@ class AlertsTab(SettingsTab):
QtCore.SIGNAL(u'pressed()'), self.onFontColorButtonClicked)
QtCore.QObject.connect(self.FontComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontComboBoxClicked)
QtCore.QObject.connect(self.LocationComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onLocationComboBoxClicked)
QtCore.QObject.connect(self.TimeoutSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
QtCore.QObject.connect(self.FontSizeSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged)
def retranslateUi(self):
self.FontGroupBox.setTitle(
self.fontGroupBox.setTitle(
translate('AlertsPlugin.AlertsTab', 'Font'))
self.FontLabel.setText(
translate('AlertsPlugin.AlertsTab', 'Font name:'))
@ -123,18 +117,8 @@ class AlertsTab(SettingsTab):
translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
self.TimeoutSpinBox.setSuffix(
translate('AlertsPlugin.AlertsTab', 's'))
self.LocationLabel.setText(
translate('AlertsPlugin.AlertsTab', 'Location:'))
self.PreviewGroupBox.setTitle(
translate('AlertsPlugin.AlertsTab', 'Preview'))
self.FontPreview.setText(
translate('AlertsPlugin.AlertsTab', 'OpenLP 2.0'))
self.LocationComboBox.setItemText(0,
translate('AlertsPlugin.AlertsTab', 'Top'))
self.LocationComboBox.setItemText(1,
translate('AlertsPlugin.AlertsTab', 'Middle'))
self.LocationComboBox.setItemText(2,
translate('AlertsPlugin.AlertsTab', 'Bottom'))
self.PreviewGroupBox.setTitle(UiStrings.Preview)
self.FontPreview.setText(UiStrings.OLPV2)
def onBackgroundColorButtonClicked(self):
new_color = QtGui.QColorDialog.getColor(
@ -148,9 +132,6 @@ class AlertsTab(SettingsTab):
def onFontComboBoxClicked(self):
self.updateDisplay()
def onLocationComboBoxClicked(self, location):
self.location = location
def onFontColorButtonClicked(self):
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.font_color), self)
@ -188,7 +169,7 @@ class AlertsTab(SettingsTab):
u'background-color: %s' % self.font_color)
self.BackgroundColorButton.setStyleSheet(
u'background-color: %s' % self.bg_color)
self.LocationComboBox.setCurrentIndex(self.location)
self.verticalComboBox.setCurrentIndex(self.location)
font = QtGui.QFont()
font.setFamily(self.font_face)
self.FontComboBox.setCurrentFont(font)
@ -197,14 +178,14 @@ class AlertsTab(SettingsTab):
def save(self):
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
self.font_face = self.FontComboBox.currentFont().family()
settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
settings.setValue(u'font color', QtCore.QVariant(self.font_color))
settings.setValue(u'font size', QtCore.QVariant(self.font_size))
self.font_face = self.FontComboBox.currentFont().family()
settings.setValue(u'font face', QtCore.QVariant(self.font_face))
settings.setValue(u'timeout', QtCore.QVariant(self.timeout))
settings.setValue(u'location',
QtCore.QVariant(self.LocationComboBox.currentIndex()))
self.location = self.verticalComboBox.currentIndex()
settings.setValue(u'location', QtCore.QVariant(self.location))
settings.endGroup()
def updateDisplay(self):

View File

@ -29,6 +29,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import UiStrings
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
log = logging.getLogger(__name__)
@ -102,7 +103,7 @@ class BiblePlugin(Plugin):
Called to find out if the bible plugin is currently using a theme.
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 False
@ -119,6 +120,7 @@ class BiblePlugin(Plugin):
The new name the plugin should now use.
"""
self.settings_tab.bible_theme = newTheme
self.settings_tab.save()
def setPluginTextStrings(self):
"""
@ -136,38 +138,38 @@ class BiblePlugin(Plugin):
# Middle Header Bar
## Import Action ##
self.textStrings[StringContent.Import] = {
u'title': translate('BiblesPlugin', '&Import'),
u'title': UiStrings.Import,
u'tooltip': translate('BiblesPlugin', 'Import a Bible')
}
## New Action ##
self.textStrings[StringContent.New] = {
u'title': translate('BiblesPlugin', '&Add'),
u'title': UiStrings.Add,
u'tooltip': translate('BiblesPlugin', 'Add a new Bible')
}
## Edit Action ##
self.textStrings[StringContent.Edit] = {
u'title': translate('BiblesPlugin', '&Edit'),
u'title': UiStrings.Edit,
u'tooltip': translate('BiblesPlugin', 'Edit the selected Bible')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('BiblesPlugin', '&Delete'),
u'title': UiStrings.Delete,
u'tooltip': translate('BiblesPlugin', 'Delete the selected Bible')
}
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('BiblesPlugin', 'Preview'),
u'title': UiStrings.Preview,
u'tooltip': translate('BiblesPlugin', 'Preview the selected Bible')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('BiblesPlugin', 'Live'),
u'title': UiStrings.Live,
u'tooltip': translate('BiblesPlugin',
'Send the selected Bible live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('BiblesPlugin', 'Service'),
u'title': UiStrings.Service,
u'tooltip': translate('BiblesPlugin',
'Add the selected Bible to the service')
}

View File

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

View File

@ -33,6 +33,13 @@ import re
log = logging.getLogger(__name__)
def get_reference_match(match_type):
"""
Provides the regexes and matches to use while parsing strings for bible
references.
``match_type``
The type of reference information trying to be extracted in this call.
"""
local_separator = unicode(u':;;\s*[:vV]\s*;;-;;\s*-\s*;;,;;\s*,\s*;;end'
).split(u';;') # English
# local_separator = unicode(u',;;\s*,\s*;;-;;\s*-\s*;;.;;\.;;[Ee]nde'
@ -77,9 +84,9 @@ def parse_reference(reference):
- After a verse reference all further single values are treat as verse in
the last selected chapter.
``John 3:16-18`` refers to John chapter 3 verses 16 to 18
- After a list separator it is possible to refer to additional verses. They
are build analog to the first ones. This way it is possible to define
each number of verse references. It is not possible to refer to verses in
- After a list separator it is possible to refer to additional verses. They
are build analog to the first ones. This way it is possible to define each
number of verse references. It is not possible to refer to verses in
additional books.
``John 3:16,18`` refers to John chapter 3 verses 16 and 18
``John 3:16-18,20`` refers to John chapter 3 verses 16 to 18 and 20
@ -91,7 +98,7 @@ def parse_reference(reference):
``range_string`` is a regular expression which matches for verse range
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
a verse separator.
2. ``(?P<from_verse>[0-9]+)``
@ -105,7 +112,7 @@ def parse_reference(reference):
5. ``(?P<to_verse>[0-9]+)``
The ``to_verse`` reference is equivalent to group 2.
The full reference is matched against get_reference_match(u'full'). This
The full reference is matched against get_reference_match(u'full'). This
regular expression looks like this:
1. ``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*``
@ -113,7 +120,7 @@ def parse_reference(reference):
are optional leading digits followed by non-digits. The group ends
before the whitspace in front of the next digit.
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.
The reference list is a list of tuples, with each tuple structured like

View File

@ -50,14 +50,17 @@ The format of the books file is:
...
40,2,Matthew,Matt
The format of the verses file is:
There are two acceptable formats of the verses file. They are:
<book_id>,<chapter_number>,<verse_number>,<verse_text>
or
<book_name>,<chapter_number>,<verse_number>,<verse_text>
For example:
1,1,1,"In the beginning God created the heaven and the earth."
1,1,2,"And the earth was without form, and void; and darkness...."
or
"Genesis",1,2,"And the earth was without form, and void; and...."
All CSV files are expected to use a comma (',') as the delimeter and double
quotes ('"') as the quote symbol.
@ -172,15 +175,22 @@ class CSVBible(BibleDB):
for line in verse_reader:
if self.stop_import_flag:
break
if book_ptr != book_list[int(line[0])]:
book = self.get_book(book_list[int(line[0])])
try:
line_book = book_list[int(line[0])]
except ValueError:
line_book = unicode(line[0], details['encoding'])
if book_ptr != line_book:
book = self.get_book(line_book)
book_ptr = book.name
self.wizard.incrementProgressBar(unicode(translate(
'BibleDB.Wizard', 'Importing verses from %s...',
'Importing verses from <book name>...')) % book.name)
self.session.commit()
self.create_verse(book.id, line[1], line[2],
unicode(line[3], details['encoding']))
try:
verse_text = unicode(line[3], details['encoding'])
except UnicodeError:
verse_text = unicode(line[3], u'cp1252')
self.create_verse(book.id, line[1], line[2], verse_text)
self.wizard.incrementProgressBar(translate('BibleDB.Wizard',
'Importing verses... done.'))
Receiver.send_message(u'openlp_process_events')

View File

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

View File

@ -38,7 +38,7 @@ from HTMLParser import HTMLParseError
from BeautifulSoup import BeautifulSoup, NavigableString
from openlp.core.lib import Receiver, translate
from openlp.core.ui import criticalErrorMessageBox
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.utils import AppLocation, get_web_page
from openlp.plugins.bibles.lib import SearchResults
from openlp.plugins.bibles.lib.db import BibleDB, Book
@ -210,7 +210,8 @@ class BGExtract(object):
cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')]
soup = get_soup_for_bible_ref(
u'http://www.biblegateway.com/passage/?%s' % url_params,
cleaner=cleaner)
pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='',
cleaner=cleaner)
if not soup:
return None
Receiver.send_message(u'openlp_process_events')
@ -430,7 +431,7 @@ class HTTPBible(BibleDB):
if not db_book:
book_details = HTTPBooks.get_book(book)
if not book_details:
criticalErrorMessageBox(
critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching '
'book could be found in this Bible. Check that you '
@ -442,7 +443,6 @@ class HTTPBible(BibleDB):
book = db_book.name
if BibleDB.get_verse_count(self, book, reference[1]) == 0:
Receiver.send_message(u'cursor_busy')
Receiver.send_message(u'openlp_process_events')
search_results = self.get_chapter(book, reference[1])
if search_results and search_results.has_verselist():
## We have found a book of the bible lets check to see
@ -499,7 +499,8 @@ class HTTPBible(BibleDB):
"""
return HTTPBooks.get_verse_count(book, chapter)
def get_soup_for_bible_ref(reference_url, header=None, cleaner=None):
def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None,
pre_parse_substitute=None, cleaner=None):
"""
Gets a webpage and returns a parsed and optionally cleaned soup or None.
@ -509,6 +510,13 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None):
``header``
An optional HTTP header to pass to the bible web server.
``pre_parse_regex``
A regular expression to run on the webpage. Allows manipulation of the
webpage before passing to BeautifulSoup for parsing.
``pre_parse_substitute``
The text to replace any matches to the regular expression with.
``cleaner``
An optional regex to use during webpage parsing.
"""
@ -518,12 +526,15 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None):
if not page:
send_error_message(u'download')
return None
page_source = page.read()
if pre_parse_regex and pre_parse_substitute is not None:
page_source = re.sub(pre_parse_regex, pre_parse_substitute, page_source)
soup = None
try:
if cleaner:
soup = BeautifulSoup(page, markupMassage=cleaner)
soup = BeautifulSoup(page_source, markupMassage=cleaner)
else:
soup = BeautifulSoup(page)
soup = BeautifulSoup(page_source)
except HTMLParseError:
log.exception(u'BeautifulSoup could not parse the bible page.')
if not soup:
@ -540,14 +551,14 @@ def send_error_message(error_type):
The type of error that occured for the issue.
"""
if error_type == u'download':
criticalErrorMessageBox(
critical_error_message_box(
translate('BiblePlugin.HTTPBible', 'Download Error'),
translate('BiblePlugin.HTTPBible', 'There was a '
'problem downloading your verse selection. Please check your '
'Internet connection, and if this error continues to occur '
'please consider reporting a bug.'))
elif error_type == u'parse':
criticalErrorMessageBox(
critical_error_message_box(
translate('BiblePlugin.HTTPBible', 'Parse Error'),
translate('BiblePlugin.HTTPBible', 'There was a '
'problem extracting your verse selection. If this error continues '

View File

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

View File

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

View File

@ -30,6 +30,7 @@ from forms import EditCustomForm
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.db import Manager
from openlp.core.lib.ui import UiStrings
from openlp.plugins.custom.lib import CustomMediaItem, CustomTab
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
@ -114,49 +115,49 @@ class CustomPlugin(Plugin):
# Middle Header Bar
## Import Action ##
self.textStrings[StringContent.Import] = {
u'title': translate('CustomsPlugin', 'Import'),
u'title': UiStrings.Import,
u'tooltip': translate('CustomsPlugin',
'Import a Custom')
}
## Load Action ##
self.textStrings[StringContent.Load] = {
u'title': translate('CustomsPlugin', 'Load'),
u'title': UiStrings.Load,
u'tooltip': translate('CustomsPlugin',
'Load a new Custom')
}
## New Action ##
self.textStrings[StringContent.New] = {
u'title': translate('CustomsPlugin', 'Add'),
u'title': UiStrings.Add,
u'tooltip': translate('CustomsPlugin',
'Add a new Custom')
}
## Edit Action ##
self.textStrings[StringContent.Edit] = {
u'title': translate('CustomsPlugin', 'Edit'),
u'title': UiStrings.Edit,
u'tooltip': translate('CustomsPlugin',
'Edit the selected Custom')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('CustomsPlugin', 'Delete'),
u'title': UiStrings.Delete,
u'tooltip': translate('CustomsPlugin',
'Delete the selected Custom')
}
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('CustomsPlugin', 'Preview'),
u'title': UiStrings.Preview,
u'tooltip': translate('CustomsPlugin',
'Preview the selected Custom')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('CustomsPlugin', 'Live'),
u'title': UiStrings.Live,
u'tooltip': translate('CustomsPlugin',
'Send the selected Custom live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('CustomsPlugin', 'Service'),
u'title': UiStrings.Service,
u'tooltip': translate('CustomsPlugin',
'Add the selected Custom to the service')
}

View File

@ -27,6 +27,8 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate
from openlp.core.lib.ui import UiStrings, create_save_cancel_button_box, \
create_delete_push_button, create_up_down_push_button_set
class Ui_CustomEditDialog(object):
def setupUi(self, customEditDialog):
@ -58,22 +60,21 @@ class Ui_CustomEditDialog(object):
self.addButton.setObjectName(u'addButton')
self.buttonLayout.addWidget(self.addButton)
self.editButton = QtGui.QPushButton(customEditDialog)
self.editButton.setEnabled(False)
self.editButton.setObjectName(u'editButton')
self.buttonLayout.addWidget(self.editButton)
self.editAllButton = QtGui.QPushButton(customEditDialog)
self.editAllButton.setObjectName(u'editAllButton')
self.buttonLayout.addWidget(self.editAllButton)
self.deleteButton = QtGui.QPushButton(customEditDialog)
self.deleteButton.setObjectName(u'deleteButton')
self.deleteButton = create_delete_push_button(customEditDialog)
self.deleteButton.setEnabled(False)
self.buttonLayout.addWidget(self.deleteButton)
self.buttonLayout.addStretch()
self.upButton = QtGui.QPushButton(customEditDialog)
self.upButton.setIcon(build_icon(u':/services/service_up.png'))
self.upButton.setObjectName(u'upButton')
self.upButton, self.downButton = create_up_down_push_button_set(
customEditDialog)
self.upButton.setEnabled(False)
self.downButton.setEnabled(False)
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.centralLayout.addLayout(self.buttonLayout)
self.dialogLayout.addLayout(self.centralLayout)
@ -93,36 +94,24 @@ class Ui_CustomEditDialog(object):
self.creditLabel.setBuddy(self.creditEdit)
self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit)
self.dialogLayout.addLayout(self.bottomFormLayout)
self.buttonBox = QtGui.QDialogButtonBox(customEditDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.buttonBox = create_save_cancel_button_box(customEditDialog)
self.previewButton = QtGui.QPushButton()
self.buttonBox.addButton(
self.previewButton, QtGui.QDialogButtonBox.ActionRole)
self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(customEditDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
customEditDialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
customEditDialog.closePressed)
QtCore.QMetaObject.connectSlotsByName(customEditDialog)
def retranslateUi(self, customEditDialog):
customEditDialog.setWindowTitle(
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(
translate('CustomPlugin.EditCustomForm', '&Title:'))
self.addButton.setText(
translate('CustomPlugin.EditCustomForm', '&Add'))
self.addButton.setText(UiStrings.Add)
self.addButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Add a new slide at '
'bottom.'))
self.editButton.setText(
translate('CustomPlugin.EditCustomForm', '&Edit'))
self.editButton.setText(UiStrings.Edit)
self.editButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit the selected '
'slide.'))
@ -131,12 +120,9 @@ class Ui_CustomEditDialog(object):
self.editAllButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit all the slides at '
'once.'))
self.deleteButton.setText(
translate('CustomPlugin.EditCustomForm', '&Delete'))
self.deleteButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Delete the selected '
'slide.'))
self.themeLabel.setText(
translate('CustomPlugin.EditCustomForm', 'The&me:'))
self.creditLabel.setText(
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 openlp.core.lib import Receiver, translate
from openlp.core.ui import criticalErrorMessageBox
from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide
from editcustomdialog import Ui_CustomEditDialog
@ -48,52 +48,22 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
"""
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
# Create other objects and forms.
self.manager = manager
self.editSlideForm = EditCustomSlideForm(self)
# Connecting signals and slots
self.previewButton = QtGui.QPushButton()
self.previewButton.setText(
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.previewButton,
QtCore.SIGNAL(u'pressed()'), self.onPreviewButtonPressed)
QtCore.QObject.connect(self.addButton,
QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed)
QtCore.QObject.connect(self.editButton,
QtCore.SIGNAL(u'pressed()'), self.onEditButtonPressed)
QtCore.QObject.connect(self.editAllButton,
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.SIGNAL(u'theme_update_list'), self.loadThemes)
# Create other objects and forms.
self.manager = manager
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()
QtCore.QObject.connect(self.slideListView,
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
def loadThemes(self, themelist):
self.themeComboBox.clear()
@ -112,9 +82,13 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
States whether the custom is edited while being previewed in the
preview panel.
"""
self.customSlide = CustomSlide()
self.initialise()
if id != 0:
self.slideListView.clear()
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.titleEdit.setText(self.customSlide.title)
self.creditEdit.setText(self.customSlide.credits)
@ -128,31 +102,26 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
if id == -1:
id = 0
self.themeComboBox.setCurrentIndex(id)
else:
self.themeComboBox.setCurrentIndex(0)
self.editAllButton.setEnabled(False)
# If not preview hide the preview button.
self.previewButton.setVisible(False)
if preview:
self.previewButton.setVisible(True)
def closePressed(self):
def reject(self):
Receiver.send_message(u'custom_edit_clear')
self.close()
QtGui.QDialog.reject(self)
def accept(self):
log.debug(u'accept')
if self.saveCustom():
Receiver.send_message(u'custom_load_list')
self.close()
QtGui.QDialog.accept(self)
def saveCustom(self):
"""
Saves the custom.
"""
valid, message = self._validate()
if not valid:
criticalErrorMessageBox(message=message)
if not self._validate():
return False
sxml = CustomXMLBuilder()
sxml.new_document()
@ -168,14 +137,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.customSlide.theme_name = unicode(self.themeComboBox.currentText())
return self.manager.save_object(self.customSlide)
def onUpButtonPressed(self):
def onUpButtonClicked(self):
selectedRow = self.slideListView.currentRow()
if selectedRow != 0:
qw = self.slideListView.takeItem(selectedRow)
self.slideListView.insertItem(selectedRow - 1, qw)
self.slideListView.setCurrentRow(selectedRow - 1)
def onDownButtonPressed(self):
def onDownButtonClicked(self):
selectedRow = self.slideListView.currentRow()
# zero base arrays
if selectedRow != self.slideListView.count() - 1:
@ -183,16 +152,11 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.slideListView.insertItem(selectedRow + 1, qw)
self.slideListView.setCurrentRow(selectedRow + 1)
def onSlideListViewPressed(self, item):
self.deleteButton.setEnabled(True)
self.editButton.setEnabled(True)
def onAddButtonPressed(self):
self.editSlideForm.setText(u'')
if self.editSlideForm.exec_():
for slide in self.editSlideForm.getText():
self.slideListView.addItem(slide)
self.editAllButton.setEnabled(True)
def onEditButtonPressed(self):
self.editSlideForm.setText(self.slideListView.currentItem().text())
@ -203,16 +167,23 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
"""
Edits all slides.
"""
if self.slideListView.count() > 0:
slide_list = u''
for row in range(0, self.slideListView.count()):
item = self.slideListView.item(row)
slide_list += item.text()
if row != self.slideListView.count() - 1:
slide_list += u'\n[---]\n'
self.editSlideForm.setText(slide_list)
if self.editSlideForm.exec_():
self.updateSlideList(self.editSlideForm.getText(), True)
slide_list = u''
for row in range(0, self.slideListView.count()):
item = self.slideListView.item(row)
slide_list += item.text()
if row != self.slideListView.count() - 1:
slide_list += u'\n[---]\n'
self.editSlideForm.setText(slide_list)
if self.editSlideForm.exec_():
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):
"""
@ -243,14 +214,41 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.slideListView.addItem(slide)
self.slideListView.repaint()
def onDeleteButtonPressed(self):
def onDeleteButtonClicked(self):
"""
Removes the current row from the list.
"""
self.slideListView.takeItem(self.slideListView.currentRow())
self.editButton.setEnabled(True)
self.editAllButton.setEnabled(True)
if self.slideListView.count() == 0:
if self.slideListView.currentRow() == 0:
self.upButton.setEnabled(False)
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.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):
"""
@ -259,10 +257,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
# We must have a title.
if len(self.titleEdit.displayText()) == 0:
self.titleEdit.setFocus()
return False, translate('CustomPlugin.EditCustomForm',
'You need to type in a title.')
critical_error_message_box(
message=translate('CustomPlugin.EditCustomForm',
'You need to type in a title.'))
return False
# We must have at least one slide.
if self.slideListView.count() == 0:
return False, translate('CustomPlugin.EditCustomForm',
'You need to add at least one slide')
return True, u''
critical_error_message_box(
message=translate('CustomPlugin.EditCustomForm',
'You need to add at least one slide'))
return False
return True

View File

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

View File

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

View File

@ -27,6 +27,7 @@
import logging
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import UiStrings
from openlp.plugins.images.lib import ImageMediaItem
log = logging.getLogger(__name__)
@ -74,43 +75,43 @@ class ImagePlugin(Plugin):
# Middle Header Bar
## Load Button ##
self.textStrings[StringContent.Load] = {
u'title': translate('ImagePlugin', 'Load'),
u'title': UiStrings.Load,
u'tooltip': translate('ImagePlugin',
'Load a new Image')
}
## New Button ##
self.textStrings[StringContent.New] = {
u'title': translate('ImagePlugin', 'Add'),
u'title': UiStrings.Add,
u'tooltip': translate('ImagePlugin',
'Add a new Image')
}
## Edit Button ##
self.textStrings[StringContent.Edit] = {
u'title': translate('ImagePlugin', 'Edit'),
u'title': UiStrings.Edit,
u'tooltip': translate('ImagePlugin',
'Edit the selected Image')
}
## Delete Button ##
self.textStrings[StringContent.Delete] = {
u'title': translate('ImagePlugin', 'Delete'),
u'title': UiStrings.Delete,
u'tooltip': translate('ImagePlugin',
'Delete the selected Image')
}
## Preview ##
self.textStrings[StringContent.Preview] = {
u'title': translate('ImagePlugin', 'Preview'),
u'title': UiStrings.Preview,
u'tooltip': translate('ImagePlugin',
'Preview the selected Image')
}
## Live Button ##
self.textStrings[StringContent.Live] = {
u'title': translate('ImagePlugin', 'Live'),
u'title': UiStrings.Live,
u'tooltip': translate('ImagePlugin',
'Send the selected Image live')
}
## Add to service Button ##
self.textStrings[StringContent.Service] = {
u'title': translate('ImagePlugin', 'Service'),
u'title': UiStrings.Service,
u'tooltip': translate('ImagePlugin',
'Add the selected Image to the service')
}

View File

@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
ItemCapabilities, SettingsManager, translate, check_item_selected, \
check_directory_exists, Receiver
from openlp.core.ui import criticalErrorMessageBox
from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.utils import AppLocation, delete_file, get_images_filter
log = logging.getLogger(__name__)
@ -64,7 +64,7 @@ class ImageMediaItem(MediaManagerItem):
'Select Image(s)')
file_formats = get_images_filter()
self.OnNewFileMasks = u'%s;;%s (*.*) (*)' % (file_formats,
unicode(translate('ImagePlugin.MediaItem', 'All Files')))
unicode(UiStrings.AllFiles))
self.replaceAction.setText(
translate('ImagePlugin.MediaItem', 'Replace Background'))
self.replaceAction.setToolTip(
@ -84,8 +84,6 @@ class ImageMediaItem(MediaManagerItem):
def initialise(self):
log.debug(u'initialise')
self.listView.clear()
self.listView.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
self.listView.setIconSize(QtCore.QSize(88, 50))
self.servicePath = os.path.join(
AppLocation.get_section_data_path(self.settingsSection),
@ -123,26 +121,26 @@ class ImageMediaItem(MediaManagerItem):
self.settingsSection, self.getFileList())
def loadList(self, list):
for file in list:
filename = os.path.split(unicode(file))[1]
for imageFile in list:
filename = os.path.split(unicode(imageFile))[1]
thumb = os.path.join(self.servicePath, filename)
if os.path.exists(thumb):
if self.validate(file, thumb):
if self.validate(imageFile, thumb):
icon = build_icon(thumb)
else:
icon = build_icon(u':/general/general_delete.png')
else:
icon = self.iconFromFile(file, thumb)
icon = self.iconFromFile(imageFile, thumb)
item_name = QtGui.QListWidgetItem(filename)
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)
def generateSlideData(self, service_item, item=None, xmlVersion=False):
items = self.listView.selectedIndexes()
if items:
service_item.title = unicode(
translate('ImagePlugin.MediaItem', 'Image(s)'))
translate('ImagePlugin.MediaItem', 'Images'))
service_item.add_capability(ItemCapabilities.AllowsMaintain)
service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop)
@ -161,7 +159,7 @@ class ImageMediaItem(MediaManagerItem):
items.remove(item)
# We cannot continue, as all images do not exist.
if not items:
criticalErrorMessageBox(
critical_error_message_box(
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
unicode(translate('ImagePlugin.MediaItem',
'The following image(s) no longer exist: %s')) %
@ -214,7 +212,7 @@ class ImageMediaItem(MediaManagerItem):
self.parent.liveController.display.directImage(name, filename)
self.resetAction.setVisible(True)
else:
criticalErrorMessageBox(
critical_error_message_box(
translate('ImagePlugin.MediaItem', 'Live Background Error'),
unicode(translate('ImagePlugin.MediaItem',
'There was a problem replacing your background, '

View File

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

View File

@ -30,6 +30,7 @@ import mimetypes
from PyQt4.phonon import Phonon
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import UiStrings
from openlp.plugins.media.lib import MediaMediaItem, MediaTab
log = logging.getLogger(__name__)
@ -103,43 +104,43 @@ class MediaPlugin(Plugin):
# Middle Header Bar
## Load Action ##
self.textStrings[StringContent.Load] = {
u'title': translate('MediaPlugin', 'Load'),
u'title': UiStrings.Load,
u'tooltip': translate('MediaPlugin',
'Load a new Media')
}
## New Action ##
self.textStrings[StringContent.New] = {
u'title': translate('MediaPlugin', 'Add'),
u'title': UiStrings.Add,
u'tooltip': translate('MediaPlugin',
'Add a new Media')
}
## Edit Action ##
self.textStrings[StringContent.Edit] = {
u'title': translate('MediaPlugin', 'Edit'),
u'title': UiStrings.Edit,
u'tooltip': translate('MediaPlugin',
'Edit the selected Media')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('MediaPlugin', 'Delete'),
u'title': UiStrings.Delete,
u'tooltip': translate('MediaPlugin',
'Delete the selected Media')
}
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('MediaPlugin', 'Preview'),
u'title': UiStrings.Preview,
u'tooltip': translate('MediaPlugin',
'Preview the selected Media')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('MediaPlugin', 'Live'),
u'title': UiStrings.Live,
u'tooltip': translate('MediaPlugin',
'Send the selected Media live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('MediaPlugin', 'Service'),
u'title': UiStrings.Service,
u'tooltip': translate('MediaPlugin',
'Add the selected Media to the service')
}

View File

@ -69,7 +69,8 @@ class ImpressController(PresentationController):
Initialise the class
"""
log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Impress')
PresentationController.__init__(self, plugin, u'Impress',
ImpressDocument)
self.supports = [u'odp']
self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx']
self.process = None
@ -183,14 +184,6 @@ class ImpressController(PresentationController):
except:
log.exception(u'Failed to terminate OpenOffice')
def add_doc(self, name):
"""
Called when a new Impress document is opened
"""
log.debug(u'Add Doc OpenOffice')
doc = ImpressDocument(self, name)
self.docs.append(doc)
return doc
class ImpressDocument(PresentationDocument):
"""
@ -431,35 +424,36 @@ class ImpressDocument(PresentationDocument):
def get_slide_text(self, slide_no):
"""
Returns the text on the slide
Returns the text on the slide.
``slide_no``
The slide the text is required for, starting at 1
The slide the text is required for, starting at 1
"""
return __get_text_from_slide(slide_no)
def get_slide_notes(self, slide_no):
"""
Returns the text in the slide notes.
``slide_no``
The slide the notes are required for, starting at 1
"""
return __get_text_from_page(slide_no, True)
def __get_text_from_page(self, slide_no, notes=False):
"""
Return any text extracted from the presentation page.
``notes``
A boolean. If set the method searches the notes of the slide.
"""
doc = self.document
pages = doc.getDrawPages()
text = ''
pages = self.document.getDrawPages()
page = pages.getByIndex(slide_no - 1)
if notes:
page = page.getNotesPage()
for idx in range(page.getCount()):
shape = page.getByIndex(idx)
if shape.supportsService("com.sun.star.drawing.Text"):
text += shape.getString() + '\n'
return text
def get_slide_notes(self, slide_no):
"""
Returns the text on the slide
``slide_no``
The slide the notes are required for, starting at 1
"""
doc = self.document
pages = doc.getDrawPages()
text = ''
page = pages.getByIndex(slide_no - 1)
notes = page.getNotesPage()
for idx in range(notes.getCount()):
shape = notes.getByIndex(idx)
if shape.supportsService("com.sun.star.drawing.Text"):
text += shape.getString() + '\n'
return text

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
SettingsManager, translate, check_item_selected, Receiver, ItemCapabilities
from openlp.core.ui import criticalErrorMessageBox
from openlp.core.lib.ui import critical_error_message_box, media_item_combo_box
from openlp.plugins.presentations.lib import MessageListener
log = logging.getLogger(__name__)
@ -116,12 +116,8 @@ class PresentationMediaItem(MediaManagerItem):
self.displayLayout.setObjectName(u'displayLayout')
self.displayTypeLabel = QtGui.QLabel(self.presentationWidget)
self.displayTypeLabel.setObjectName(u'displayTypeLabel')
self.displayTypeComboBox = QtGui.QComboBox(self.presentationWidget)
self.displayTypeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.displayTypeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.displayTypeComboBox.setObjectName(u'displayTypeComboBox')
self.displayTypeComboBox = media_item_combo_box(
self.presentationWidget, u'displayTypeComboBox')
self.displayTypeLabel.setBuddy(self.displayTypeComboBox)
self.displayLayout.addRow(self.displayTypeLabel,
self.displayTypeComboBox)
@ -181,7 +177,7 @@ class PresentationMediaItem(MediaManagerItem):
filename = os.path.split(unicode(file))[1]
if titles.count(filename) > 0:
if not initialLoad:
criticalErrorMessageBox(
critical_error_message_box(
translate('PresentationPlugin.MediaItem',
'File Exists'),
translate('PresentationPlugin.MediaItem',
@ -190,7 +186,7 @@ class PresentationMediaItem(MediaManagerItem):
controller_name = self.findControllerByType(filename)
if controller_name:
controller = self.controllers[controller_name]
doc = controller.add_doc(unicode(file))
doc = controller.add_document(unicode(file))
thumb = os.path.join(doc.get_thumbnail_folder(), u'icon.png')
preview = doc.get_thumbnail_path(1, True)
if not preview and not initialLoad:
@ -205,7 +201,7 @@ class PresentationMediaItem(MediaManagerItem):
if initialLoad:
icon = build_icon(u':/general/general_delete.png')
else:
criticalErrorMessageBox(
critical_error_message_box(
self, translate('PresentationPlugin.MediaItem',
'Unsupported File'),
translate('PresentationPlugin.MediaItem',
@ -230,7 +226,7 @@ class PresentationMediaItem(MediaManagerItem):
filepath = unicode(item.data(
QtCore.Qt.UserRole).toString())
for cidx in self.controllers:
doc = self.controllers[cidx].add_doc(filepath)
doc = self.controllers[cidx].add_document(filepath)
doc.presentation_deleted()
doc.close_presentation()
for row in row_list:
@ -264,7 +260,7 @@ class PresentationMediaItem(MediaManagerItem):
return False
controller = self.controllers[service_item.shortname]
(path, name) = os.path.split(filename)
doc = controller.add_doc(filename)
doc = controller.add_document(filename)
if doc.get_thumbnail_path(1, True) is None:
doc.load_presentation()
i = 1
@ -278,7 +274,7 @@ class PresentationMediaItem(MediaManagerItem):
return True
else:
# File is no longer present
criticalErrorMessageBox(
critical_error_message_box(
translate('PresentationPlugin.MediaItem',
'Missing Presentation'),
unicode(translate('PresentationPlugin.MediaItem',
@ -287,7 +283,7 @@ class PresentationMediaItem(MediaManagerItem):
return False
else:
# File is no longer present
criticalErrorMessageBox(
critical_error_message_box(
translate('PresentationPlugin.MediaItem',
'Missing Presentation'),
unicode(translate('PresentationPlugin.MediaItem',

View File

@ -59,7 +59,7 @@ class Controller(object):
self.controller = controller
if self.doc is not None:
self.shutdown()
self.doc = self.controller.add_doc(file)
self.doc = self.controller.add_document(file)
if not self.doc.load_presentation():
# Display error message to user
# Inform slidecontroller that the action failed?
@ -116,7 +116,7 @@ class Controller(object):
def last(self):
"""
Based on the handler passed at startup triggers the first slide
Based on the handler passed at startup triggers the last slide
"""
log.debug(u'Live = %s, last' % self.is_live)
if not self.is_live:

View File

@ -53,7 +53,8 @@ class PowerpointController(PresentationController):
Initialise the class
"""
log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Powerpoint')
PresentationController.__init__(self, plugin, u'Powerpoint',
PowerpointDocument)
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
self.process = None
@ -97,14 +98,6 @@ class PowerpointController(PresentationController):
pass
self.process = None
def add_doc(self, name):
"""
Called when a new powerpoint document is opened
"""
log.debug(u'Add Doc PowerPoint')
doc = PowerpointDocument(self, name)
self.docs.append(doc)
return doc
class PowerpointDocument(PresentationDocument):
"""
@ -291,13 +284,7 @@ class PowerpointDocument(PresentationDocument):
``slide_no``
The slide the text is required for, starting at 1.
"""
text = ''
shapes = self.presentation.Slides(slide_no).Shapes
for idx in range(shapes.Count):
shape = shapes(idx + 1)
if shape.HasTextFrame:
text += shape.TextFrame.TextRange.Text + '\n'
return text
return _get_text_from_shapes(self.presentation.Slides(slide_no).Shapes)
def get_slide_notes(self, slide_no):
"""
@ -306,10 +293,19 @@ class PowerpointDocument(PresentationDocument):
``slide_no``
The slide the notes are required for, starting at 1.
"""
text = ''
shapes = self.presentation.Slides(slide_no).NotesPage.Shapes
for idx in range(shapes.Count):
shape = shapes(idx + 1)
if shape.HasTextFrame:
text += shape.TextFrame.TextRange.Text + '\n'
return text
return _get_text_from_shapes(
self.presentation.Slides(slide_no).NotesPage.Shapes)
def _get_text_from_shapes(shapes):
"""
Returns any text extracted from the shapes on a presentation slide.
``shapes``
A set of shapes to search for text.
"""
text = ''
for idx in range(shapes.Count):
shape = shapes(idx + 1)
if shape.HasTextFrame:
text += shape.TextFrame.TextRange.Text + '\n'
return text

View File

@ -49,7 +49,8 @@ class PptviewController(PresentationController):
"""
log.debug(u'Initialising')
self.process = None
PresentationController.__init__(self, plugin, u'Powerpoint Viewer')
PresentationController.__init__(self, plugin, u'Powerpoint Viewer',
PptviewDocument)
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
def check_available(self):
@ -93,14 +94,6 @@ class PptviewController(PresentationController):
while self.docs:
self.docs[0].close_presentation()
def add_doc(self, name):
"""
Called when a new powerpoint document is opened
"""
log.debug(u'Add Doc PPTView')
doc = PptviewDocument(self, name)
self.docs.append(doc)
return doc
class PptviewDocument(PresentationDocument):
"""
@ -247,4 +240,4 @@ class PptviewDocument(PresentationDocument):
"""
Triggers the previous slide on the running presentation
"""
self.controller.process.PrevStep(self.pptid)
self.controller.process.PrevStep(self.pptid)

View File

@ -35,151 +35,6 @@ from openlp.core.utils import AppLocation
log = logging.getLogger(__name__)
class PresentationController(object):
"""
This class is used to control interactions with presentation applications
by creating a runtime environment. This is a base class for presentation
controllers to inherit from.
To create a new controller, take a copy of this file and name it so it ends
with ``controller.py``, i.e. ``foobarcontroller.py``. Make sure it inherits
:class:`~openlp.plugins.presentations.lib.presentationcontroller.PresentationController`,
and then fill in the blanks. If possible try to make sure it loads on all
platforms, usually by using :mod:``os.name`` checks, although
``__init__``, ``check_available`` and ``presentation_deleted`` should
always be implemented.
See :class:`~openlp.plugins.presentations.lib.impresscontroller.ImpressController`,
:class:`~openlp.plugins.presentations.lib.powerpointcontroller.PowerpointController` or
:class:`~openlp.plugins.presentations.lib.pptviewcontroller.PptviewController`
for examples.
**Basic Attributes**
``name``
The name that appears in the options and the media manager
``enabled``
The controller is enabled
``available``
The controller is available on this machine. Set by init via
call to check_available
``plugin``
The presentationplugin object
``supports``
The primary native file types this application supports
``alsosupports``
Other file types the application can import, although not necessarily
the first choice due to potential incompatibilities
**Hook Functions**
``kill()``
Called at system exit to clean up any running presentations
``check_available()``
Returns True if presentation application is installed/can run on this
machine
``presentation_deleted()``
Deletes presentation specific files, e.g. thumbnails
"""
log.info(u'PresentationController loaded')
def __init__(self, plugin=None, name=u'PresentationController'):
"""
This is the constructor for the presentationcontroller object. This
provides an easy way for descendent plugins to populate common data.
This method *must* be overridden, like so::
class MyPresentationController(PresentationController):
def __init__(self, plugin):
PresentationController.__init(
self, plugin, u'My Presenter App')
``plugin``
Defaults to *None*. The presentationplugin object
``name``
Name of the application, to appear in the application
"""
self.supports = []
self.alsosupports = []
self.docs = []
self.plugin = plugin
self.name = name
self.settings_section = self.plugin.settingsSection
self.available = self.check_available()
self.temp_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section), name)
self.thumbnail_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section),
u'thumbnails')
self.thumbnail_prefix = u'slide'
if not os.path.isdir(self.thumbnail_folder):
os.makedirs(self.thumbnail_folder)
if not os.path.isdir(self.temp_folder):
os.makedirs(self.temp_folder)
def enabled(self):
"""
Return whether the controller is currently enabled
"""
if self.available:
return QtCore.QSettings().value(
self.settings_section + u'/' + self.name,
QtCore.QVariant(QtCore.Qt.Checked)).toInt()[0] == \
QtCore.Qt.Checked
else:
return False
def check_available(self):
"""
Presentation app is able to run on this machine
"""
return False
def start_process(self):
"""
Loads a running version of the presentation application in the
background.
"""
pass
def kill(self):
"""
Called at system exit to clean up any running presentations and
close the application
"""
log.debug(u'Kill')
self.close_presentation()
def add_doc(self, name):
"""
Called when a new presentation document is opened
"""
doc = PresentationDocument(self, name)
self.docs.append(doc)
return doc
def remove_doc(self, doc=None):
"""
Called to remove an open document from the collection
"""
log.debug(u'remove_doc Presentation')
if doc is None:
return
if doc in self.docs:
self.docs.remove(doc)
def close_presentation(self):
pass
class PresentationDocument(object):
"""
Base class for presentation documents to inherit from.
@ -440,4 +295,152 @@ class PresentationDocument(object):
``slide_no``
The slide the notes are required for, starting at 1
"""
return ''
return ''
class PresentationController(object):
"""
This class is used to control interactions with presentation applications
by creating a runtime environment. This is a base class for presentation
controllers to inherit from.
To create a new controller, take a copy of this file and name it so it ends
with ``controller.py``, i.e. ``foobarcontroller.py``. Make sure it inherits
:class:`~openlp.plugins.presentations.lib.presentationcontroller.PresentationController`,
and then fill in the blanks. If possible try to make sure it loads on all
platforms, usually by using :mod:``os.name`` checks, although
``__init__``, ``check_available`` and ``presentation_deleted`` should
always be implemented.
See :class:`~openlp.plugins.presentations.lib.impresscontroller.ImpressController`,
:class:`~openlp.plugins.presentations.lib.powerpointcontroller.PowerpointController` or
:class:`~openlp.plugins.presentations.lib.pptviewcontroller.PptviewController`
for examples.
**Basic Attributes**
``name``
The name that appears in the options and the media manager
``enabled``
The controller is enabled
``available``
The controller is available on this machine. Set by init via
call to check_available
``plugin``
The presentationplugin object
``supports``
The primary native file types this application supports
``alsosupports``
Other file types the application can import, although not necessarily
the first choice due to potential incompatibilities
**Hook Functions**
``kill()``
Called at system exit to clean up any running presentations
``check_available()``
Returns True if presentation application is installed/can run on this
machine
``presentation_deleted()``
Deletes presentation specific files, e.g. thumbnails
"""
log.info(u'PresentationController loaded')
def __init__(self, plugin=None, name=u'PresentationController',
document_class=PresentationDocument):
"""
This is the constructor for the presentationcontroller object. This
provides an easy way for descendent plugins to populate common data.
This method *must* be overridden, like so::
class MyPresentationController(PresentationController):
def __init__(self, plugin):
PresentationController.__init(
self, plugin, u'My Presenter App')
``plugin``
Defaults to *None*. The presentationplugin object
``name``
Name of the application, to appear in the application
"""
self.supports = []
self.alsosupports = []
self.docs = []
self.plugin = plugin
self.name = name
self.document_class = document_class
self.settings_section = self.plugin.settingsSection
self.available = self.check_available()
self.temp_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section), name)
self.thumbnail_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section),
u'thumbnails')
self.thumbnail_prefix = u'slide'
if not os.path.isdir(self.thumbnail_folder):
os.makedirs(self.thumbnail_folder)
if not os.path.isdir(self.temp_folder):
os.makedirs(self.temp_folder)
def enabled(self):
"""
Return whether the controller is currently enabled
"""
if self.available:
return QtCore.QSettings().value(
self.settings_section + u'/' + self.name,
QtCore.QVariant(QtCore.Qt.Checked)).toInt()[0] == \
QtCore.Qt.Checked
else:
return False
def check_available(self):
"""
Presentation app is able to run on this machine
"""
return False
def start_process(self):
"""
Loads a running version of the presentation application in the
background.
"""
pass
def kill(self):
"""
Called at system exit to clean up any running presentations and
close the application
"""
log.debug(u'Kill')
self.close_presentation()
def add_document(self, name):
"""
Called when a new presentation document is opened
"""
document = self.document_class(self, name)
self.docs.append(document)
return document
def remove_doc(self, doc=None):
"""
Called to remove an open document from the collection
"""
log.debug(u'remove_doc Presentation')
if doc is None:
return
if doc in self.docs:
self.docs.remove(doc)
def close_presentation(self):
pass

View File

@ -31,6 +31,7 @@ import os
import logging
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import UiStrings
from openlp.core.utils import AppLocation
from openlp.plugins.presentations.lib import PresentationController, \
PresentationMediaItem, PresentationTab
@ -74,7 +75,11 @@ class PresentationPlugin(Plugin):
self.insertToolboxItem()
for controller in self.controllers:
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()
def finalise(self):
@ -165,31 +170,31 @@ class PresentationPlugin(Plugin):
# Middle Header Bar
## Load Action ##
self.textStrings[StringContent.Load] = {
u'title': translate('PresentationPlugin', 'Load'),
u'title': UiStrings.Load,
u'tooltip': translate('PresentationPlugin',
'Load a new Presentation')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('PresentationPlugin', 'Delete'),
u'title': UiStrings.Delete,
u'tooltip': translate('PresentationPlugin',
'Delete the selected Presentation')
}
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('PresentationPlugin', 'Preview'),
u'title': UiStrings.Preview,
u'tooltip': translate('PresentationPlugin',
'Preview the selected Presentation')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('PresentationPlugin', 'Live'),
u'title': UiStrings.Live,
u'tooltip': translate('PresentationPlugin',
'Send the selected Presentation live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('PresentationPlugin', 'Service'),
u'title': UiStrings.Service,
u'tooltip': translate('PresentationPlugin',
'Add the selected Presentation to the service')
}

View File

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

View File

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

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate
from openlp.core.lib.ui import UiStrings, create_save_cancel_button_box
class Ui_EditSongDialog(object):
def setupUi(self, editSongDialog):
@ -111,14 +112,8 @@ class Ui_EditSongDialog(object):
self.authorsLayout.setObjectName(u'authorsLayout')
self.authorAddLayout = QtGui.QHBoxLayout()
self.authorAddLayout.setObjectName(u'authorAddLayout')
self.authorsComboBox = QtGui.QComboBox(self.authorsGroupBox)
self.authorsComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.authorsComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.authorsComboBox.setEditable(True)
self.authorsComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.authorsComboBox.setObjectName(u'authorsComboBox')
self.authorsComboBox = editSongDialogComboBox(
self.authorsGroupBox, u'authorsComboBox')
self.authorAddLayout.addWidget(self.authorsComboBox)
self.authorAddButton = QtGui.QPushButton(self.authorsGroupBox)
self.authorAddButton.setObjectName(u'authorAddButton')
@ -152,14 +147,8 @@ class Ui_EditSongDialog(object):
self.topicsLayout.setObjectName(u'topicsLayout')
self.topicAddLayout = QtGui.QHBoxLayout()
self.topicAddLayout.setObjectName(u'topicAddLayout')
self.topicsComboBox = QtGui.QComboBox(self.topicsGroupBox)
self.topicsComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.topicsComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.topicsComboBox.setEditable(True)
self.topicsComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.topicsComboBox.setObjectName(u'topicsComboBox')
self.topicsComboBox = editSongDialogComboBox(
self.topicsGroupBox, u'topicsComboBox')
self.topicAddLayout.addWidget(self.topicsComboBox)
self.topicAddButton = QtGui.QPushButton(self.topicsGroupBox)
self.topicAddButton.setObjectName(u'topicAddButton')
@ -183,14 +172,8 @@ class Ui_EditSongDialog(object):
self.songBookLayout.setObjectName(u'songBookLayout')
self.songBookNameLabel = QtGui.QLabel(self.songBookGroupBox)
self.songBookNameLabel.setObjectName(u'songBookNameLabel')
self.songBookComboBox = QtGui.QComboBox(self.songBookGroupBox)
self.songBookComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.songBookComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.songBookComboBox.setEditable(True)
self.songBookComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.songBookComboBox.setObjectName(u'songBookComboBox')
self.songBookComboBox = editSongDialogComboBox(
self.songBookGroupBox, u'songBookComboBox')
self.songBookNameLabel.setBuddy(self.songBookComboBox)
self.songBookLayout.addRow(self.songBookNameLabel,
self.songBookComboBox)
@ -215,14 +198,8 @@ class Ui_EditSongDialog(object):
self.themeGroupBox.setObjectName(u'themeGroupBox')
self.themeLayout = QtGui.QHBoxLayout(self.themeGroupBox)
self.themeLayout.setObjectName(u'themeLayout')
self.themeComboBox = QtGui.QComboBox(self.themeGroupBox)
self.themeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.themeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.themeComboBox.setEditable(True)
self.themeComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.themeComboBox.setObjectName(u'themeComboBox')
self.themeComboBox = editSongDialogComboBox(
self.themeGroupBox, u'themeComboBox')
self.themeLayout.addWidget(self.themeComboBox)
self.themeAddButton = QtGui.QPushButton(self.themeGroupBox)
self.themeAddButton.setObjectName(u'themeAddButton')
@ -264,16 +241,9 @@ class Ui_EditSongDialog(object):
self.themeTabLayout.addWidget(self.commentsGroupBox)
self.songTabWidget.addTab(self.themeTab, u'')
self.dialogLayout.addWidget(self.songTabWidget)
self.buttonBox = QtGui.QDialogButtonBox(editSongDialog)
self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.buttonBox = create_save_cancel_button_box(editSongDialog)
self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(editSongDialog)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'rejected()'), editSongDialog.closePressed)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'accepted()'), editSongDialog.accept)
QtCore.QMetaObject.connectSlotsByName(editSongDialog)
def retranslateUi(self, editSongDialog):
@ -287,19 +257,15 @@ class Ui_EditSongDialog(object):
translate('SongsPlugin.EditSongForm', '&Lyrics:'))
self.verseOrderLabel.setText(
translate('SongsPlugin.EditSongForm', '&Verse order:'))
self.verseAddButton.setText(
translate('SongsPlugin.EditSongForm', '&Add'))
self.verseEditButton.setText(
translate('SongsPlugin.EditSongForm', '&Edit'))
self.verseAddButton.setText(UiStrings.Add)
self.verseEditButton.setText(UiStrings.Edit)
self.verseEditAllButton.setText(
translate('SongsPlugin.EditSongForm', 'Ed&it All'))
self.verseDeleteButton.setText(
translate('SongsPlugin.EditSongForm', '&Delete'))
self.verseDeleteButton.setText(UiStrings.Delete)
self.songTabWidget.setTabText(
self.songTabWidget.indexOf(self.lyricsTab),
translate('SongsPlugin.EditSongForm', 'Title && Lyrics'))
self.authorsGroupBox.setTitle(
translate('SongsPlugin.EditSongForm', 'Authors'))
self.authorsGroupBox.setTitle(UiStrings.Authors)
self.authorAddButton.setText(
translate('SongsPlugin.EditSongForm', '&Add to Song'))
self.authorRemoveButton.setText(
@ -322,8 +288,7 @@ class Ui_EditSongDialog(object):
self.songTabWidget.indexOf(self.authorsTab),
translate('SongsPlugin.EditSongForm',
'Authors, Topics && Song Book'))
self.themeGroupBox.setTitle(
translate('SongsPlugin.EditSongForm', 'Theme'))
self.themeGroupBox.setTitle(UiStrings.Theme)
self.themeAddButton.setText(
translate('SongsPlugin.EditSongForm', 'New &Theme'))
self.rightsGroupBox.setTitle(
@ -338,3 +303,15 @@ class Ui_EditSongDialog(object):
self.songTabWidget.indexOf(self.themeTab),
translate('SongsPlugin.EditSongForm',
'Theme, Copyright Info && Comments'))
def editSongDialogComboBox(parent, name):
"""
Utility method to generate a standard combo box for this dialog.
"""
comboBox = QtGui.QComboBox(parent)
comboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength)
comboBox.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
comboBox.setEditable(True)
comboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
comboBox.setObjectName(name)
return comboBox

View File

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

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui
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
class Ui_EditVerseDialog(object):
@ -59,17 +60,9 @@ class Ui_EditVerseDialog(object):
self.verseTypeLayout.addWidget(self.insertButton)
self.verseTypeLayout.addStretch()
self.dialogLayout.addLayout(self.verseTypeLayout)
self.buttonBox = QtGui.QDialogButtonBox(editVerseDialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox)
self.dialogLayout.addWidget(
create_save_cancel_button_box(editVerseDialog))
self.retranslateUi(editVerseDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
editVerseDialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
editVerseDialog.reject)
QtCore.QMetaObject.connectSlotsByName(editVerseDialog)
def retranslateUi(self, editVerseDialog):

View File

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

View File

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

View File

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

View File

@ -32,7 +32,7 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.ui import criticalErrorMessageBox
from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard
from openlp.plugins.songs.lib.importer import SongFormat
@ -162,32 +162,34 @@ class SongImportForm(OpenLPWizard):
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.formatSpacer)
self.sourceLayout.addLayout(self.formatLayout)
self.stackSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Expanding)
self.formatStack = QtGui.QStackedLayout()
self.formatStack.setObjectName(u'FormatStack')
# OpenLP 2.0
self.addSingleFileSelectItem(u'openLP2')
self.addFileSelectItem(u'openLP2', single_select=True)
# openlp.org 1.x
self.addSingleFileSelectItem(u'openLP1', None, True)
self.addFileSelectItem(u'openLP1', None, True, True)
# OpenLyrics
self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True)
self.addFileSelectItem(u'openLyrics', u'OpenLyrics', True)
# Open Song
self.addMultiFileSelectItem(u'openSong', u'OpenSong')
self.addFileSelectItem(u'openSong', u'OpenSong')
# Words of Worship
self.addMultiFileSelectItem(u'wordsOfWorship')
self.addFileSelectItem(u'wordsOfWorship')
# CCLI File import
self.addMultiFileSelectItem(u'ccli')
self.addFileSelectItem(u'ccli')
# Songs of Fellowship
self.addMultiFileSelectItem(u'songsOfFellowship', None, True)
self.addFileSelectItem(u'songsOfFellowship', None, True)
# Generic Document/Presentation import
self.addMultiFileSelectItem(u'generic', None, True)
self.addFileSelectItem(u'generic', None, True)
# EasySlides
self.addSingleFileSelectItem(u'easiSlides')
self.addFileSelectItem(u'easiSlides', single_select=True)
# EasyWorship
self.addSingleFileSelectItem(u'ew')
self.addFileSelectItem(u'ew', single_select=True)
# Words of Worship
self.addMultiFileSelectItem(u'songBeamer')
self.addFileSelectItem(u'songBeamer')
# Commented out for future use.
# self.addSingleFileSelectItem(u'csv', u'CSV')
# self.addFileSelectItem(u'csv', u'CSV', single_select=True)
self.sourceLayout.addLayout(self.formatStack)
self.addPage(self.sourcePage)
@ -213,8 +215,7 @@ class SongImportForm(OpenLPWizard):
'Select the import format, and where to import from.'))
self.formatLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Format:'))
self.formatComboBox.setItemText(0,
translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0'))
self.formatComboBox.setItemText(0, UiStrings.OLPV2)
self.formatComboBox.setItemText(1,
translate('SongsPlugin.ImportWizardForm', 'openlp.org 1.x'))
self.formatComboBox.setItemText(2,
@ -318,16 +319,6 @@ class SongImportForm(OpenLPWizard):
self.openLP2FilenameLabel.minimumSizeHint().width())
self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Fixed)
self.openLP2FormLabelSpacer.changeSize(width, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openLP1FormLabelSpacer.changeSize(width, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.easiSlidesFormLabelSpacer.changeSize(width, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.ewFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Fixed)
# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed,
# QtGui.QSizePolicy.Fixed)
def validateCurrentPage(self):
"""
@ -339,7 +330,7 @@ class SongImportForm(OpenLPWizard):
source_format = self.formatComboBox.currentIndex()
if source_format == SongFormat.OpenLP2:
if self.openLP2FilenameEdit.text().isEmpty():
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No OpenLP 2.0 Song Database Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -349,7 +340,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.OpenLP1:
if self.openLP1FilenameEdit.text().isEmpty():
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No openlp.org 1.x Song Database Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -359,7 +350,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.OpenLyrics:
if self.openLyricsFileListWidget.count() == 0:
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No OpenLyrics Files Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -369,7 +360,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.OpenSong:
if self.openSongFileListWidget.count() == 0:
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No OpenSong Files Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -379,7 +370,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.WordsOfWorship:
if self.wordsOfWorshipFileListWidget.count() == 0:
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No Words of Worship Files Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -389,7 +380,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.CCLI:
if self.ccliFileListWidget.count() == 0:
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No CCLI Files Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -399,7 +390,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.SongsOfFellowship:
if self.songsOfFellowshipFileListWidget.count() == 0:
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No Songs of Fellowship File Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -409,7 +400,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.Generic:
if self.genericFileListWidget.count() == 0:
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No Document/Presentation Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -419,7 +410,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.EasiSlides:
if self.easiSlidesFilenameEdit.text().isEmpty():
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No Easislides Songs file selected'),
translate('SongsPlugin.ImportWizardForm',
@ -429,7 +420,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.EasyWorship:
if self.ewFilenameEdit.text().isEmpty():
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No EasyWorship Song Database Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -439,7 +430,7 @@ class SongImportForm(OpenLPWizard):
return False
elif source_format == SongFormat.SongBeamer:
if self.songBeamerFileListWidget.count() == 0:
criticalErrorMessageBox(
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No SongBeamer File Selected'),
translate('SongsPlugin.ImportWizardForm',
@ -497,8 +488,7 @@ class SongImportForm(OpenLPWizard):
"""
if filters:
filters += u';;'
filters += u'%s (*)' % translate('SongsPlugin.ImportWizardForm',
'All Files')
filters += u'%s (*)' % UiStrings.AllFiles
filenames = QtGui.QFileDialog.getOpenFileNames(self, title,
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
filters)
@ -791,52 +781,8 @@ class SongImportForm(OpenLPWizard):
translate('SongsPlugin.SongImportForm',
'Your song import failed.'))
def addSingleFileSelectItem(self, prefix, obj_prefix=None,
can_disable=False):
if not obj_prefix:
obj_prefix = prefix
page = QtGui.QWidget()
page.setObjectName(obj_prefix + u'Page')
if can_disable:
importWidget = self.disablableWidget(page, prefix, obj_prefix)
else:
importWidget = page
importLayout = QtGui.QFormLayout(importWidget)
importLayout.setMargin(0)
if can_disable:
importLayout.setObjectName(obj_prefix + u'ImportLayout')
else:
importLayout.setObjectName(obj_prefix + u'Layout')
filenameLabel = QtGui.QLabel(importWidget)
filenameLabel.setObjectName(obj_prefix + u'FilenameLabel')
fileLayout = QtGui.QHBoxLayout()
fileLayout.setObjectName(obj_prefix + u'FileLayout')
filenameEdit = QtGui.QLineEdit(importWidget)
filenameEdit.setObjectName(obj_prefix + u'FilenameEdit')
fileLayout.addWidget(filenameEdit)
browseButton = QtGui.QToolButton(importWidget)
browseButton.setIcon(self.openIcon)
browseButton.setObjectName(obj_prefix + u'BrowseButton')
fileLayout.addWidget(browseButton)
importLayout.addRow(filenameLabel, fileLayout)
formSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
importLayout.setItem(1, QtGui.QFormLayout.LabelRole, formSpacer)
self.formatStack.addWidget(page)
setattr(self, prefix + u'Page', page)
setattr(self, prefix + u'FilenameLabel', filenameLabel)
setattr(self, prefix + u'FormLabelSpacer', formSpacer)
setattr(self, prefix + u'FileLayout', fileLayout)
setattr(self, prefix + u'FilenameEdit', filenameEdit)
setattr(self, prefix + u'BrowseButton', browseButton)
if can_disable:
setattr(self, prefix + u'ImportLayout', importLayout)
else:
setattr(self, prefix + u'Layout', importLayout)
self.formatComboBox.addItem(u'')
def addMultiFileSelectItem(self, prefix, obj_prefix=None,
can_disable=False):
def addFileSelectItem(self, prefix, obj_prefix=None, can_disable=False,
single_select=False):
if not obj_prefix:
obj_prefix = prefix
page = QtGui.QWidget()
@ -847,37 +793,53 @@ class SongImportForm(OpenLPWizard):
importWidget = page
importLayout = QtGui.QVBoxLayout(importWidget)
importLayout.setMargin(0)
if can_disable:
importLayout.setObjectName(obj_prefix + u'ImportLayout')
importLayout.setObjectName(obj_prefix + u'ImportLayout')
if single_select:
fileLayout = QtGui.QHBoxLayout()
fileLayout.setObjectName(obj_prefix + u'FileLayout')
filenameLabel = QtGui.QLabel(importWidget)
filenameLabel.setObjectName(obj_prefix + u'FilenameLabel')
fileLayout.addWidget(filenameLabel)
filenameEdit = QtGui.QLineEdit(importWidget)
filenameEdit.setObjectName(obj_prefix + u'FilenameEdit')
fileLayout.addWidget(filenameEdit)
browseButton = QtGui.QToolButton(importWidget)
browseButton.setIcon(self.openIcon)
browseButton.setObjectName(obj_prefix + u'BrowseButton')
fileLayout.addWidget(browseButton)
importLayout.addLayout(fileLayout)
importLayout.addSpacerItem(self.stackSpacer)
else:
importLayout.setObjectName(obj_prefix + u'Layout')
fileListWidget = QtGui.QListWidget(importWidget)
fileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
fileListWidget.setObjectName(obj_prefix + u'FileListWidget')
importLayout.addWidget(fileListWidget)
buttonLayout = QtGui.QHBoxLayout()
buttonLayout.setObjectName(obj_prefix + u'ButtonLayout')
addButton = QtGui.QPushButton(importWidget)
addButton.setIcon(self.openIcon)
addButton.setObjectName(obj_prefix + u'AddButton')
buttonLayout.addWidget(addButton)
buttonLayout.addStretch()
removeButton = QtGui.QPushButton(importWidget)
removeButton.setIcon(self.deleteIcon)
removeButton.setObjectName(obj_prefix + u'RemoveButton')
buttonLayout.addWidget(removeButton)
importLayout.addLayout(buttonLayout)
fileListWidget = QtGui.QListWidget(importWidget)
fileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
fileListWidget.setObjectName(obj_prefix + u'FileListWidget')
importLayout.addWidget(fileListWidget)
buttonLayout = QtGui.QHBoxLayout()
buttonLayout.setObjectName(obj_prefix + u'ButtonLayout')
addButton = QtGui.QPushButton(importWidget)
addButton.setIcon(self.openIcon)
addButton.setObjectName(obj_prefix + u'AddButton')
buttonLayout.addWidget(addButton)
buttonLayout.addStretch()
removeButton = QtGui.QPushButton(importWidget)
removeButton.setIcon(self.deleteIcon)
removeButton.setObjectName(obj_prefix + u'RemoveButton')
buttonLayout.addWidget(removeButton)
importLayout.addLayout(buttonLayout)
self.formatStack.addWidget(page)
setattr(self, prefix + u'Page', page)
setattr(self, prefix + u'FileListWidget', fileListWidget)
setattr(self, prefix + u'ButtonLayout', buttonLayout)
setattr(self, prefix + u'AddButton', addButton)
setattr(self, prefix + u'RemoveButton', removeButton)
if can_disable:
setattr(self, prefix + u'ImportLayout', importLayout)
if single_select:
setattr(self, prefix + u'FilenameLabel', filenameLabel)
setattr(self, prefix + u'FileLayout', fileLayout)
setattr(self, prefix + u'FilenameEdit', filenameEdit)
setattr(self, prefix + u'BrowseButton', browseButton)
else:
setattr(self, prefix + u'Layout', importLayout)
setattr(self, prefix + u'FileListWidget', fileListWidget)
setattr(self, prefix + u'ButtonLayout', buttonLayout)
setattr(self, prefix + u'AddButton', addButton)
setattr(self, prefix + u'RemoveButton', removeButton)
setattr(self, prefix + u'ImportLayout', importLayout)
self.formatComboBox.addItem(u'')
def disablableWidget(self, page, prefix, obj_prefix):
@ -895,6 +857,7 @@ class SongImportForm(OpenLPWizard):
disabledLabel.setWordWrap(True)
disabledLabel.setObjectName(obj_prefix + u'DisabledLabel')
disabledLayout.addWidget(disabledLabel)
disabledLayout.addSpacerItem(self.stackSpacer)
layout.addWidget(disabledWidget)
importWidget = QtGui.QWidget(page)
importWidget.setObjectName(obj_prefix + u'ImportWidget')

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate
from openlp.core.lib.ui import UiStrings
class Ui_SongMaintenanceDialog(object):
def setupUi(self, songMaintenanceDialog):
@ -145,30 +146,21 @@ class Ui_SongMaintenanceDialog(object):
def retranslateUi(self, songMaintenanceDialog):
songMaintenanceDialog.setWindowTitle(
translate('SongsPlugin.SongMaintenanceForm', 'Song Maintenance'))
authorsString = translate('SongsPlugin.SongMaintenanceForm', 'Authors')
authorsString = UiStrings.Authors
topicsString = translate('SongsPlugin.SongMaintenanceForm', 'Topics')
booksString = translate('SongsPlugin.SongMaintenanceForm', 'Song Books')
self.listItemAuthors.setText(authorsString)
self.listItemTopics.setText(topicsString)
self.listItemBooks.setText(booksString)
self.authorsAddButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Add'))
self.authorsEditButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Edit'))
self.authorsDeleteButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Delete'))
self.topicsAddButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Add'))
self.topicsEditButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Edit'))
self.topicsDeleteButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Delete'))
self.booksAddButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Add'))
self.booksEditButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Edit'))
self.booksDeleteButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Delete'))
self.authorsAddButton.setText(UiStrings.Add)
self.authorsEditButton.setText(UiStrings.Edit)
self.authorsDeleteButton.setText(UiStrings.Delete)
self.topicsAddButton.setText(UiStrings.Add)
self.topicsEditButton.setText(UiStrings.Edit)
self.topicsDeleteButton.setText(UiStrings.Delete)
self.booksAddButton.setText(UiStrings.Add)
self.booksEditButton.setText(UiStrings.Edit)
self.booksDeleteButton.setText(UiStrings.Delete)
typeListWidth = max(self.fontMetrics().width(authorsString),
self.fontMetrics().width(topicsString),
self.fontMetrics().width(booksString))

View File

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

View File

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

View File

@ -27,7 +27,7 @@
from PyQt4 import QtGui
from openlp.core.lib import translate
from openlp.core.ui import criticalErrorMessageBox
from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
@ -49,7 +49,8 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
def accept(self):
if not self.nameEdit.text():
criticalErrorMessageBox(message=translate('SongsPlugin.TopicsForm',
critical_error_message_box(
message=translate('SongsPlugin.TopicsForm',
'You need to type in a topic name.'))
self.nameEdit.setFocus()
return False

View File

@ -104,6 +104,15 @@ class VerseType(object):
def retrieve_windows_encoding(recommendation=None):
"""
Determines which encoding to use on an information source. The process uses
both automated detection, which is passed to this method as a
recommendation, and user confirmation to return an encoding.
``recommendation``
A recommended encoding discovered programmatically for the user to
confirm.
"""
# map chardet result to compatible windows standard code page
codepage_mapping = {'IBM866': u'cp866', 'TIS-620': u'cp874',
'SHIFT_JIS': u'cp932', 'GB2312': u'cp936', 'HZ-GB-2312': u'cp936',

View File

@ -39,6 +39,7 @@ class Author(BaseModel):
"""
pass
class Book(BaseModel):
"""
Book model
@ -47,30 +48,114 @@ class Book(BaseModel):
return u'<Book id="%s" name="%s" publisher="%s" />' % (
str(self.id), self.name, self.publisher)
class MediaFile(BaseModel):
"""
MediaFile model
"""
pass
class Song(BaseModel):
"""
Song model
"""
pass
class Topic(BaseModel):
"""
Topic model
"""
pass
def init_schema(url):
"""
Setup the songs database connection and initialise the database schema
Setup the songs database connection and initialise the database schema.
``url``
The database to setup
The song database contains the following tables:
* authors
* authors_songs
* media_files
* media_files_songs
* song_books
* songs
* songs_topics
* topics
**authors** Table
This table holds the names of all the authors. It has the following
columns:
* id
* first_name
* last_name
* display_name
**authors_songs Table**
This is a bridging table between the *authors* and *songs* tables, which
serves to create a many-to-many relationship between the two tables. It
has the following columns:
* author_id
* song_id
**media_files Table**
* id
* file_name
* type
**media_files_songs Table**
* media_file_id
* song_id
**song_books Table**
The *song_books* table holds a list of books that a congregation gets
their songs from, or old hymnals now no longer used. This table has the
following columns:
* id
* name
* publisher
**songs Table**
This table contains the songs, and each song has a list of attributes.
The *songs* table has the following columns:
* id
* song_book_id
* title
* alternate_title
* lyrics
* verse_order
* copyright
* comments
* ccli_number
* song_number
* theme_name
* search_title
* search_lyrics
**songs_topics Table**
This is a bridging table between the *songs* and *topics* tables, which
serves to create a many-to-many relationship between the two tables. It
has the following columns:
* song_id
* topic_id
**topics Table**
The topics table holds a selection of topics that songs can cover. This
is useful when a worship leader wants to select songs with a certain
theme. This table has the following columns:
* id
* name
"""
session, metadata = init_db(url)

View File

@ -81,14 +81,14 @@ class EasiSlidesImport(SongImport):
def _parse_song(self, song):
self._success = True
self._add_title(self.title, song.Title1, True)
self._add_alttitle(self.alternate_title, song.Title2)
self._add_number(self.song_number, song.SongNumber)
self._add_unicode_attribute(self.title, song.Title1, True)
self._add_unicode_attribute(self.alternate_title, song.Title2)
self._add_unicode_attribute(self.song_number, song.SongNumber)
if self.song_number == u'0':
self.song_number = u''
self._add_authors(song)
self._add_copyright(song)
self._add_book(self.song_book_name, song.BookReference)
self._add_unicode_attribute(self.song_book_name, song.BookReference)
self._parse_and_add_lyrics(song)
return self._success
@ -133,29 +133,37 @@ class EasiSlidesImport(SongImport):
pass
def _add_copyright(self, song):
copyright = []
"""
Assign the copyright information from the import to the song being
created.
``song``
The current song being imported.
"""
copyright_list = []
self.__add_copyright_element(copyright_list, song.Copyright)
self.__add_copyright_element(copyright_list, song.LicenceAdmin1)
self.__add_copyright_element(copyright_list, song.LicenceAdmin2)
self.add_copyright(u' '.join(copyright_list))
def __add_copyright_element(self, copyright_list, element):
"""
Add a piece of copyright to the total copyright information for the
song.
``copyright_list``
The array to add the information to.
``element``
The imported variable to get the data from.
"""
try:
copyright.append(unicode(song.Copyright).strip())
copyright_list.append(unicode(element).strip())
except UnicodeDecodeError:
log.exception(u'Unicode decode error while decoding Copyright')
log.exception(u'Unicode error decoding %s' % element)
self._success = False
except AttributeError:
pass
try:
copyright.append(unicode(song.LicenceAdmin1).strip())
except UnicodeDecodeError:
log.exception(u'Unicode decode error while decoding LicenceAdmin1')
self._success = False
except AttributeError:
pass
try:
copyright.append(unicode(song.LicenceAdmin2).strip())
except UnicodeDecodeError:
log.exception(u'Unicode decode error while decoding LicenceAdmin2')
self._success = False
except AttributeError:
pass
self.add_copyright(u' '.join(copyright))
def _parse_and_add_lyrics(self, song):
try:

View File

@ -32,7 +32,8 @@ from PyQt4 import QtCore, QtGui
from sqlalchemy.sql import or_
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \
ItemCapabilities, translate, check_item_selected
ItemCapabilities, translate, check_item_selected, PluginStatus
from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML
@ -95,8 +96,6 @@ class SongMediaItem(MediaManagerItem):
self.searchLayout.addLayout(self.searchButtonLayout)
self.pageLayout.addWidget(self.searchWidget)
# Signals and slots
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'plugin_list_refresh'), self.onSearchTextButtonClick)
QtCore.QObject.connect(self.searchTextEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick)
QtCore.QObject.connect(self.searchTextButton,
@ -149,10 +148,8 @@ class SongMediaItem(MediaManagerItem):
translate('SongsPlugin.MediaItem', 'Titles')),
(3, u':/songs/song_search_lyrics.png',
translate('SongsPlugin.MediaItem', 'Lyrics')),
(4, u':/songs/song_search_author.png',
translate('SongsPlugin.MediaItem', 'Authors')),
(5, u':/slides/slide_theme.png',
translate('SongsPlugin.MediaItem', 'Themes'))
(4, u':/songs/song_search_author.png', UiStrings.Authors),
(5, u':/slides/slide_theme.png', UiStrings.Themes)
])
self.configUpdated()
@ -337,16 +334,7 @@ class SongMediaItem(MediaManagerItem):
author_list = u''
author_audit = []
ccli = u''
if item is None:
if self.remoteTriggered is None:
item = self.listView.currentItem()
if item is None:
return False
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
else:
item_id = self.remoteSong
else:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
item_id = self._getIdOfItemToGenerate(item, self.remoteSong)
service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop)
@ -389,10 +377,12 @@ class SongMediaItem(MediaManagerItem):
raw_footer.append(song.title)
raw_footer.append(author_list)
raw_footer.append(song.copyright)
raw_footer.append(unicode(
translate('SongsPlugin.MediaItem', 'CCLI License: ') +
QtCore.QSettings().value(u'general/ccli number',
QtCore.QVariant(u'')).toString()))
if QtCore.QSettings().value(u'general/ccli number',
QtCore.QVariant(u'')).toString():
raw_footer.append(unicode(
translate('SongsPlugin.MediaItem', 'CCLI License: ') +
QtCore.QSettings().value(u'general/ccli number',
QtCore.QVariant(u'')).toString()))
service_item.raw_footer = raw_footer
service_item.audit = [
song.title, author_audit, song.copyright, unicode(song.ccli_number)
@ -407,45 +397,46 @@ class SongMediaItem(MediaManagerItem):
Triggered by a song being loaded by the service item
"""
log.debug(u'serviceLoad')
if item.data_string:
search_results = self.parent.manager.get_all_objects(Song,
Song.search_title == re.compile(r'\W+', re.UNICODE).sub(u' ',
item.data_string[u'title'].split(u'@')[0].lower()).strip(),
Song.search_title.asc())
author_list = item.data_string[u'authors'].split(u', ')
# The service item always has an author (at least it has u'' as
# author). However, songs saved in the database do not have to have
# an author.
if u'' in author_list:
author_list.remove(u'')
editId = 0
add_song = True
if search_results:
for song in search_results:
same_authors = True
# If the author counts are different, we do not have to do
# any further checking. This is also important when a song
# does not have any author (because we can not loop over an
# empty list).
if len(song.authors) == len(author_list):
for author in song.authors:
if author.display_name not in author_list:
same_authors = False
else:
same_authors = False
# All authors are the same, so we can stop here and the song
# does not have to be saved.
if same_authors:
add_song = False
editId = song.id
break
if add_song:
if self.addSongFromService:
editId = self.openLyrics.xml_to_song(item.xml_version)
# Update service with correct song id.
if editId:
Receiver.send_message(u'service_item_update',
u'%s:%s' % (editId, item._uuid))
if self.plugin.status != PluginStatus.Active or not item.data_string:
return
search_results = self.parent.manager.get_all_objects(Song,
Song.search_title == re.compile(r'\W+', re.UNICODE).sub(u' ',
item.data_string[u'title'].split(u'@')[0].lower()).strip(),
Song.search_title.asc())
author_list = item.data_string[u'authors'].split(u', ')
# The service item always has an author (at least it has u'' as
# author). However, songs saved in the database do not have to have
# an author.
if u'' in author_list:
author_list.remove(u'')
editId = 0
add_song = True
if search_results:
for song in search_results:
same_authors = True
# If the author counts are different, we do not have to do any
# further checking. This is also important when a song does not
# have any author (because we can not loop over an empty list).
if len(song.authors) == len(author_list):
for author in song.authors:
if author.display_name not in author_list:
same_authors = False
else:
same_authors = False
# All authors are the same, so we can stop here and the song
# does not have to be saved.
if same_authors:
add_song = False
editId = song.id
break
if add_song:
if self.addSongFromService:
editId = self.openLyrics.xml_to_song(item.xml_version)
self.onSearchTextButtonClick()
# Update service with correct song id.
if editId:
Receiver.send_message(u'service_item_update',
u'%s:%s' % (editId, item._uuid))
def collateSongTitles(self, song_1, song_2):
"""

View File

@ -36,9 +36,6 @@ from openlp.plugins.songs.lib.songimport import SongImport
log = logging.getLogger(__name__)
class OpenSongImportError(Exception):
pass
class OpenSongImport(SongImport):
"""
Import songs exported from OpenSong

View File

@ -31,6 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.db import Manager
from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.lib import SongMediaItem, SongsTab, SongXML
from openlp.plugins.songs.lib.db import init_schema, Song
from openlp.plugins.songs.lib.importer import SongFormat
@ -227,37 +228,37 @@ class SongsPlugin(Plugin):
# Middle Header Bar
## New Action ##
self.textStrings[StringContent.New] = {
u'title': translate('SongsPlugin', 'Add'),
u'title': UiStrings.Add,
u'tooltip': translate('SongsPlugin',
'Add a new Song')
}
## Edit Action ##
self.textStrings[StringContent.Edit] = {
u'title': translate('SongsPlugin', 'Edit'),
u'title': UiStrings.Edit,
u'tooltip': translate('SongsPlugin',
'Edit the selected Song')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('SongsPlugin', 'Delete'),
u'title': UiStrings.Delete,
u'tooltip': translate('SongsPlugin',
'Delete the selected Song')
}
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('SongsPlugin', 'Preview'),
u'title': UiStrings.Preview,
u'tooltip': translate('SongsPlugin',
'Preview the selected Song')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('SongsPlugin', 'Live'),
u'title': UiStrings.Live,
u'tooltip': translate('SongsPlugin',
'Send the selected Song live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('SongsPlugin', 'Service'),
u'title': UiStrings.Service,
u'tooltip': translate('SongsPlugin',
'Add the selected Song to the service')
}

View File

@ -13,82 +13,128 @@
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="exceptionLayout">
<property name="spacing">
<number>8</number>
<widget class="QPlainTextEdit" name="exceptionTextEdit">
<property name="geometry">
<rect>
<x>8</x>
<y>194</y>
<width>564</width>
<height>171</height>
</rect>
</property>
<property name="margin">
<number>8</number>
<property name="readOnly">
<bool>true</bool>
</property>
<item>
<layout class="QHBoxLayout" name="messageLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<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>
</item>
<item>
<widget class="QPlainTextEdit" name="exceptionTextEdit">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="backgroundVisible">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="exceptionButtonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
<property name="backgroundVisible">
<bool>false</bool>
</property>
</widget>
<widget class="QDialogButtonBox" name="exceptionButtonBox">
<property name="geometry">
<rect>
<x>8</x>
<y>373</y>
<width>83</width>
<height>26</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
<widget class="QPlainTextEdit" name="discriptionplainTextEdit">
<property name="geometry">
<rect>
<x>8</x>
<y>103</y>
<width>561</width>
<height>71</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QLabel" name="characterCount">
<property name="geometry">
<rect>
<x>10</x>
<y>170</y>
<width>301</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="whatyouweredoinglabel">
<property name="geometry">
<rect>
<x>10</x>
<y>80</y>
<width>59</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QWidget" name="">
<layout class="QHBoxLayout" name="messageLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<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>
<resources>
<include location="../images/openlp-2.qrc"/>

View File

@ -0,0 +1,206 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>494</width>
<height>426</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QGridLayout" name="dialogLayout">
<item row="0" column="3">
<layout class="QVBoxLayout" name="settingsLayout">
<item>
<layout class="QGridLayout" name="serviceTitleLayout">
<item row="1" column="1">
<widget class="QLineEdit" name="serviceTitleLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="serviceTitleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Service Title:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="printSlideTextCheckBox">
<property name="text">
<string>Include slide text if avaialbe</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="printNotesCheckBox">
<property name="text">
<string>Include service item notes</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="printMetaDataCheckBox">
<property name="text">
<string>Include play lenght of media items</string>
</property>
</widget>
</item>
<item>
<spacer name="spacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="customNotesLabel">
<property name="text">
<string>&lt;b&gt;Custom Notes:&lt;/b&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="customNoteEdit"/>
</item>
</layout>
</item>
<item row="1" column="3">
<layout class="QHBoxLayout" name="buttonLayout">
<item>
<spacer name="spacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="printButton">
<property name="text">
<string>Print</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="zoomButtonLayout">
<item>
<spacer name="spacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="zoomOutButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../images/openlp-2.qrc">
<normaloff>:/general/general_zoom_out.png</normaloff>:/general/general_zoom_out.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="zoomInButton">
<property name="icon">
<iconset resource="../images/openlp-2.qrc">
<normaloff>:/general/general_zoom_in.png</normaloff>:/general/general_zoom_in.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QVBoxLayout" name="perviewLayout">
<item>
<widget class="QLabel" name="previewLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Preview:</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="previewWidget" native="true">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
<zorder></zorder>
</widget>
<resources>
<include location="../images/openlp-2.qrc"/>
</resources>
<connections/>
</ui>

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

View File

@ -41,6 +41,8 @@
<file>general_export.png</file>
<file>general_import.png</file>
<file>general_new.png</file>
<file>general_zoom_out.png</file>
<file>general_zoom_in.png</file>
<file>general_open.png</file>
<file>general_save.png</file>
<file>general_email.png</file>

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\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\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\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/',
license='GNU General Public License',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
scripts=['openlp.pyw', 'scripts/openlp-1to2-converter.py',
'scripts/bible-1to2-converter.py','scripts/openlp-remoteclient.py'],
scripts=['openlp.pyw', 'scripts/openlp-remoteclient.py'],
include_package_data=True,
zip_safe=False,
install_requires=[